mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-05 12:05:56 -04:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e150892f9f | |||
| a6cef9c6be | |||
| c5b2691302 | |||
| 8122c7245e | |||
| 8a51c167f8 | |||
| 1b5af1402d | |||
| fffe93fac8 | |||
| dbd857f6b5 | |||
| a4d394f727 | |||
| 3c857f4132 | |||
| 36cfb93eb2 | |||
| ab4762f026 | |||
| 56763dc57d | |||
| 5375fdd704 | |||
| e7484efca5 | |||
| c958a1645a | |||
| 0140a257c4 | |||
| 40161fe8d2 | |||
| d883fe7351 | |||
| 2bc6914784 |
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@llamaindex/core": patch
|
||||
---
|
||||
|
||||
Add more Acronyms on SentenceSplitter
|
||||
@@ -1,5 +1,38 @@
|
||||
# @llamaindex/doc
|
||||
|
||||
## 0.2.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 8a51c16: Add natural language agent page
|
||||
- Updated dependencies [8a51c16]
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/workflow@1.1.9
|
||||
- @llamaindex/core@0.6.10
|
||||
- llamaindex@0.11.8
|
||||
- @llamaindex/cloud@4.0.14
|
||||
- @llamaindex/node-parser@2.0.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
- @llamaindex/readers@3.1.8
|
||||
|
||||
## 0.2.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a4d394f: fix: correct SimpleDirectoryReader import path in documentation example
|
||||
- Updated dependencies [dbd857f]
|
||||
- Updated dependencies [3c857f4]
|
||||
- @llamaindex/workflow@1.1.8
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.2.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [40161fe]
|
||||
- @llamaindex/workflow@1.1.7
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.2.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -15,6 +15,20 @@ const config = {
|
||||
"twoslash",
|
||||
"typescript",
|
||||
],
|
||||
async redirects() {
|
||||
return [
|
||||
{
|
||||
source: "/docs/chat-ui/:path*.mdx",
|
||||
destination: "/docs/chat-ui/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/docs/llamaflow/:path*.mdx",
|
||||
destination: "/docs/llamaflow/:path*",
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
turbopack: {
|
||||
resolveAlias: {
|
||||
fs: { browser: "./fallback.js" },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/doc",
|
||||
"version": "0.2.24",
|
||||
"version": "0.2.27",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"postinstall": "fumadocs-mdx",
|
||||
@@ -16,7 +16,7 @@
|
||||
"@huggingface/transformers": "^3.5.0",
|
||||
"@icons-pack/react-simple-icons": "^10.1.0",
|
||||
"@llama-flow/docs": "0.0.8",
|
||||
"@llamaindex/chat-ui-docs": "0.0.3",
|
||||
"@llamaindex/chat-ui-docs": "^0.0.5",
|
||||
"@llamaindex/cloud": "workspace:*",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/node-parser": "workspace:*",
|
||||
@@ -39,13 +39,13 @@
|
||||
"clsx": "2.1.1",
|
||||
"foxact": "^0.2.41",
|
||||
"framer-motion": "^11.11.17",
|
||||
"fumadocs-core": "^15.2.7",
|
||||
"fumadocs-core": "^15.5.0",
|
||||
"fumadocs-docgen": "^2.0.0",
|
||||
"fumadocs-mdx": "^11.6.0",
|
||||
"fumadocs-openapi": "^8.0.1",
|
||||
"fumadocs-twoslash": "^3.1.1",
|
||||
"fumadocs-typescript": "^4.0.2",
|
||||
"fumadocs-ui": "^15.2.7",
|
||||
"fumadocs-mdx": "^11.6.6",
|
||||
"fumadocs-openapi": "^9.0.5",
|
||||
"fumadocs-twoslash": "^3.1.3",
|
||||
"fumadocs-typescript": "^4.0.5",
|
||||
"fumadocs-ui": "^15.5.0",
|
||||
"hast-util-to-jsx-runtime": "^2.3.2",
|
||||
"llamaindex": "workspace:*",
|
||||
"lucide-react": "^0.460.0",
|
||||
|
||||
@@ -13,6 +13,11 @@ export const docs = defineDocs({
|
||||
"./src/content/docs",
|
||||
"./node_modules/@llama-flow/docs",
|
||||
"./node_modules/@llamaindex/chat-ui-docs",
|
||||
// NOTE: When adding external docs (like chat-ui or llama-flow above),
|
||||
// make sure to also update:
|
||||
// 1. scripts/validate-links.mts - add to ALLOWED_LINKS array
|
||||
// 2. next.config.mjs - add redirect for .mdx files
|
||||
// 3. src/content/docs/meta.json - add to pages array
|
||||
],
|
||||
docs: {
|
||||
async: true,
|
||||
|
||||
@@ -113,7 +113,8 @@ 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 { SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
|
||||
code={`import { VectorStoreIndex } from "llamaindex";
|
||||
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"title": "Agents",
|
||||
"pages": ["tool", "agent_workflow", "workflows"]
|
||||
"pages": ["tool", "agent_workflow", "workflows", "natural_language_workflow"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Define workflows using natural language
|
||||
---
|
||||
|
||||
When working with Workflows, you have to write code to handle an event in the workflow.
|
||||
Often, the logic of the handler is not too complex so that it can be expressed using natural language and executed by an LLM.
|
||||
Besides the instructions, we just need the expected result event of the step, possible tool calls and optionally other events that can be emitted.
|
||||
|
||||
## Usage
|
||||
|
||||
Let's take an example of a workflow that generates a joke, gets a critique for it, and then improves it.
|
||||
|
||||
### Define the events
|
||||
|
||||
First, we define the events for our workflow. We need one for writing the joke, one for critiquing it, and one for the final result:
|
||||
|
||||
```typescript
|
||||
import { z } from "zod";
|
||||
import { zodEvent } from "@llamaindex/workflow";
|
||||
|
||||
const writeJokeSchema = z.object({
|
||||
description: z
|
||||
.string()
|
||||
.describe("The topic to write a joke or describe the joke to improve."),
|
||||
writtenJoke: z.optional(z.string()).describe("The written joke."),
|
||||
retriedTimes: z
|
||||
.number()
|
||||
.default(0)
|
||||
.describe(
|
||||
"The retried times for writing the joke. Always increase this from the input retriedTimes.",
|
||||
),
|
||||
});
|
||||
|
||||
const critiqueSchema = z.object({
|
||||
joke: z.string().describe("The joke to critique"),
|
||||
retriedTimes: z.number().describe("The retried times for writing the joke."),
|
||||
});
|
||||
|
||||
const finalResultSchema = z.object({
|
||||
joke: z.string().describe("The joke to critique"),
|
||||
critique: z.string().describe("The critique of the joke"),
|
||||
});
|
||||
|
||||
const writeJokeEvent = zodEvent(writeJokeSchema, {
|
||||
debugLabel: "writeJokeEvent",
|
||||
});
|
||||
const critiqueEvent = zodEvent(critiqueSchema, {
|
||||
debugLabel: "critiqueEvent",
|
||||
});
|
||||
const finalResultEvent = zodEvent(finalResultSchema, {
|
||||
debugLabel: "finalResultEvent",
|
||||
});
|
||||
```
|
||||
|
||||
Note that your natural language workflows the events need to be created by the `zodEvent` function passing the zod schema as an argument. The agent needs the schema of the event data to correctly generate events.
|
||||
Also, we need a `debugLabel` so the LLM can identify the event to emit in the workflow.
|
||||
|
||||
### Define the workflow
|
||||
|
||||
As usual you first create the workflow:
|
||||
|
||||
```typescript
|
||||
import { agentHandler, createWorkflow } from "@llamaindex/workflow";
|
||||
|
||||
const jokeFlow = createWorkflow();
|
||||
```
|
||||
|
||||
Then you need to handle the events. For the handlers, instead of code, you're now going to use natural language by calling the `agentHandler` function.
|
||||
|
||||
It only requires two parameters:
|
||||
- `instructions`: A prompt to guide the agent how to handle the steps.
|
||||
- `results`: The output events that the agent should return after handling the step.
|
||||
|
||||
Then you will have a simple code to handle the step:
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle(
|
||||
[writeJokeEvent],
|
||||
agentHandler({
|
||||
instructions: `You are a joke writer. You are given a topic and you need to write a joke about it.`,
|
||||
results: [critiqueEvent],
|
||||
}),
|
||||
);
|
||||
|
||||
jokeFlow.handle(
|
||||
[critiqueEvent],
|
||||
agentHandler({
|
||||
instructions: `
|
||||
You are given a joke and you need to critique it. Follow the following guidelines:
|
||||
1. You have maximum 3 times to improve the joke.
|
||||
2. If the joke is not good, increase the retriedTimes, describe how to improve the joke and send a writeJokeEvent.
|
||||
3. If the joke is good, trigger the finalResultEvent event.
|
||||
`,
|
||||
results: [writeJokeEvent, finalResultEvent],
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
For advanced usage, you can add more functionality to `agentHandler` by using these parameters:
|
||||
- `events`: A list of additional events that the agent can emit to the workflow. E.g., your agent can emit a `uiEvent` to update the UI during the execution.
|
||||
- `tools`: A list of tools that the agent can use to handle the step. E.g., your agent can use a `search` tool to search the web.
|
||||
|
||||
You can find more code examples in the [examples](https://github.com/run-llama/LlamaIndexTS/tree/main/examples/agents/natural) folder.
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/cloudflare-worker-agent-test
|
||||
|
||||
## 0.0.169
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 0.0.168
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.0.167
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.0.166
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloudflare-worker-agent-test",
|
||||
"version": "0.0.166",
|
||||
"version": "0.0.169",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @llamaindex/llama-parse-browser-test
|
||||
|
||||
## 0.0.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/cloud@4.0.14
|
||||
|
||||
## 0.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/llama-parse-browser-test",
|
||||
"private": true,
|
||||
"version": "0.0.68",
|
||||
"version": "0.0.69",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/next-agent-test
|
||||
|
||||
## 0.1.169
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 0.1.168
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.1.167
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.1.166
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-agent-test",
|
||||
"version": "0.1.166",
|
||||
"version": "0.1.169",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# test-edge-runtime
|
||||
|
||||
## 0.1.168
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 0.1.167
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.1.166
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.1.165
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/nextjs-edge-runtime-test",
|
||||
"version": "0.1.165",
|
||||
"version": "0.1.168",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @llamaindex/next-node-runtime
|
||||
|
||||
## 0.1.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
- @llamaindex/huggingface@0.1.14
|
||||
- @llamaindex/readers@3.1.8
|
||||
|
||||
## 0.1.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.1.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.1.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-node-runtime-test",
|
||||
"version": "0.1.33",
|
||||
"version": "0.1.36",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# vite-import-llamaindex
|
||||
|
||||
## 0.0.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 0.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.0.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.0.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vite-import-llamaindex",
|
||||
"private": true,
|
||||
"version": "0.0.32",
|
||||
"version": "0.0.35",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/waku-query-engine-test
|
||||
|
||||
## 0.0.169
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 0.0.168
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.0.167
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.0.166
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/waku-query-engine-test",
|
||||
"version": "0.0.166",
|
||||
"version": "0.0.169",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,74 @@
|
||||
# examples
|
||||
|
||||
## 0.3.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8a51c16]
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/workflow@1.1.9
|
||||
- @llamaindex/core@0.6.10
|
||||
- llamaindex@0.11.8
|
||||
- @llamaindex/cloud@4.0.14
|
||||
- @llamaindex/node-parser@2.0.10
|
||||
- @llamaindex/anthropic@0.3.12
|
||||
- @llamaindex/assemblyai@0.1.9
|
||||
- @llamaindex/clip@0.0.60
|
||||
- @llamaindex/cohere@0.0.24
|
||||
- @llamaindex/deepinfra@0.0.60
|
||||
- @llamaindex/discord@0.1.9
|
||||
- @llamaindex/google@0.3.9
|
||||
- @llamaindex/huggingface@0.1.14
|
||||
- @llamaindex/jinaai@0.0.20
|
||||
- @llamaindex/mistral@0.1.10
|
||||
- @llamaindex/mixedbread@0.0.24
|
||||
- @llamaindex/notion@0.1.9
|
||||
- @llamaindex/ollama@0.1.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
- @llamaindex/perplexity@0.0.17
|
||||
- @llamaindex/portkey-ai@0.0.52
|
||||
- @llamaindex/replicate@0.0.52
|
||||
- @llamaindex/astra@0.0.24
|
||||
- @llamaindex/azure@0.1.21
|
||||
- @llamaindex/chroma@0.0.24
|
||||
- @llamaindex/elastic-search@0.1.10
|
||||
- @llamaindex/firestore@1.0.17
|
||||
- @llamaindex/milvus@0.1.19
|
||||
- @llamaindex/mongodb@0.0.25
|
||||
- @llamaindex/pinecone@0.1.10
|
||||
- @llamaindex/postgres@0.0.53
|
||||
- @llamaindex/qdrant@0.1.20
|
||||
- @llamaindex/supabase@0.1.9
|
||||
- @llamaindex/upstash@0.0.24
|
||||
- @llamaindex/weaviate@0.0.25
|
||||
- @llamaindex/vercel@0.1.10
|
||||
- @llamaindex/voyage-ai@1.0.16
|
||||
- @llamaindex/readers@3.1.8
|
||||
- @llamaindex/tools@0.0.16
|
||||
- @llamaindex/deepseek@0.0.20
|
||||
- @llamaindex/fireworks@0.0.20
|
||||
- @llamaindex/groq@0.0.75
|
||||
- @llamaindex/together@0.0.20
|
||||
- @llamaindex/vllm@0.0.46
|
||||
- @llamaindex/xai@0.0.7
|
||||
|
||||
## 0.3.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [dbd857f]
|
||||
- Updated dependencies [3c857f4]
|
||||
- @llamaindex/workflow@1.1.8
|
||||
- llamaindex@0.11.7
|
||||
- @llamaindex/tools@0.0.15
|
||||
|
||||
## 0.3.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e7484ef]
|
||||
- @llamaindex/weaviate@0.0.24
|
||||
|
||||
## 0.3.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { tool } from "@llamaindex/core/tools";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import {
|
||||
agent,
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
multiAgent,
|
||||
} from "@llamaindex/workflow";
|
||||
import fs from "fs";
|
||||
import { tool } from "llamaindex";
|
||||
import os from "os";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
import { ToolCallLLM } from "llamaindex";
|
||||
|
||||
import {
|
||||
agentHandler,
|
||||
createWorkflow,
|
||||
workflowEvent,
|
||||
zodEvent,
|
||||
} from "@llamaindex/workflow";
|
||||
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
// ===== 1. Define events =====
|
||||
// An event to trigger the workflow
|
||||
const planEvent = workflowEvent<{ topic: string }>();
|
||||
|
||||
// Generate artifact event
|
||||
const ArtifactRequirementSchema = z.object({
|
||||
type: z.literal("markdown"),
|
||||
title: z.string().describe("The title of the artifact."),
|
||||
requirement: z
|
||||
.string()
|
||||
.describe("The requirement for the artifact generation."),
|
||||
});
|
||||
|
||||
const generateArtifactEvent = zodEvent(ArtifactRequirementSchema, {
|
||||
debugLabel: "generateArtifactEvent",
|
||||
});
|
||||
|
||||
// Artifact output event
|
||||
const ArtifactSchema = z.object({
|
||||
type: z.literal("artifact"),
|
||||
data: z.object({
|
||||
type: z.literal("document"),
|
||||
data: z.object({
|
||||
title: z.string().describe("The title of the data."),
|
||||
content: z.string().describe("The content of the data."),
|
||||
type: z.enum(["markdown", "html"]).describe("The type of the data."),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
const outputArtifactEvent = zodEvent(ArtifactSchema, {
|
||||
debugLabel: "outputArtifactEvent",
|
||||
});
|
||||
|
||||
// Events for updating UI
|
||||
// assume that we have a UI that can render different states of the workflow
|
||||
// and update the UI based on the state and the requirement
|
||||
export const UIEventSchema = z.object({
|
||||
type: z.literal("ui_event"),
|
||||
data: z.object({
|
||||
state: z
|
||||
.enum(["plan", "generate", "completed"])
|
||||
.describe("The current state of the workflow."),
|
||||
requirement: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
"An optional requirement creating or updating a document, if applicable.",
|
||||
),
|
||||
}),
|
||||
});
|
||||
const uiEvent = zodEvent(UIEventSchema, { debugLabel: "uiEvent" });
|
||||
|
||||
// ===== 2. Define workflow with agents using natural language =====
|
||||
// We have a document artifact workflow that made up of 2 steps:
|
||||
// 1. Generate requirement for the document
|
||||
// 2. Generate document content based on the requirement
|
||||
export function createDocumentArtifactWorkflow(llm: ToolCallLLM) {
|
||||
const workflow = createWorkflow();
|
||||
|
||||
// Generate requirement for the document
|
||||
workflow.handle(
|
||||
[planEvent],
|
||||
agentHandler({
|
||||
instructions: `
|
||||
Your task is to analyze the request and provide requirements for document generation or update.
|
||||
1. Send an uiEvent with the \`plan\` to show UI what you are going to do.
|
||||
2. Analyze the conversation history and the user's request carefully to determine the completed tasks and the next steps.
|
||||
3. Return the generateArtifactEvent with the requirement for the next step of the document generation or update.
|
||||
`,
|
||||
results: [generateArtifactEvent],
|
||||
events: [uiEvent],
|
||||
llm,
|
||||
}),
|
||||
);
|
||||
|
||||
// Generate document content based on the requirement
|
||||
workflow.handle(
|
||||
[generateArtifactEvent],
|
||||
agentHandler({
|
||||
instructions: `
|
||||
You are a skilled technical writer who can assist users with documentation.
|
||||
Your task is to generate document content based on the requirement and update the UI state.
|
||||
|
||||
Here are the steps to handle this task:
|
||||
1. First, send an uiEvent with the \`generate\` state and the requirement you received from the input.
|
||||
2. Next, start generating the content based on the requirement then send an uiEvent with the \`completed\` state to update the state.
|
||||
3. Finally, return the outputArtifactEvent with the document values.
|
||||
`,
|
||||
results: [outputArtifactEvent],
|
||||
events: [uiEvent],
|
||||
llm,
|
||||
}),
|
||||
);
|
||||
|
||||
return workflow;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
const workflow = createDocumentArtifactWorkflow(llm);
|
||||
const { stream, sendEvent } = workflow.createContext();
|
||||
|
||||
// Ask the workflow to generate a document about `llama`
|
||||
sendEvent(planEvent.with({ topic: "llama" }));
|
||||
|
||||
await stream.until(outputArtifactEvent).forEach((event) => {
|
||||
if (planEvent.include(event)) {
|
||||
console.log("Starting workflow: ", event.data);
|
||||
}
|
||||
if (uiEvent.include(event)) {
|
||||
console.log("UI event: ", event.data);
|
||||
} else if (outputArtifactEvent.include(event)) {
|
||||
console.log("Output artifact event: ", event.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,93 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agentHandler, createWorkflow, zodEvent } from "@llamaindex/workflow";
|
||||
import { Settings } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
Settings.llm = llm;
|
||||
|
||||
// Define our workflow events
|
||||
const writeJokeSchema = z.object({
|
||||
description: z
|
||||
.string()
|
||||
.describe("The topic to write a joke or describe the joke to improve."),
|
||||
writtenJoke: z.optional(z.string()).describe("The written joke."),
|
||||
retriedTimes: z
|
||||
.number()
|
||||
.default(0)
|
||||
.describe(
|
||||
"The retried times for writing the joke. Always increase this from the input retriedTimes.",
|
||||
),
|
||||
});
|
||||
|
||||
const critiqueSchema = z.object({
|
||||
joke: z.string().describe("The joke to critique"),
|
||||
retriedTimes: z.number().describe("The retried times for writing the joke."),
|
||||
});
|
||||
|
||||
const finalResultSchema = z.object({
|
||||
joke: z.string().describe("The joke to critique"),
|
||||
critique: z.string().describe("The critique of the joke"),
|
||||
});
|
||||
|
||||
const writeJokeEvent = zodEvent(writeJokeSchema, {
|
||||
debugLabel: "writeJokeEvent",
|
||||
}); // Input topic for writing a joke
|
||||
const critiqueEvent = zodEvent(critiqueSchema, {
|
||||
debugLabel: "critiqueEvent",
|
||||
}); // Ask for critique of the joke
|
||||
const finalResultEvent = zodEvent(finalResultSchema, {
|
||||
debugLabel: "finalResultEvent",
|
||||
}); // Final result
|
||||
|
||||
// Create our workflow
|
||||
const jokeFlow = createWorkflow();
|
||||
|
||||
// Define handlers for each step
|
||||
// This step always write a joke based on the description
|
||||
jokeFlow.handle(
|
||||
[writeJokeEvent],
|
||||
agentHandler({
|
||||
instructions: `You are a joke writer. You are given a topic and you need to write a joke about it.`,
|
||||
results: [critiqueEvent],
|
||||
}),
|
||||
);
|
||||
|
||||
// This step critiques the joke and asks the writer to improve the joke or send a final result event for stopping.
|
||||
jokeFlow.handle(
|
||||
[critiqueEvent],
|
||||
agentHandler({
|
||||
instructions: `
|
||||
You are given a joke and you need to critique it. Follow the following guidelines:
|
||||
1. You have maximum 3 times to improve the joke.
|
||||
2. If the joke is not good, increase the retriedTimes, describe how to improve the joke and send a writeJokeEvent.
|
||||
3. If the joke is good, trigger the finalResultEvent event.
|
||||
`,
|
||||
results: [writeJokeEvent, finalResultEvent],
|
||||
}),
|
||||
);
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(writeJokeEvent.with({ description: "write a joke about llama" }));
|
||||
|
||||
await stream.until(finalResultEvent).forEach((event) => {
|
||||
if (writeJokeEvent.include(event)) {
|
||||
console.log(
|
||||
"Triggering write joke: ",
|
||||
JSON.stringify(event.data, null, 2),
|
||||
);
|
||||
} else if (critiqueEvent.include(event)) {
|
||||
console.log("Written joke: ", JSON.stringify(event.data, null, 2));
|
||||
} else if (finalResultEvent.include(event)) {
|
||||
console.log("Output: ", JSON.stringify(event.data, null, 2));
|
||||
} else {
|
||||
console.log("Unknown event: ", JSON.stringify(event.data, null, 2));
|
||||
}
|
||||
});
|
||||
console.log("Done");
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ModalityType } from "@llamaindex/core/schema";
|
||||
import { tool } from "@llamaindex/core/tools";
|
||||
import { gemini, GEMINI_MODEL } from "@llamaindex/google";
|
||||
import { ModalityType, tool } from "llamaindex";
|
||||
|
||||
import { liveEvents } from "llamaindex";
|
||||
import { z } from "zod";
|
||||
|
||||
+46
-46
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/examples",
|
||||
"version": "0.3.19",
|
||||
"version": "0.3.22",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
@@ -11,51 +11,51 @@
|
||||
"@azure/cosmos": "^4.1.1",
|
||||
"@azure/identity": "^4.4.1",
|
||||
"@azure/search-documents": "^12.1.0",
|
||||
"@llamaindex/anthropic": "^0.3.11",
|
||||
"@llamaindex/assemblyai": "^0.1.8",
|
||||
"@llamaindex/astra": "^0.0.23",
|
||||
"@llamaindex/azure": "^0.1.20",
|
||||
"@llamaindex/chroma": "^0.0.23",
|
||||
"@llamaindex/clip": "^0.0.59",
|
||||
"@llamaindex/cloud": "^4.0.13",
|
||||
"@llamaindex/cohere": "^0.0.23",
|
||||
"@llamaindex/core": "^0.6.9",
|
||||
"@llamaindex/deepinfra": "^0.0.59",
|
||||
"@llamaindex/deepseek": "^0.0.19",
|
||||
"@llamaindex/discord": "^0.1.8",
|
||||
"@llamaindex/elastic-search": "^0.1.9",
|
||||
"@llamaindex/anthropic": "^0.3.12",
|
||||
"@llamaindex/assemblyai": "^0.1.9",
|
||||
"@llamaindex/astra": "^0.0.24",
|
||||
"@llamaindex/azure": "^0.1.21",
|
||||
"@llamaindex/chroma": "^0.0.24",
|
||||
"@llamaindex/clip": "^0.0.60",
|
||||
"@llamaindex/cloud": "^4.0.14",
|
||||
"@llamaindex/cohere": "^0.0.24",
|
||||
"@llamaindex/core": "^0.6.10",
|
||||
"@llamaindex/deepinfra": "^0.0.60",
|
||||
"@llamaindex/deepseek": "^0.0.20",
|
||||
"@llamaindex/discord": "^0.1.9",
|
||||
"@llamaindex/elastic-search": "^0.1.10",
|
||||
"@llamaindex/env": "^0.1.30",
|
||||
"@llamaindex/firestore": "^1.0.16",
|
||||
"@llamaindex/fireworks": "^0.0.19",
|
||||
"@llamaindex/google": "^0.3.6",
|
||||
"@llamaindex/groq": "^0.0.74",
|
||||
"@llamaindex/huggingface": "^0.1.13",
|
||||
"@llamaindex/jinaai": "^0.0.19",
|
||||
"@llamaindex/milvus": "^0.1.18",
|
||||
"@llamaindex/mistral": "^0.1.9",
|
||||
"@llamaindex/mixedbread": "^0.0.23",
|
||||
"@llamaindex/mongodb": "^0.0.24",
|
||||
"@llamaindex/node-parser": "^2.0.9",
|
||||
"@llamaindex/notion": "^0.1.8",
|
||||
"@llamaindex/ollama": "^0.1.9",
|
||||
"@llamaindex/openai": "^0.4.3",
|
||||
"@llamaindex/perplexity": "^0.0.16",
|
||||
"@llamaindex/pinecone": "^0.1.9",
|
||||
"@llamaindex/portkey-ai": "^0.0.51",
|
||||
"@llamaindex/postgres": "^0.0.52",
|
||||
"@llamaindex/qdrant": "^0.1.19",
|
||||
"@llamaindex/readers": "^3.1.7",
|
||||
"@llamaindex/replicate": "^0.0.51",
|
||||
"@llamaindex/supabase": "^0.1.8",
|
||||
"@llamaindex/together": "^0.0.19",
|
||||
"@llamaindex/tools": "^0.0.14",
|
||||
"@llamaindex/upstash": "^0.0.23",
|
||||
"@llamaindex/vercel": "^0.1.9",
|
||||
"@llamaindex/vllm": "^0.0.45",
|
||||
"@llamaindex/voyage-ai": "^1.0.15",
|
||||
"@llamaindex/weaviate": "^0.0.23",
|
||||
"@llamaindex/workflow": "^1.1.6",
|
||||
"@llamaindex/xai": "workspace:^0.0.6",
|
||||
"@llamaindex/firestore": "^1.0.17",
|
||||
"@llamaindex/fireworks": "^0.0.20",
|
||||
"@llamaindex/google": "^0.3.9",
|
||||
"@llamaindex/groq": "^0.0.75",
|
||||
"@llamaindex/huggingface": "^0.1.14",
|
||||
"@llamaindex/jinaai": "^0.0.20",
|
||||
"@llamaindex/milvus": "^0.1.19",
|
||||
"@llamaindex/mistral": "^0.1.10",
|
||||
"@llamaindex/mixedbread": "^0.0.24",
|
||||
"@llamaindex/mongodb": "^0.0.25",
|
||||
"@llamaindex/node-parser": "^2.0.10",
|
||||
"@llamaindex/notion": "^0.1.9",
|
||||
"@llamaindex/ollama": "^0.1.10",
|
||||
"@llamaindex/openai": "^0.4.4",
|
||||
"@llamaindex/perplexity": "^0.0.17",
|
||||
"@llamaindex/pinecone": "^0.1.10",
|
||||
"@llamaindex/portkey-ai": "^0.0.52",
|
||||
"@llamaindex/postgres": "^0.0.53",
|
||||
"@llamaindex/qdrant": "^0.1.20",
|
||||
"@llamaindex/readers": "^3.1.8",
|
||||
"@llamaindex/replicate": "^0.0.52",
|
||||
"@llamaindex/supabase": "^0.1.9",
|
||||
"@llamaindex/together": "^0.0.20",
|
||||
"@llamaindex/tools": "^0.0.16",
|
||||
"@llamaindex/upstash": "^0.0.24",
|
||||
"@llamaindex/vercel": "^0.1.10",
|
||||
"@llamaindex/vllm": "^0.0.46",
|
||||
"@llamaindex/voyage-ai": "^1.0.16",
|
||||
"@llamaindex/weaviate": "^0.0.25",
|
||||
"@llamaindex/workflow": "^1.1.9",
|
||||
"@llamaindex/xai": "workspace:^0.0.7",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
"@pinecone-database/pinecone": "^4.0.0",
|
||||
"@vercel/postgres": "^0.10.0",
|
||||
@@ -64,7 +64,7 @@
|
||||
"commander": "^12.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"js-tiktoken": "^1.0.14",
|
||||
"llamaindex": "^0.11.5",
|
||||
"llamaindex": "^0.11.8",
|
||||
"mongodb": "6.7.0",
|
||||
"postgres": "^3.4.4",
|
||||
"wikipedia": "^2.1.2",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/autotool
|
||||
|
||||
## 8.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 8.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 8.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 8.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @llamaindex/autotool-01-node-example
|
||||
|
||||
## 0.0.116
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
- @llamaindex/autotool@8.0.8
|
||||
|
||||
## 0.0.115
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
- @llamaindex/autotool@8.0.7
|
||||
|
||||
## 0.0.114
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
- @llamaindex/autotool@8.0.6
|
||||
|
||||
## 0.0.113
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
"scripts": {
|
||||
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
|
||||
},
|
||||
"version": "0.0.113"
|
||||
"version": "0.0.116"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"url": "git+https://github.com/run-llama/LlamaIndexTS.git",
|
||||
"directory": "packages/autotool"
|
||||
},
|
||||
"version": "8.0.5",
|
||||
"version": "8.0.8",
|
||||
"description": "auto transpile your JS function to LLM Agent compatible",
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/cloud
|
||||
|
||||
## 4.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 4.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloud",
|
||||
"version": "4.0.13",
|
||||
"version": "4.0.14",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @llamaindex/core
|
||||
|
||||
## 0.6.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1b5af14: fix: jsonToNode for image nodes
|
||||
|
||||
## 0.6.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/core",
|
||||
"type": "module",
|
||||
"version": "0.6.9",
|
||||
"version": "0.6.10",
|
||||
"description": "LlamaIndex Core Module",
|
||||
"exports": {
|
||||
"./agent": {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage } from "../llms";
|
||||
import { type BaseChatStore, SimpleChatStore } from "../storage/chat-store";
|
||||
import type { ChatMessage, MessageContent, MessageType } from "../llms";
|
||||
import { SimpleChatStore, type BaseChatStore } from "../storage/chat-store";
|
||||
import { extractText } from "../utils";
|
||||
import type { MemoryBlockContent } from "./types";
|
||||
|
||||
export const DEFAULT_TOKEN_LIMIT_RATIO = 0.75;
|
||||
export const DEFAULT_CHAT_STORE_KEY = "chat_history";
|
||||
@@ -83,3 +84,70 @@ export abstract class BaseChatStoreMemory<
|
||||
this.chatStore.deleteMessages(this.chatStoreKey);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseMemoryBlock<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
protected priority: number;
|
||||
protected content: MemoryBlockContent[];
|
||||
|
||||
constructor(priority: number, content: MemoryBlockContent[]) {
|
||||
this.priority = priority;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all content from the memory block.
|
||||
* @returns An array of content.
|
||||
*/
|
||||
get(): MemoryBlockContent[] {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new content to the memory block.
|
||||
* @param content The content to be added to the memory block.
|
||||
*/
|
||||
add(content: MemoryBlockContent): void {
|
||||
this.content.push(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all content from the memory block.
|
||||
*/
|
||||
clear(): void {
|
||||
this.content = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the priority of the memory block.
|
||||
* @returns The priority of the memory block.
|
||||
*/
|
||||
getPriority = (): number => this.priority;
|
||||
|
||||
/**
|
||||
* Converts content to messages.
|
||||
* @param content The content to be converted to messages.
|
||||
* @returns An array of messages.
|
||||
*/
|
||||
toMessages(): ChatMessage<AdditionalMessageOptions>[] {
|
||||
return this.content.map((entry) => {
|
||||
// If entry is a ChatMessage, return it
|
||||
if (typeof entry === "object" && "content" in entry && "role" in entry) {
|
||||
return entry as ChatMessage<AdditionalMessageOptions>;
|
||||
}
|
||||
// Else, create a new ChatMessage with the entry as content
|
||||
return {
|
||||
content: entry as MessageContent,
|
||||
role: "system" as MessageType,
|
||||
options: {} as AdditionalMessageOptions,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class StaticMemoryBlock extends BaseMemoryBlock {
|
||||
constructor(content: MemoryBlockContent[], priority: number) {
|
||||
super(priority, content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { StaticMemoryBlock } from "./base";
|
||||
import { Memory } from "./memory";
|
||||
import type { MemoryBlockContent, MemoryOptions } from "./types";
|
||||
|
||||
/**
|
||||
* Create a new enhanced memory instance with support for dual message formats,
|
||||
* snapshots, and memory blocks
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Basic usage
|
||||
* const memory = createMemory();
|
||||
*
|
||||
* // With configuration
|
||||
* const memory = createMemory({
|
||||
* tokenLimit: 10_000,
|
||||
* blocks: [
|
||||
* staticMemoryBlock(["You are a helpful assistant named Claude."], 0),
|
||||
* ],
|
||||
* });
|
||||
*
|
||||
* // Add messages in different formats
|
||||
* await memory.add({
|
||||
* content: "Hello, how are you?",
|
||||
* role: "user",
|
||||
* });
|
||||
*
|
||||
* // Get messages in Vercel AI format
|
||||
* const uiMessages = await memory.get({ type: "vercel" });
|
||||
*
|
||||
* // Save and restore memory state
|
||||
* const snapshot = memory.snapshot();
|
||||
* await memory.loadSnapshot(snapshot);
|
||||
* ```
|
||||
*
|
||||
* @param options Configuration options for the memory instance
|
||||
* @returns A new EnhancedMemory instance
|
||||
*/
|
||||
export function createMemory(options: MemoryOptions = {}): Memory {
|
||||
return new Memory(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new static memory block instance
|
||||
*
|
||||
* @param content The content of the memory block
|
||||
* @param priority The priority of the memory block
|
||||
* @returns A new StaticMemoryBlock instance
|
||||
*/
|
||||
export function staticMemoryBlock(
|
||||
content: MemoryBlockContent[],
|
||||
priority: number,
|
||||
): StaticMemoryBlock {
|
||||
return new StaticMemoryBlock(content, priority);
|
||||
}
|
||||
@@ -1,3 +1,16 @@
|
||||
export { BaseMemory } from "./base";
|
||||
// Existing exports (backward compatibility)
|
||||
export { BaseChatStoreMemory, BaseMemory } from "./base";
|
||||
export { ChatMemoryBuffer } from "./chat-memory-buffer";
|
||||
export { ChatSummaryMemoryBuffer } from "./summary-memory";
|
||||
|
||||
export { createMemory, staticMemoryBlock } from "./factory";
|
||||
export { Memory } from "./memory";
|
||||
export { MessageConverter } from "./message-converter";
|
||||
|
||||
// Type exports
|
||||
export type {
|
||||
GetMessageOptions,
|
||||
MemoryOptions,
|
||||
UIMessage,
|
||||
UIPart,
|
||||
} from "./types";
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import { Settings, type JSONValue } from "../global";
|
||||
import type { ChatMessage } from "../llms";
|
||||
import { extractText } from "../utils";
|
||||
import { BaseMemoryBlock, StaticMemoryBlock } from "./base";
|
||||
import { MessageConverter } from "./message-converter";
|
||||
import type { GetMessageOptions, MemoryOptions, UIMessage } from "./types";
|
||||
import { serializeChatMessage, serializeMessageContent } from "./utils";
|
||||
|
||||
const DEFAULT_TOKEN_LIMIT = 4096;
|
||||
|
||||
export class Memory {
|
||||
private blocks: BaseMemoryBlock[] = [];
|
||||
private tokenLimit: number;
|
||||
|
||||
constructor(options: MemoryOptions = {}) {
|
||||
this.blocks = options.blocks || [];
|
||||
this.tokenLimit = options.tokenLimit || DEFAULT_TOKEN_LIMIT;
|
||||
}
|
||||
|
||||
private async getAllMessages(): Promise<ChatMessage[]> {
|
||||
// Order blocks by priority
|
||||
const orderedBlocks = this.blocks.sort(
|
||||
(a, b) => b.getPriority() - a.getPriority(),
|
||||
);
|
||||
|
||||
// Get all messages
|
||||
return orderedBlocks.map((block) => block.toMessages()).flat();
|
||||
}
|
||||
|
||||
async getMessagesWithLimit(tokenLimit: number): Promise<ChatMessage[]> {
|
||||
const messages = await this.getAllMessages();
|
||||
return this.applyTokenLimit(messages, tokenLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns Return a serialized snapshot of the memory in JSON format.
|
||||
*/
|
||||
snapshot(): JSONValue {
|
||||
return {
|
||||
blocks: this.blocks.map((block) =>
|
||||
block.get().map((message) => {
|
||||
if (MessageConverter.isChatMessage(message)) {
|
||||
return serializeChatMessage(message);
|
||||
}
|
||||
return serializeMessageContent(message);
|
||||
}),
|
||||
),
|
||||
metadata: {
|
||||
tokenLimit: this.tokenLimit,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async loadSnapshot(snapshot: JSONValue): Promise<void> {}
|
||||
|
||||
async add(message: ChatMessage | UIMessage): Promise<void> {
|
||||
let llamaMessage: ChatMessage;
|
||||
|
||||
if (MessageConverter.isUIMessage(message)) {
|
||||
llamaMessage = MessageConverter.toLlamaIndexMessage(message);
|
||||
} else if (MessageConverter.isChatMessage(message)) {
|
||||
llamaMessage = message as ChatMessage;
|
||||
} else {
|
||||
throw new Error(
|
||||
"Invalid message format. Expected ChatMessage or UIMessage.",
|
||||
);
|
||||
}
|
||||
|
||||
// Convert message to block
|
||||
const block = new StaticMemoryBlock([llamaMessage.content], 0);
|
||||
|
||||
this.blocks.push(block);
|
||||
}
|
||||
|
||||
async get(options?: GetMessageOptions): Promise<ChatMessage[] | UIMessage[]> {
|
||||
const messages = await this.getAllMessages();
|
||||
|
||||
if (options?.type === "vercel") {
|
||||
return messages.map((message) => MessageConverter.toUIMessage(message));
|
||||
}
|
||||
|
||||
// Default to LlamaIndex format
|
||||
return messages;
|
||||
}
|
||||
|
||||
async getLLM(): Promise<ChatMessage[]> {
|
||||
// Convert all blocks to messages
|
||||
const allMessages = await this.getAllMessages();
|
||||
|
||||
// Apply token limit
|
||||
return this.applyTokenLimit(allMessages, this.tokenLimit);
|
||||
}
|
||||
|
||||
async clear(): Promise<void> {
|
||||
this.blocks = [];
|
||||
}
|
||||
|
||||
private applyTokenLimit(
|
||||
messages: ChatMessage[],
|
||||
tokenLimit: number,
|
||||
): ChatMessage[] {
|
||||
if (messages.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let tokenCount = 0;
|
||||
const result: ChatMessage[] = [];
|
||||
|
||||
// Process messages in reverse order (keep most recent)
|
||||
for (let i = messages.length - 1; i >= 0; i--) {
|
||||
const message = messages[i];
|
||||
if (!message) continue;
|
||||
|
||||
const messageTokens = this.countMessagesToken([message]);
|
||||
|
||||
if (tokenCount + messageTokens <= tokenLimit) {
|
||||
result.unshift(message);
|
||||
tokenCount += messageTokens;
|
||||
} else {
|
||||
// If we can't fit any more messages, break
|
||||
// But always try to include at least the most recent message
|
||||
if (result.length === 0 && messageTokens <= tokenLimit) {
|
||||
result.push(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private countMessagesToken(messages: ChatMessage[]): number {
|
||||
if (messages.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
const tokenizer = Settings.tokenizer;
|
||||
const str = messages.map((m) => extractText(m.content)).join(" ");
|
||||
return tokenizer.encode(str).length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import type {
|
||||
ChatMessage,
|
||||
MessageContent,
|
||||
MessageContentDetail,
|
||||
} from "../llms";
|
||||
import { extractText } from "../utils";
|
||||
import type { UIMessage, UIPart } from "./types";
|
||||
|
||||
/**
|
||||
* Utility class for converting between LlamaIndex ChatMessage and Vercel UI Message formats
|
||||
*/
|
||||
export class MessageConverter {
|
||||
/**
|
||||
* Convert Vercel UI Message to LlamaIndex ChatMessage format
|
||||
*/
|
||||
static toLlamaIndexMessage<AdditionalMessageOptions extends object = object>(
|
||||
uiMessage: UIMessage,
|
||||
): ChatMessage<AdditionalMessageOptions> {
|
||||
// Convert UI message role to MessageType
|
||||
let role: ChatMessage["role"];
|
||||
switch (uiMessage.role) {
|
||||
case "system":
|
||||
role = "system";
|
||||
break;
|
||||
case "user":
|
||||
role = "user";
|
||||
break;
|
||||
case "assistant":
|
||||
role = "assistant";
|
||||
break;
|
||||
case "data":
|
||||
role = "system"; // Map data role to system
|
||||
break;
|
||||
default:
|
||||
role = "user"; // Default fallback
|
||||
}
|
||||
|
||||
// Convert parts to MessageContent
|
||||
const content = this.convertPartsToMessageContent(uiMessage.parts);
|
||||
|
||||
return {
|
||||
content: content || uiMessage.content,
|
||||
role,
|
||||
options: undefined as unknown as AdditionalMessageOptions,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert LlamaIndex ChatMessage to Vercel UI Message format
|
||||
*/
|
||||
static toUIMessage(llamaMessage: ChatMessage): UIMessage {
|
||||
const parts: UIPart[] = this.convertMessageContentToParts(
|
||||
llamaMessage.content,
|
||||
);
|
||||
|
||||
// Convert role to UI message role
|
||||
let role: UIMessage["role"];
|
||||
switch (llamaMessage.role) {
|
||||
case "user":
|
||||
role = "user";
|
||||
break;
|
||||
case "assistant":
|
||||
role = "assistant";
|
||||
break;
|
||||
case "system":
|
||||
case "memory":
|
||||
case "developer":
|
||||
role = "system";
|
||||
break;
|
||||
default:
|
||||
role = "user";
|
||||
}
|
||||
|
||||
return {
|
||||
id: randomUUID(),
|
||||
role,
|
||||
content: extractText(llamaMessage.content),
|
||||
parts,
|
||||
createdAt: new Date(),
|
||||
annotations: [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if object matches UIMessage structure
|
||||
*/
|
||||
static isUIMessage(message: unknown): message is UIMessage {
|
||||
if (!message || typeof message !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const msg = message as Record<string, unknown>;
|
||||
|
||||
return (
|
||||
typeof msg.id === "string" &&
|
||||
typeof msg.role === "string" &&
|
||||
["system", "user", "assistant", "data"].includes(msg.role as string) &&
|
||||
typeof msg.content === "string" &&
|
||||
Array.isArray(msg.parts)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if object matches ChatMessage structure
|
||||
*/
|
||||
static isChatMessage(message: unknown): message is ChatMessage {
|
||||
if (!message || typeof message !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const msg = message as Record<string, unknown>;
|
||||
|
||||
return (
|
||||
(typeof msg.content === "string" || Array.isArray(msg.content)) &&
|
||||
typeof msg.role === "string" &&
|
||||
["user", "assistant", "system", "memory", "developer"].includes(
|
||||
msg.role as string,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UI parts to MessageContent
|
||||
*/
|
||||
private static convertPartsToMessageContent(parts: UIPart[]): MessageContent {
|
||||
if (parts.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const details: MessageContentDetail[] = [];
|
||||
|
||||
for (const part of parts) {
|
||||
switch (part.type) {
|
||||
case "text": {
|
||||
details.push({
|
||||
type: "text",
|
||||
text: part.content || "",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "tool": {
|
||||
const toolPart = part as unknown as UIPart;
|
||||
details.push({
|
||||
type: "text",
|
||||
text: `Tool: ${part.data?.toolName}`,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "reasoning": {
|
||||
const resultPart = part as unknown as UIPart;
|
||||
details.push({
|
||||
type: "text",
|
||||
text: `Result: ${JSON.stringify(part.data?.result)}`,
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// For other part types, convert to text
|
||||
details.push({
|
||||
type: "text",
|
||||
text: JSON.stringify(part),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If only one text detail, return as string
|
||||
if (details.length === 1 && details[0]?.type === "text") {
|
||||
return details[0].text;
|
||||
}
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert MessageContent to UI parts
|
||||
*/
|
||||
private static convertMessageContentToParts(
|
||||
content: MessageContent,
|
||||
): UIPart[] {
|
||||
if (typeof content === "string") {
|
||||
return [
|
||||
{
|
||||
type: "text",
|
||||
text: content,
|
||||
} as UIPart,
|
||||
];
|
||||
}
|
||||
|
||||
const parts: UIPart[] = [];
|
||||
|
||||
for (const detail of content) {
|
||||
switch (detail.type) {
|
||||
case "text":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: detail.text,
|
||||
} as UIPart);
|
||||
break;
|
||||
case "image_url":
|
||||
// Convert image to text representation for UI
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: `[Image: ${detail.image_url.url}]`,
|
||||
} as UIPart);
|
||||
break;
|
||||
case "audio":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: `[Audio: ${detail.mimeType}]`,
|
||||
} as UIPart);
|
||||
break;
|
||||
case "video":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: `[Video: ${detail.mimeType}]`,
|
||||
} as UIPart);
|
||||
break;
|
||||
case "image":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: `[Image: ${detail.mimeType}]`,
|
||||
} as UIPart);
|
||||
break;
|
||||
case "file":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: `[File: ${detail.mimeType}]`,
|
||||
} as UIPart);
|
||||
break;
|
||||
default:
|
||||
// For unknown types, create a text representation
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: JSON.stringify(detail),
|
||||
} as UIPart);
|
||||
}
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { JSONValue } from "../global";
|
||||
import type { ChatMessage, MessageContent } from "../llms";
|
||||
import type { BaseMemoryBlock } from "./base";
|
||||
|
||||
export type MemoryBlockContent = MessageContent | ChatMessage;
|
||||
|
||||
export type MemoryOptions = {
|
||||
blocks?: BaseMemoryBlock[];
|
||||
tokenLimit?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Vercel AI SDK message types (avoid dependency)
|
||||
* These types mirror the Vercel AI SDK without requiring it as a dependency
|
||||
*/
|
||||
export interface UIMessage {
|
||||
id: string;
|
||||
role: "system" | "user" | "assistant" | "data";
|
||||
content: string;
|
||||
createdAt?: Date;
|
||||
annotations?: Array<JSONValue>;
|
||||
parts: Array<UIPart>;
|
||||
}
|
||||
|
||||
export interface UIPart {
|
||||
type: "text" | "tool" | "reasoning" | "source" | "step";
|
||||
content?: string;
|
||||
data?: Record<string, unknown>; // TODO: Can expand this to be more specific later
|
||||
}
|
||||
|
||||
export type GetMessageOptions = {
|
||||
type?: "llamaindex" | "vercel";
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
import { type JSONValue } from "../global";
|
||||
import type { ChatMessage, MessageContent } from "../llms";
|
||||
|
||||
/**
|
||||
* Serialize a message content to a JSON value.
|
||||
* @param message - The message content to serialize.
|
||||
* @returns The serialized message content.
|
||||
*/
|
||||
export function serializeMessageContent(message: MessageContent): JSONValue {
|
||||
if (typeof message === "string") {
|
||||
return message;
|
||||
}
|
||||
|
||||
// message is an array of MessageContentDetail
|
||||
return message.map((detail) => {
|
||||
const serialized: { [key: string]: JSONValue } = {
|
||||
type: detail.type,
|
||||
};
|
||||
|
||||
switch (detail.type) {
|
||||
case "text":
|
||||
serialized.text = detail.text;
|
||||
break;
|
||||
case "image_url":
|
||||
serialized.image_url = {
|
||||
url: detail.image_url.url,
|
||||
};
|
||||
if (detail.detail) {
|
||||
(serialized.image_url as { [key: string]: JSONValue }).detail =
|
||||
detail.detail;
|
||||
}
|
||||
break;
|
||||
case "audio":
|
||||
serialized.data = detail.data;
|
||||
serialized.mimeType = detail.mimeType;
|
||||
break;
|
||||
case "video":
|
||||
serialized.data = detail.data;
|
||||
serialized.mimeType = detail.mimeType;
|
||||
break;
|
||||
case "image":
|
||||
serialized.data = detail.data;
|
||||
serialized.mimeType = detail.mimeType;
|
||||
break;
|
||||
case "file":
|
||||
serialized.data = detail.data;
|
||||
serialized.mimeType = detail.mimeType;
|
||||
break;
|
||||
default:
|
||||
// For any unknown types, serialize all properties
|
||||
Object.assign(serialized, detail);
|
||||
}
|
||||
|
||||
return serialized;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize a chat message to a JSON value.
|
||||
* @param message - The chat message to serialize.
|
||||
* @returns The serialized chat message.
|
||||
*/
|
||||
export function serializeChatMessage(message: ChatMessage): JSONValue {
|
||||
const serialized: { [key: string]: JSONValue } = {
|
||||
content: serializeMessageContent(message.content),
|
||||
role: message.role,
|
||||
};
|
||||
|
||||
if (message.options) {
|
||||
serialized.options = message.options as JSONValue;
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
@@ -39,11 +39,45 @@ let sentenceTokenizer: SentenceTokenizer | null = null;
|
||||
export const splitBySentenceTokenizer = (): TextSplitterFn => {
|
||||
if (!sentenceTokenizer) {
|
||||
sentenceTokenizer = new SentenceTokenizer([
|
||||
// TODO: This should be improved. Take a look at: https://github.com/run-llama/LlamaIndexTS/issues/2019
|
||||
// English
|
||||
"i.e.",
|
||||
"etc.",
|
||||
"vs.",
|
||||
"Inc.",
|
||||
"A.S.A.P.",
|
||||
"Mr.",
|
||||
"Mrs.",
|
||||
"Ms.",
|
||||
"Dr.",
|
||||
"Prof.",
|
||||
"Sr.",
|
||||
"Jr.",
|
||||
// Spanish
|
||||
"Sr.",
|
||||
"Sres.",
|
||||
"Srs.",
|
||||
"Sra.",
|
||||
"Sras.",
|
||||
"Srta.",
|
||||
"Srtas.",
|
||||
"Dr.",
|
||||
"Drs.",
|
||||
"Dra.",
|
||||
"Dras.",
|
||||
"Prof.",
|
||||
"Profs.",
|
||||
"Profa.",
|
||||
"Profas.",
|
||||
"Ing.",
|
||||
"Lic.",
|
||||
"Arq.",
|
||||
"Ab.",
|
||||
"Abs.",
|
||||
"Tel.",
|
||||
"a.m.",
|
||||
"p.m.",
|
||||
"Art.",
|
||||
]);
|
||||
}
|
||||
const tokenizer = sentenceTokenizer;
|
||||
|
||||
@@ -347,6 +347,8 @@ export function jsonToNode(json: any, type?: ObjectType) {
|
||||
return new Document(json);
|
||||
case ObjectType.IMAGE_DOCUMENT:
|
||||
return new ImageDocument(json);
|
||||
case ObjectType.IMAGE:
|
||||
return new ImageNode(json);
|
||||
default:
|
||||
throw new Error(`Invalid node type: ${nodeType}`);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { Settings } from "@llamaindex/core/global";
|
||||
import type { ChatMessage } from "@llamaindex/core/llms";
|
||||
import { createMemory, staticMemoryBlock } from "@llamaindex/core/memory";
|
||||
import { beforeEach, describe, expect, test } from "vitest";
|
||||
|
||||
describe("createMemory factory function", () => {
|
||||
beforeEach(() => {
|
||||
// Mock the Settings.llm
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(Settings.llm as any) = {
|
||||
metadata: {
|
||||
contextWindow: 1000,
|
||||
maxTokens: 100,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
test("creates memory with default settings", () => {
|
||||
const memory = createMemory();
|
||||
expect(memory).toBeDefined();
|
||||
expect(typeof memory.add).toBe("function");
|
||||
expect(typeof memory.get).toBe("function");
|
||||
expect(typeof memory.getLLM).toBe("function");
|
||||
expect(typeof memory.clear).toBe("function");
|
||||
expect(typeof memory.snapshot).toBe("function");
|
||||
expect(typeof memory.loadSnapshot).toBe("function");
|
||||
});
|
||||
|
||||
test("creates memory with custom token limit", () => {
|
||||
const memory = createMemory({ tokenLimit: 5000 });
|
||||
expect(memory).toBeDefined();
|
||||
});
|
||||
|
||||
test("creates memory with memory blocks", () => {
|
||||
const blocks = [staticMemoryBlock(["You are a helpful assistant."], 0)];
|
||||
const memory = createMemory({ blocks });
|
||||
expect(memory).toBeDefined();
|
||||
});
|
||||
|
||||
test("supports basic operations", async () => {
|
||||
const memory = createMemory({ tokenLimit: 1000 });
|
||||
|
||||
// Test add and get
|
||||
const message: ChatMessage = { content: "Hello", role: "user" };
|
||||
await memory.add(message);
|
||||
|
||||
const messages = await memory.get();
|
||||
expect(messages).toHaveLength(1);
|
||||
expect(messages[0]?.content).toBe("Hello");
|
||||
});
|
||||
|
||||
// test("supports snapshot operations", async () => {
|
||||
// const memory = createMemory({ tokenLimit: 1000 });
|
||||
|
||||
// await memory.add({ content: "Test message", role: "user" });
|
||||
|
||||
// const snapshot = memory.snapshot();
|
||||
// expect(snapshot).toHaveProperty("blocks");
|
||||
// expect(snapshot).toHaveProperty("metadata");
|
||||
|
||||
// const newMemory = createMemory();
|
||||
// await newMemory.loadSnapshot(snapshot);
|
||||
|
||||
// const messages = await newMemory.get();
|
||||
// expect(messages).toHaveLength(1);
|
||||
// expect(messages[0]?.content).toBe("Test message");
|
||||
// });
|
||||
|
||||
test("supports backward compatibility methods", async () => {
|
||||
const memory = createMemory({ tokenLimit: 1000 });
|
||||
|
||||
// Test legacy methods exist and work
|
||||
const message: ChatMessage = { content: "Hello", role: "user" };
|
||||
memory.add(message);
|
||||
|
||||
const messages = await memory.get();
|
||||
expect(messages).toHaveLength(1);
|
||||
expect(messages[0]?.content).toBe("Hello");
|
||||
|
||||
await memory.clear();
|
||||
const emptyMessages = await memory.get();
|
||||
expect(emptyMessages).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("creates memory with different message format support", async () => {
|
||||
const memory = createMemory({ tokenLimit: 1000 });
|
||||
|
||||
await memory.add({ content: "LlamaIndex message", role: "user" });
|
||||
|
||||
const llamaMessages = await memory.get({ type: "llamaindex" });
|
||||
expect(llamaMessages).toHaveLength(1);
|
||||
|
||||
const uiMessages = await memory.get({ type: "vercel" });
|
||||
expect(uiMessages).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,238 @@
|
||||
import { Settings } from "@llamaindex/core/global";
|
||||
import type { ChatMessage } from "@llamaindex/core/llms";
|
||||
import { beforeEach, describe, expect, test } from "vitest";
|
||||
|
||||
import type { UIMessage, UIPart } from "@llamaindex/core/memory";
|
||||
import { Memory, staticMemoryBlock } from "@llamaindex/core/memory";
|
||||
|
||||
describe("Memory", () => {
|
||||
beforeEach(() => {
|
||||
// Mock the Settings.llm
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(Settings.llm as any) = {
|
||||
metadata: {
|
||||
contextWindow: 1000,
|
||||
maxTokens: 100,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe("constructor and initialization", () => {
|
||||
test("creates with default options", () => {
|
||||
const memory = new Memory();
|
||||
expect(memory).toBeInstanceOf(Memory);
|
||||
});
|
||||
|
||||
test("creates with custom token limit", () => {
|
||||
const memory = new Memory({ tokenLimit: 5000 });
|
||||
// Test through behavior rather than private property access
|
||||
expect(memory).toBeInstanceOf(Memory);
|
||||
});
|
||||
|
||||
test("creates with memory blocks", () => {
|
||||
const blocks = [staticMemoryBlock([], 0)];
|
||||
const memory = new Memory({ blocks });
|
||||
// Test through behavior rather than private property access
|
||||
expect(memory).toBeInstanceOf(Memory);
|
||||
});
|
||||
});
|
||||
|
||||
describe("new API methods", () => {
|
||||
let memory: Memory;
|
||||
|
||||
beforeEach(() => {
|
||||
memory = new Memory({ tokenLimit: 1000 });
|
||||
});
|
||||
|
||||
describe("add method", () => {
|
||||
test("adds ChatMessage successfully", async () => {
|
||||
const message: ChatMessage = { content: "Hello", role: "user" };
|
||||
await memory.add(message);
|
||||
|
||||
const messages = await memory.get();
|
||||
expect(messages).toHaveLength(1);
|
||||
expect(messages[0]?.content).toBe("Hello");
|
||||
});
|
||||
|
||||
test("adds UIMessage successfully", async () => {
|
||||
const uiMessage: UIMessage = {
|
||||
id: "msg-1",
|
||||
content: "Hello from UI",
|
||||
role: "user",
|
||||
parts: [{ type: "text", content: "Hello from UI" } as UIPart],
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
||||
await memory.add(uiMessage);
|
||||
const messages = await memory.get();
|
||||
expect(messages).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("adds multiple messages in sequence", async () => {
|
||||
const messages = [
|
||||
{ content: "Hello", role: "user" as const },
|
||||
{ content: "Hi there!", role: "assistant" as const },
|
||||
{ content: "How are you?", role: "user" as const },
|
||||
];
|
||||
|
||||
for (const msg of messages) {
|
||||
await memory.add(msg);
|
||||
}
|
||||
|
||||
const storedMessages = await memory.get();
|
||||
expect(storedMessages).toHaveLength(3);
|
||||
});
|
||||
|
||||
test("throws error for invalid message format", async () => {
|
||||
const invalidMessage = { content: "test" }; // missing role
|
||||
await expect(
|
||||
memory.add(invalidMessage as unknown as ChatMessage),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("get method", () => {
|
||||
beforeEach(async () => {
|
||||
await memory.add({ content: "Hello", role: "user" });
|
||||
await memory.add({ content: "Hi there!", role: "assistant" });
|
||||
});
|
||||
|
||||
test("returns messages in LlamaIndex format by default", async () => {
|
||||
const messages = await memory.get();
|
||||
expect(messages).toHaveLength(2);
|
||||
expect(messages[0]).toHaveProperty("content");
|
||||
expect(messages[0]).toHaveProperty("role");
|
||||
});
|
||||
|
||||
test("returns messages in LlamaIndex format when specified", async () => {
|
||||
const messages = await memory.get({ type: "llamaindex" });
|
||||
expect(messages).toHaveLength(2);
|
||||
expect(messages[0]).toHaveProperty("content");
|
||||
expect(messages[0]).toHaveProperty("role");
|
||||
});
|
||||
|
||||
test("returns messages in UI format when specified", async () => {
|
||||
const messages = await memory.get({ type: "vercel" });
|
||||
expect(messages).toHaveLength(2);
|
||||
// UI messages should have id, parts, etc.
|
||||
expect(messages[0]).toHaveProperty("id");
|
||||
expect(messages[0]).toHaveProperty("parts");
|
||||
expect(messages[0]).toHaveProperty("content");
|
||||
expect(messages[0]).toHaveProperty("role");
|
||||
});
|
||||
|
||||
test("handles empty memory", async () => {
|
||||
const emptyMemory = new Memory();
|
||||
const messages = await emptyMemory.get();
|
||||
expect(messages).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getLLM method", () => {
|
||||
test("returns token-limited messages", async () => {
|
||||
const shortMemory = new Memory({ tokenLimit: 10 });
|
||||
|
||||
// Add messages that exceed token limit
|
||||
await shortMemory.add({
|
||||
content: "Very long message that exceeds token limit",
|
||||
role: "user",
|
||||
});
|
||||
await shortMemory.add({
|
||||
content: "Another long message",
|
||||
role: "assistant",
|
||||
});
|
||||
await shortMemory.add({ content: "Short", role: "user" });
|
||||
|
||||
const llmMessages = await shortMemory.getLLM();
|
||||
const allMessages = await shortMemory.get();
|
||||
|
||||
expect(llmMessages.length).toBeLessThanOrEqual(allMessages.length);
|
||||
});
|
||||
|
||||
test("includes memory blocks in LLM messages", async () => {
|
||||
const blocks = [staticMemoryBlock(["System instruction"], 0)];
|
||||
const memoryWithBlocks = new Memory({
|
||||
blocks,
|
||||
tokenLimit: 1000,
|
||||
});
|
||||
|
||||
await memoryWithBlocks.add({ content: "User message", role: "user" });
|
||||
|
||||
const llmMessages = await memoryWithBlocks.getLLM();
|
||||
expect(llmMessages.length).toBeGreaterThan(1); // Should include block + user message
|
||||
});
|
||||
|
||||
test("prioritizes recent messages when token limit is exceeded", async () => {
|
||||
const memory = new Memory({ tokenLimit: 20 });
|
||||
|
||||
await memory.add({ content: "Old message", role: "user" });
|
||||
await memory.add({ content: "Recent message", role: "user" });
|
||||
|
||||
const llmMessages = await memory.getLLM();
|
||||
const lastMessage = llmMessages[llmMessages.length - 1];
|
||||
expect(lastMessage?.content).toBe("Recent message");
|
||||
});
|
||||
});
|
||||
|
||||
describe("clear method", () => {
|
||||
test("clears all messages", async () => {
|
||||
await memory.add({ content: "Hello", role: "user" });
|
||||
await memory.add({ content: "Hi there!", role: "assistant" });
|
||||
|
||||
let messages = await memory.get();
|
||||
expect(messages).toHaveLength(2);
|
||||
|
||||
await memory.clear();
|
||||
messages = await memory.get();
|
||||
expect(messages).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("memory blocks functionality", () => {
|
||||
test("includes static blocks in LLM messages", async () => {
|
||||
const blocks = [
|
||||
staticMemoryBlock(["You are a helpful assistant."], 0),
|
||||
staticMemoryBlock(["Always be polite."], 0),
|
||||
];
|
||||
|
||||
const memory = new Memory({ blocks, tokenLimit: 1000 });
|
||||
await memory.add({ content: "Hello", role: "user" });
|
||||
|
||||
const llmMessages = await memory.getLLM();
|
||||
expect(llmMessages.length).toBe(3);
|
||||
|
||||
// First messages should be from blocks (converted to system messages)
|
||||
expect(llmMessages[0]?.content).toBe("You are a helpful assistant.");
|
||||
expect(llmMessages[1]?.content).toBe("Always be polite.");
|
||||
expect(llmMessages[2]?.content).toBe("Hello");
|
||||
});
|
||||
});
|
||||
|
||||
describe("error handling", () => {
|
||||
let memory: Memory;
|
||||
|
||||
beforeEach(() => {
|
||||
memory = new Memory({ tokenLimit: 1000 });
|
||||
});
|
||||
|
||||
test("handles invalid message types gracefully", async () => {
|
||||
const invalidMessage = { content: 123, role: "user" }; // invalid content type
|
||||
await expect(
|
||||
memory.add(invalidMessage as unknown as ChatMessage),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
test("handles token limit edge cases", async () => {
|
||||
const verySmallMemory = new Memory({ tokenLimit: 1 });
|
||||
await verySmallMemory.add({
|
||||
content: "This message is too long for the token limit",
|
||||
role: "user",
|
||||
});
|
||||
|
||||
const llmMessages = await verySmallMemory.getLLM();
|
||||
// Should handle gracefully, possibly returning empty array
|
||||
expect(Array.isArray(llmMessages)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
import type { ChatMessage } from "@llamaindex/core/llms";
|
||||
import type { UIMessage } from "@llamaindex/core/memory";
|
||||
import { MessageConverter } from "@llamaindex/core/memory";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
describe("MessageConverter", () => {
|
||||
describe("toUIMessage", () => {
|
||||
test("converts simple ChatMessage to UIMessage", () => {
|
||||
const chatMessage: ChatMessage = {
|
||||
content: "Hello, how are you?",
|
||||
role: "user",
|
||||
};
|
||||
|
||||
const uiMessage = MessageConverter.toUIMessage(chatMessage);
|
||||
|
||||
expect(uiMessage).toHaveProperty("id");
|
||||
expect(uiMessage.role).toBe("user");
|
||||
expect(uiMessage.content).toBe("Hello, how are you?");
|
||||
expect(uiMessage).toHaveProperty("parts");
|
||||
expect(uiMessage.parts).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("generates unique IDs for each conversion", () => {
|
||||
const chatMessage: ChatMessage = {
|
||||
content: "Test message",
|
||||
role: "user",
|
||||
};
|
||||
|
||||
const uiMessage1 = MessageConverter.toUIMessage(chatMessage);
|
||||
const uiMessage2 = MessageConverter.toUIMessage(chatMessage);
|
||||
|
||||
expect(uiMessage1.id).not.toBe(uiMessage2.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toLlamaIndexMessage", () => {
|
||||
test("converts simple UIMessage to ChatMessage", () => {
|
||||
const uiMessage: UIMessage = {
|
||||
id: "msg-123",
|
||||
content: "Hello, how are you?",
|
||||
role: "user",
|
||||
parts: [],
|
||||
};
|
||||
|
||||
const chatMessage = MessageConverter.toLlamaIndexMessage(uiMessage);
|
||||
|
||||
expect(chatMessage.content).toBe("Hello, how are you?");
|
||||
expect(chatMessage.role).toBe("user");
|
||||
});
|
||||
});
|
||||
|
||||
describe("type guards", () => {
|
||||
test("isChatMessage identifies valid ChatMessage", () => {
|
||||
const validChatMessage = {
|
||||
content: "Hello",
|
||||
role: "user",
|
||||
};
|
||||
|
||||
expect(MessageConverter.isChatMessage(validChatMessage)).toBe(true);
|
||||
});
|
||||
|
||||
test("isChatMessage rejects invalid objects", () => {
|
||||
const invalidObjects = [
|
||||
null,
|
||||
undefined,
|
||||
{ content: "Hello" }, // missing role
|
||||
{ role: "user" }, // missing content
|
||||
];
|
||||
|
||||
for (const obj of invalidObjects) {
|
||||
expect(MessageConverter.isChatMessage(obj)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("isUIMessage identifies valid UIMessage", () => {
|
||||
const validUIMessage = {
|
||||
id: "msg-123",
|
||||
content: "Hello",
|
||||
role: "user",
|
||||
parts: [],
|
||||
};
|
||||
|
||||
expect(MessageConverter.isUIMessage(validUIMessage)).toBe(true);
|
||||
});
|
||||
|
||||
test("isUIMessage rejects invalid objects", () => {
|
||||
const invalidObjects = [
|
||||
null,
|
||||
undefined,
|
||||
{ content: "Hello", role: "user" }, // missing id and parts
|
||||
{ id: "123", role: "user" }, // missing content and parts
|
||||
];
|
||||
|
||||
for (const obj of invalidObjects) {
|
||||
expect(MessageConverter.isUIMessage(obj)).toBe(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/experimental
|
||||
|
||||
## 0.0.185
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.8
|
||||
|
||||
## 0.0.184
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3c857f4]
|
||||
- llamaindex@0.11.7
|
||||
|
||||
## 0.0.183
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.6
|
||||
|
||||
## 0.0.182
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/experimental",
|
||||
"description": "Experimental package for LlamaIndexTS",
|
||||
"version": "0.0.182",
|
||||
"version": "0.0.185",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# llamaindex
|
||||
|
||||
## 0.11.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [8a51c16]
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/workflow@1.1.9
|
||||
- @llamaindex/core@0.6.10
|
||||
- @llamaindex/cloud@4.0.14
|
||||
- @llamaindex/node-parser@2.0.10
|
||||
|
||||
## 0.11.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3c857f4: chore: move ajv to dev deps
|
||||
- Updated dependencies [dbd857f]
|
||||
- @llamaindex/workflow@1.1.8
|
||||
|
||||
## 0.11.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [40161fe]
|
||||
- @llamaindex/workflow@1.1.7
|
||||
|
||||
## 0.11.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "llamaindex",
|
||||
"version": "0.11.5",
|
||||
"version": "0.11.8",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
@@ -24,14 +24,14 @@
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"@llamaindex/node-parser": "workspace:*",
|
||||
"@llamaindex/workflow": "1.1.6",
|
||||
"@llamaindex/workflow": "workspace:*",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/node": "^22.9.0",
|
||||
"ajv": "^8.17.1",
|
||||
"lodash": "^4.17.21",
|
||||
"magic-bytes.js": "^1.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv": "^8.17.1",
|
||||
"@types/node": "^22.9.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @llamaindex/core-test
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/llamaindex-test",
|
||||
"private": true,
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "vitest run"
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/node-parser
|
||||
|
||||
## 2.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/node-parser",
|
||||
"version": "2.0.9",
|
||||
"version": "2.0.10",
|
||||
"description": "Node parser for LlamaIndex",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/anthropic
|
||||
|
||||
## 0.3.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.3.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/anthropic",
|
||||
"description": "Anthropic Adapter for LlamaIndex",
|
||||
"version": "0.3.11",
|
||||
"version": "0.3.12",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/assemblyai
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/assemblyai",
|
||||
"description": "AssemblyAI Reader for LlamaIndex",
|
||||
"version": "0.1.8",
|
||||
"version": "0.1.9",
|
||||
"type": "module",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.cjs",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/community
|
||||
|
||||
## 0.0.105
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.0.104
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/aws",
|
||||
"description": "AWS package for LlamaIndexTS",
|
||||
"version": "0.0.104",
|
||||
"version": "0.0.105",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @llamaindex/clip
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/clip",
|
||||
"description": "Clip Embedding Adapter for LlamaIndex",
|
||||
"version": "0.0.59",
|
||||
"version": "0.0.60",
|
||||
"type": "module",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.cjs",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/cohere
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/cohere",
|
||||
"description": "Cohere Adapter for LlamaIndex",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @llamaindex/deepinfra
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/deepinfra",
|
||||
"description": "Deepinfra Adapter for LlamaIndex",
|
||||
"version": "0.0.59",
|
||||
"version": "0.0.60",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @llamaindex/deepseek
|
||||
|
||||
## 0.0.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/deepseek",
|
||||
"description": "DeepSeek Adapter for LlamaIndex",
|
||||
"version": "0.0.19",
|
||||
"version": "0.0.20",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/discord
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/discord",
|
||||
"description": "Discord Reader for LlamaIndex",
|
||||
"version": "0.1.8",
|
||||
"version": "0.1.9",
|
||||
"type": "module",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.cjs",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @llamaindex/fireworks
|
||||
|
||||
## 0.0.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/fireworks",
|
||||
"description": "Fireworks Adapter for LlamaIndex",
|
||||
"version": "0.0.19",
|
||||
"version": "0.0.20",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @llamaindex/google
|
||||
|
||||
## 0.3.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.3.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 56763dc: Update to the latest Gemini 2.5 Pro Preview key
|
||||
|
||||
## 0.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2bc6914: fix: ignore empty parts for gemini which confuses agent
|
||||
|
||||
## 0.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/google",
|
||||
"description": "Google Adapter for LlamaIndex",
|
||||
"version": "0.3.6",
|
||||
"version": "0.3.9",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -25,6 +25,7 @@ import { streamConverter } from "@llamaindex/core/utils";
|
||||
|
||||
import { wrapLLMEvent } from "@llamaindex/core/decorator";
|
||||
import type { JSONObject } from "@llamaindex/core/global";
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import { DEFAULT_GEMINI_PARAMS, SUPPORT_TOOL_CALL_MODELS } from "../base";
|
||||
import type { GEMINI_MODEL } from "../types";
|
||||
import {
|
||||
@@ -117,7 +118,7 @@ export class GoogleStudio extends ToolCallLLM<GoogleAdditionalChatOptions> {
|
||||
getToolCallsFromResponse(response: GenerateContentResponse): ToolCall[] {
|
||||
if (!response.functionCalls) return [];
|
||||
return response.functionCalls.map((call) => ({
|
||||
id: call.id ?? "",
|
||||
id: call.id ?? randomUUID(),
|
||||
name: call.name ?? "",
|
||||
input: call.args as JSONObject,
|
||||
}));
|
||||
@@ -170,6 +171,35 @@ export class GoogleStudio extends ToolCallLLM<GoogleAdditionalChatOptions> {
|
||||
};
|
||||
}
|
||||
|
||||
async *reduceStream(
|
||||
stream: AsyncGenerator<GenerateContentResponse>,
|
||||
): AsyncIterable<ChatResponseChunk> {
|
||||
for await (const response of stream) {
|
||||
if (response.functionCalls?.length) {
|
||||
const toolCalls = this.getToolCallsFromResponse(response) as ToolCall[];
|
||||
yield {
|
||||
delta: "",
|
||||
raw: response,
|
||||
options: { toolCall: toolCalls },
|
||||
} as ChatResponseChunk;
|
||||
}
|
||||
|
||||
const text = response.candidates
|
||||
?.flatMap((candidate) => candidate.content?.parts)
|
||||
.map((part) => part?.text ?? "")
|
||||
.filter((text) => text)
|
||||
.join("");
|
||||
if (!text) continue;
|
||||
yield {
|
||||
delta: text,
|
||||
raw: response,
|
||||
options: {
|
||||
inlineData: getGoogleStudioInlineData(response),
|
||||
},
|
||||
} as ChatResponseChunk;
|
||||
}
|
||||
}
|
||||
|
||||
protected async *streamChat(
|
||||
params: GoogleChatParamsStreaming,
|
||||
): GoogleChatStreamResponse {
|
||||
@@ -190,25 +220,7 @@ export class GoogleStudio extends ToolCallLLM<GoogleAdditionalChatOptions> {
|
||||
contents: mapChatMessagesToGoogleMessages(params.messages),
|
||||
config,
|
||||
});
|
||||
yield* streamConverter(response, (response) => {
|
||||
if (response.functionCalls?.length) {
|
||||
return {
|
||||
delta: "",
|
||||
raw: response,
|
||||
options: {
|
||||
toolCall: this.getToolCallsFromResponse(response),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
delta: response.text ?? "",
|
||||
raw: response,
|
||||
options: {
|
||||
inlineData: getGoogleStudioInlineData(response),
|
||||
},
|
||||
};
|
||||
});
|
||||
yield* this.reduceStream(response);
|
||||
}
|
||||
|
||||
chat(params: GoogleChatParamsStreaming): Promise<GoogleChatStreamResponse>;
|
||||
|
||||
@@ -75,7 +75,7 @@ export enum GEMINI_MODEL {
|
||||
GEMINI_2_0_PRO_EXPERIMENTAL = "gemini-2.0-pro-exp-02-05",
|
||||
GEMINI_2_0_FLASH_LIVE = "gemini-2.0-flash-live-001",
|
||||
GEMINI_2_5_PRO_PREVIEW = "gemini-2.5-pro-preview-03-25",
|
||||
GEMINI_2_5_PRO_PREVIEW_LATEST = "gemini-2.5-pro-preview-05-06",
|
||||
GEMINI_2_5_PRO_PREVIEW_LATEST = "gemini-2.5-pro-preview-06-05",
|
||||
GEMINI_2_5_FLASH_PREVIEW = "gemini-2.5-flash-preview-05-20",
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @llamaindex/groq
|
||||
|
||||
## 0.0.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/groq",
|
||||
"description": "Groq Adapter for LlamaIndex",
|
||||
"version": "0.0.74",
|
||||
"version": "0.0.75",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @llamaindex/huggingface
|
||||
|
||||
## 0.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/huggingface",
|
||||
"description": "Huggingface Adapter for LlamaIndex",
|
||||
"version": "0.1.13",
|
||||
"version": "0.1.14",
|
||||
"type": "module",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.cjs",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @llamaindex/jinaai
|
||||
|
||||
## 0.0.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/jinaai",
|
||||
"description": "JinaAI Adapter for LlamaIndex",
|
||||
"version": "0.0.19",
|
||||
"version": "0.0.20",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/mistral
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/mistral",
|
||||
"description": "Mistral Adapter for LlamaIndex",
|
||||
"version": "0.1.9",
|
||||
"version": "0.1.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/mixedbread
|
||||
|
||||
## 0.0.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.0.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/mixedbread",
|
||||
"description": "Mixedbread Adapter for LlamaIndex",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/notion
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/notion",
|
||||
"description": "Notion Reader for LlamaIndex",
|
||||
"version": "0.1.8",
|
||||
"version": "0.1.9",
|
||||
"type": "module",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.cjs",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/ollama
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/ollama",
|
||||
"description": "Ollama Adapter for LlamaIndex",
|
||||
"version": "0.1.9",
|
||||
"version": "0.1.10",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/openai
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/openai",
|
||||
"description": "OpenAI Adapter for LlamaIndex",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @llamaindex/perplexity
|
||||
|
||||
## 0.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
- @llamaindex/openai@0.4.4
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/perplexity",
|
||||
"description": "Perplexity Adapter for LlamaIndex",
|
||||
"version": "0.0.16",
|
||||
"version": "0.0.17",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/portkey-ai
|
||||
|
||||
## 0.0.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.0.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/portkey-ai",
|
||||
"description": "Portkey Adapter for LlamaIndex",
|
||||
"version": "0.0.51",
|
||||
"version": "0.0.52",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @llamaindex/replicate
|
||||
|
||||
## 0.0.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [1b5af14]
|
||||
- @llamaindex/core@0.6.10
|
||||
|
||||
## 0.0.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/replicate",
|
||||
"description": "Replicate Adapter for LlamaIndex",
|
||||
"version": "0.0.51",
|
||||
"version": "0.0.52",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/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