mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-02 20:13:52 -04:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d68c2a4be8 | |||
| 47a7555c07 | |||
| 363bfa778e | |||
| 229cdeb0ff | |||
| 7a2485cca2 | |||
| 1329186a23 | |||
| 5d6e7384f5 | |||
| f2dfd305fb | |||
| 3cd8a573df | |||
| 09c6077f6e | |||
| 14cc65b4e3 | |||
| c544d8f67c | |||
| d578889e21 | |||
| 9f745d1941 | |||
| f292e94dcd | |||
| 0fcc92f632 | |||
| 515a8b9111 | |||
| 7e8efc6284 | |||
| 0fcf65126d |
+1
-1
@@ -25,7 +25,7 @@ Make sure you have Node.js LTS (Long-term Support) installed. You can check your
|
||||
|
||||
```shell
|
||||
node -v
|
||||
# v20.x.x
|
||||
# v22.x.x
|
||||
```
|
||||
|
||||
### Use pnpm
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# @llamaindex/doc
|
||||
|
||||
## 0.2.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [47a7555]
|
||||
- @llamaindex/cloud@4.0.18
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.2.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d578889]
|
||||
- Updated dependencies [0fcc92f]
|
||||
- Updated dependencies [515a8b9]
|
||||
- @llamaindex/core@0.6.13
|
||||
- llamaindex@0.11.12
|
||||
- @llamaindex/cloud@4.0.17
|
||||
- @llamaindex/node-parser@2.0.13
|
||||
- @llamaindex/openai@0.4.7
|
||||
- @llamaindex/readers@3.1.12
|
||||
- @llamaindex/workflow@1.1.13
|
||||
|
||||
## 0.2.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
This is a Next.js application generated with
|
||||
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).
|
||||
|
||||
> Note: Before running the development server, make sure to build the whole project first, see [CONTRIBUTING.md](../../CONTRIBUTING.md) for more details.
|
||||
|
||||
Run development server:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"utils": "@/libs/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"lib": "@/libs",
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/doc",
|
||||
"version": "0.2.31",
|
||||
"version": "0.2.33",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"postinstall": "fumadocs-mdx",
|
||||
@@ -15,7 +15,6 @@
|
||||
"dependencies": {
|
||||
"@huggingface/transformers": "^3.5.0",
|
||||
"@icons-pack/react-simple-icons": "^10.1.0",
|
||||
"@llamaindex/workflow-docs": "0.1.1",
|
||||
"@llamaindex/chat-ui-docs": "^0.0.5",
|
||||
"@llamaindex/cloud": "workspace:*",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
@@ -23,8 +22,10 @@
|
||||
"@llamaindex/openai": "workspace:*",
|
||||
"@llamaindex/readers": "workspace:*",
|
||||
"@llamaindex/workflow": "workspace:*",
|
||||
"@llamaindex/workflow-docs": "0.1.1",
|
||||
"@mdx-js/mdx": "^3.1.0",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@next/third-parties": "^15.3.4",
|
||||
"@number-flow/react": "^0.3.4",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
|
||||
@@ -10,7 +10,7 @@ import { MagicMove } from "@/components/magic-move";
|
||||
import { NpmInstall } from "@/components/npm-install";
|
||||
import { Supports } from "@/components/supports";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DOCUMENT_URL } from "@/lib/const";
|
||||
import { DOCUMENT_URL } from "@/libs/const";
|
||||
import { SiStackblitz } from "@icons-pack/react-simple-icons";
|
||||
import { Blocks, Bot, Footprints, Terminal } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { source } from "@/lib/source";
|
||||
import { source } from "@/libs/source";
|
||||
import { structure } from "fumadocs-core/mdx-plugins";
|
||||
import { createFromSource } from "fumadocs-core/search/server";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as demos from "@/components/demo/lazy";
|
||||
import { createMetadata, metadataImage } from "@/lib/metadata";
|
||||
import { openapi, source } from "@/lib/source";
|
||||
import { createMetadata, metadataImage } from "@/libs/metadata";
|
||||
import { openapi, source } from "@/libs/source";
|
||||
import * as Icons from "@icons-pack/react-simple-icons";
|
||||
import { APIPage } from "fumadocs-openapi/ui";
|
||||
import { Popup, PopupContent, PopupTrigger } from "fumadocs-twoslash/ui";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { baseOptions } from "@/app/layout.config";
|
||||
import { source } from "@/lib/source";
|
||||
import { source } from "@/libs/source";
|
||||
import "fumadocs-twoslash/twoslash.css";
|
||||
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DOCUMENT_URL } from "@/lib/const";
|
||||
import { DOCUMENT_URL } from "@/libs/const";
|
||||
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
||||
import Image from "next/image";
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AIProvider } from "@/actions";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { GoogleAnalytics } from "@next/third-parties/google";
|
||||
import { RootProvider } from "fumadocs-ui/provider";
|
||||
import { Inter } from "next/font/google";
|
||||
import type { ReactNode } from "react";
|
||||
@@ -39,6 +40,7 @@ export default function Layout({ children }: { children: ReactNode }) {
|
||||
</AIProvider>
|
||||
</TooltipProvider>
|
||||
</body>
|
||||
<GoogleAnalytics gaId="G-NB9B8LW9W5" />
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { generateOGImage } from "@/app/og/[...slug]/og";
|
||||
import { metadataImage } from "@/lib/metadata";
|
||||
import { metadataImage } from "@/libs/metadata";
|
||||
import { type ImageResponse } from "next/og";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ContributorCounter from "@/components/contributor-count";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import { Heart } from "lucide-react";
|
||||
import { ReactElement } from "react";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { fetchContributors } from "@/lib/get-contributors";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { fetchContributors } from "@/libs/get-contributors";
|
||||
import { cn } from "@/libs/utils";
|
||||
import Image from "next/image";
|
||||
import type { HTMLAttributes, ReactElement } from "react";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import { TerminalIcon } from "lucide-react";
|
||||
import {
|
||||
Fragment,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import { LucideIcon } from "lucide-react";
|
||||
import { HTMLAttributes, ReactElement, ReactNode } from "react";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import { CodeBlock } from "fumadocs-ui/components/codeblock";
|
||||
import { RotateCcw } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import Image from "next/image";
|
||||
import { ReactNode } from "react";
|
||||
import { IconAI, IconUser } from "./ui/icons";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import {
|
||||
AnimatePresence,
|
||||
motion,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const alertVariants = cva(
|
||||
"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { Cross2Icon } from "@radix-ui/react-icons";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const Dialog = DialogPrimitive.Root;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
export function IconAI({ className, ...props }: React.ComponentProps<"svg">) {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
import { animate, motion, useMotionValue } from "framer-motion";
|
||||
import { useEffect, useState } from "react";
|
||||
import useMeasure from "react-use-measure";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as LabelPrimitive from "@radix-ui/react-label";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const labelVariants = cva(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
function Skeleton({
|
||||
className,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import * as SliderPrimitive from "@radix-ui/react-slider";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const Slider = React.forwardRef<
|
||||
React.ElementRef<typeof SliderPrimitive.Root>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/libs/utils";
|
||||
|
||||
const TooltipProvider = TooltipPrimitive.Provider;
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
---
|
||||
title: Memory
|
||||
description: Manage conversation history and context with agents
|
||||
---
|
||||
|
||||
## Concept
|
||||
|
||||
Memory is a core component of agentic systems. It allows you to store and retrieve information from the past.
|
||||
|
||||
In LlamaIndexTS, you can create memory by using the `createMemory` function. This function will return a `Memory` object, which you can then use to store and retrieve information.
|
||||
|
||||
As the agent runs, it will make calls to `add()` to store information, and `get()` to retrieve information.
|
||||
|
||||
## Usage
|
||||
|
||||
A `Memory` object has both short-term memory (i.e. a FIFO queue of messages) and optionally long-term memory (i.e. extracting information over time).
|
||||
|
||||
`get()` always returns all messages stored in the memory. The longer the agent runs, this will exceed the context window of the agent. To avoid this, the agent is using the `getLLM` method to get the last X messages that fit into the context window.
|
||||
|
||||
### Configuring Memory for an Agent
|
||||
|
||||
Here we're creating a memory with a static block (read more about [memory blocks](#long-term-memory)) that contains some information about the user.
|
||||
|
||||
```ts twoslash
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { createMemory, staticBlock } from "llamaindex";
|
||||
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
|
||||
// Create memory with predefined context
|
||||
const memory = createMemory({
|
||||
memoryBlocks: [
|
||||
staticBlock({
|
||||
content:
|
||||
"The user is a software engineer who loves TypeScript and LlamaIndex.",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// Create an agent with the memory
|
||||
const workflow = agent({
|
||||
name: "assistant",
|
||||
llm,
|
||||
memory,
|
||||
});
|
||||
|
||||
const result = await workflow.run("What is my name?");
|
||||
console.log("Response:", result.data.result);
|
||||
```
|
||||
|
||||
### Using Vercel format
|
||||
|
||||
You can also put messages in Vercel format directly to the memory:
|
||||
|
||||
```ts
|
||||
await memory.add({
|
||||
id: "1",
|
||||
createdAt: new Date(),
|
||||
role: "user",
|
||||
content: "Hello!",
|
||||
options: {
|
||||
parts: [
|
||||
{
|
||||
type: "file",
|
||||
data: "base64...",
|
||||
mimeType: "image/png",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you call `get`, messages are usually retrieved in the LlamaIndexTS format (type `ChatMessage`). If you specify the `type` parameter using `get`, you can return the messages in different formats. E.g.: using `type: "vercel"`, you can return the messages in Vercel format:
|
||||
|
||||
```ts
|
||||
const messages = await memory.get({ type: "vercel" });
|
||||
console.log(messages);
|
||||
```
|
||||
|
||||
## Customizing Memory
|
||||
|
||||
### Short-Term Memory
|
||||
|
||||
The `Memory` object will store all the messages that are added to the `Memory` object. Unless you call `clear()`, no messages are removed from the memory. This is the short-term memory (usually you will store the memory of one user session there) which is augmented by the long-term memory.
|
||||
|
||||
Calling `getLLM` will retrieve messages from long-term memory and ensure that the given `tokenLimit` is not reached. These are the messages that you will sent to the LLM.
|
||||
|
||||
For initialization, you call `createMemory` with the following options:
|
||||
|
||||
- `tokenLimit`: Maximum tokens for memory retrieval using `getLLM` (default: 30000).
|
||||
- `shortTermTokenLimitRatio`: Ratio of tokens for short-term vs long-term memory (default: 0.7)
|
||||
- `customAdapters`: Custom message adapters for different message formats. LlamaIndex (`ChatMessageAdapter`) and Vercel (`VercelMessageAdapter`) are built-in adapters.
|
||||
- `memoryBlocks`: Memory blocks for long-term storage, see [Long-Term Memory](#long-term-memory)
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
const memory = createMemory({
|
||||
tokenLimit=40000,
|
||||
shortTermTokenLimitRatio=0.5,
|
||||
});
|
||||
```
|
||||
|
||||
### Long-Term Memory
|
||||
|
||||
Long-term memory is represented as `Memory Block` objects. These objects contain information that are from previous user sessions or from the beginning of the current conversation. When memory is retrieved (by calling `getLLM`), the short-term and long-term memories are merged together within the given `tokenLimit`.
|
||||
|
||||
Currently, there are two predefined memory blocks:
|
||||
|
||||
- `staticBlock`: A memory block that stores a static piece of information.
|
||||
- `factExtractionBlock`: A memory block that extracts facts from the chat history.
|
||||
|
||||
This sounds a bit complicated, but it's actually quite simple. Let's look at an example:
|
||||
|
||||
```ts
|
||||
import { createMemory, factExtractionBlock, staticBlock } from "llamaindex";
|
||||
|
||||
const memoryBlocks= [
|
||||
staticBlock({
|
||||
id: "core_info",
|
||||
content: "My name is Logan, and I live in Saskatoon. I work at LlamaIndex.",
|
||||
}),
|
||||
factExtractionBlock({
|
||||
id: "user-extracted_info",
|
||||
priority: 1,
|
||||
llm: llm,
|
||||
maxFacts: 50,
|
||||
}),
|
||||
];
|
||||
```
|
||||
|
||||
Here, we've setup two memory blocks:
|
||||
|
||||
- `core_info`: A static memory block that stores some core information about the user. This information will always be inserted into the memory. The type used is `MessageContent` to support multi-modal content.
|
||||
- `extracted_info`: An extracted memory block that will extract information from the chat history. Here we've passed in the `llm` to use to extract facts from the chat history, and set the `maxFacts` to 50. If the number of extracted facts exceeds this limit, the `maxFacts` will be automatically summarized and reduced to leave room for new information.
|
||||
|
||||
You'll also notice that we've set the `priority` for the `factExtractionBlock` block. This is used to determine the handling when the memory blocks content (i.e. long-term memory) + short-term memory exceeds the token limit on the `Memory` object.
|
||||
|
||||
- `priority=0`: This block will always be kept in memory (`staticBlocks` always have priority 0.)
|
||||
- `priority=1, 2, 3, etc`: This determines the order in which memory blocks are truncated when the memory exceeds the token limit, to help the overall short-term memory + long-term memory content be less than or equal to the `tokenLimit`.
|
||||
|
||||
Now, let's pass these blocks into the `createMemory` function:
|
||||
|
||||
```ts
|
||||
const memory = createMemory({
|
||||
tokenLimit: 40000,
|
||||
memoryBlocks: memoryBlocks,
|
||||
)
|
||||
```
|
||||
|
||||
When memory is retrieved (using `getLLM`), the short-term and long-term memories are merged together. The `Memory` object will ensure that the short-term memory + long-term memory content is less than or equal to the `tokenLimit`. If it is longer, messages are retrieved in the following order:
|
||||
|
||||
1. StaticMemoryBlock (information always included)
|
||||
2. LongTermMemoryBlock (depending on priority)
|
||||
3. ShortTermMemoryBlock
|
||||
4. Transient messages
|
||||
|
||||
The amount of short-term memory included is specified by the `shortTermTokenLimitRatio`. If it's set to `0.7`, 70% of the `tokenLimit` is used for short-term memory (not including the static memory block).
|
||||
|
||||
## Persistence with Snapshots
|
||||
|
||||
Save and restore memory state:
|
||||
|
||||
```ts twoslash
|
||||
import { createMemory, loadMemory } from "llamaindex";
|
||||
|
||||
const memory = createMemory();
|
||||
|
||||
// Add some messages
|
||||
await memory.add({ role: "user", content: "Hello!" });
|
||||
|
||||
// Create snapshot
|
||||
const snapshot = memory.snapshot();
|
||||
|
||||
// Later, restore from the snapshot
|
||||
const restoredMemory = loadMemory(snapshot);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Want to learn more about the Memory class? Check out our example codes in [Github](https://github.com/run-llama/LlamaIndexTS/tree/main/examples/agents/memory).
|
||||
@@ -1,4 +1,11 @@
|
||||
{
|
||||
"title": "Data",
|
||||
"pages": ["index", "readers", "data_index", "ingestion_pipeline", "stores"]
|
||||
"pages": [
|
||||
"index",
|
||||
"memory",
|
||||
"readers",
|
||||
"data_index",
|
||||
"ingestion_pipeline",
|
||||
"stores"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ A retriever in LlamaIndex is what is used to fetch `Node`s from an index using a
|
||||
- [KeywordTableLLMRetriever](/docs/api/classes/KeywordTableLLMRetriever) uses an LLM to extract keywords from the query and retrieve relevant nodes based on keyword matches.
|
||||
- [KeywordTableSimpleRetriever](/docs/api/classes/KeywordTableSimpleRetriever) uses a basic frequency-based approach to extract keywords and retrieve nodes.
|
||||
- [KeywordTableRAKERetriever](/docs/api/classes/KeywordTableRAKERetriever) uses the RAKE (Rapid Automatic Keyword Extraction) algorithm to extract keywords from the query, focusing on co-occurrence and context for keyword-based retrieval.
|
||||
- [Bm25Retriever](/docs/api/classes/Bm25Retriever) uses the BM25 algorithm to extract keywords from the query and retrieve relevant nodes based on keyword matches.
|
||||
|
||||
```typescript
|
||||
const retriever = vectorIndex.asRetriever({
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { createMetadataImage } from 'fumadocs-core/server';
|
||||
import { source } from '@/lib/source';
|
||||
import { Metadata } from 'next';
|
||||
|
||||
export const metadataImage = createMetadataImage({
|
||||
source,
|
||||
imageRoute: 'og',
|
||||
});
|
||||
|
||||
export function createMetadata(override: Metadata): Metadata {
|
||||
return {
|
||||
...override,
|
||||
openGraph: {
|
||||
title: override.title ?? undefined,
|
||||
description: override.description ?? undefined,
|
||||
url: 'https://ts.llamaindex.ai/',
|
||||
images: '/og.png',
|
||||
siteName: 'LlamaIndex.TS',
|
||||
...override.openGraph,
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
creator: '@llama_index',
|
||||
title: override.title ?? undefined,
|
||||
description: override.description ?? undefined,
|
||||
images: '/og.png',
|
||||
...override.twitter,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
// when we are ready, change to /docs/llamaindex
|
||||
export const DOCUMENT_URL = '/docs/llamaindex'
|
||||
export const DOCUMENT_URL = "/docs/llamaindex";
|
||||
@@ -10,7 +10,7 @@ export async function fetchContributors(
|
||||
): Promise<Contributor[]> {
|
||||
const headers = new Headers();
|
||||
if (process.env.GITHUB_TOKEN)
|
||||
headers.set('Authorization', `Bearer ${process.env.GITHUB_TOKEN}`);
|
||||
headers.set("Authorization", `Bearer ${process.env.GITHUB_TOKEN}`);
|
||||
|
||||
const response = await fetch(
|
||||
`https://api.github.com/repos/${repoOwner}/${repoName}/contributors?per_page=50`,
|
||||
@@ -26,6 +26,6 @@ export async function fetchContributors(
|
||||
|
||||
const contributors = (await response.json()) as Contributor[];
|
||||
return contributors
|
||||
.filter((contributor) => !contributor.login.endsWith('[bot]'))
|
||||
.filter((contributor) => !contributor.login.endsWith("[bot]"))
|
||||
.sort((a, b) => b.contributions - a.contributions);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { source } from "@/libs/source";
|
||||
import { createMetadataImage } from "fumadocs-core/server";
|
||||
import { Metadata } from "next";
|
||||
|
||||
export const metadataImage = createMetadataImage({
|
||||
source,
|
||||
imageRoute: "og",
|
||||
});
|
||||
|
||||
export function createMetadata(override: Metadata): Metadata {
|
||||
return {
|
||||
...override,
|
||||
openGraph: {
|
||||
title: override.title ?? undefined,
|
||||
description: override.description ?? undefined,
|
||||
url: "https://ts.llamaindex.ai/",
|
||||
images: "/og.png",
|
||||
siteName: "LlamaIndex.TS",
|
||||
...override.openGraph,
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
creator: "@llama_index",
|
||||
title: override.title ?? undefined,
|
||||
description: override.description ?? undefined,
|
||||
images: "/og.png",
|
||||
...override.twitter,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import { docs } from '@/.source';
|
||||
import { loader } from 'fumadocs-core/source';
|
||||
import { docs } from "@/.source";
|
||||
import { loader } from "fumadocs-core/source";
|
||||
import { createOpenAPI } from "fumadocs-openapi/server";
|
||||
|
||||
export const source = loader({
|
||||
baseUrl: '/docs',
|
||||
baseUrl: "/docs",
|
||||
source: docs.toFumadocsSource(),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
@@ -1,5 +1,18 @@
|
||||
# @llamaindex/cloudflare-worker-agent-test
|
||||
|
||||
## 0.0.174
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.0.173
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
|
||||
## 0.0.172
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloudflare-worker-agent-test",
|
||||
"version": "0.0.172",
|
||||
"version": "0.0.174",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @llamaindex/llama-parse-browser-test
|
||||
|
||||
## 0.0.73
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [47a7555]
|
||||
- @llamaindex/cloud@4.0.18
|
||||
|
||||
## 0.0.72
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @llamaindex/cloud@4.0.17
|
||||
|
||||
## 0.0.71
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/llama-parse-browser-test",
|
||||
"private": true,
|
||||
"version": "0.0.71",
|
||||
"version": "0.0.73",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @llamaindex/next-agent-test
|
||||
|
||||
## 0.1.174
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.1.173
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
|
||||
## 0.1.172
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-agent-test",
|
||||
"version": "0.1.172",
|
||||
"version": "0.1.174",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# test-edge-runtime
|
||||
|
||||
## 0.1.173
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.1.172
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
|
||||
## 0.1.171
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/nextjs-edge-runtime-test",
|
||||
"version": "0.1.171",
|
||||
"version": "0.1.173",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/next-node-runtime
|
||||
|
||||
## 0.1.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.1.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
- @llamaindex/huggingface@0.1.17
|
||||
- @llamaindex/readers@3.1.12
|
||||
|
||||
## 0.1.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-node-runtime-test",
|
||||
"version": "0.1.40",
|
||||
"version": "0.1.42",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# vite-import-llamaindex
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
|
||||
## 0.0.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vite-import-llamaindex",
|
||||
"private": true,
|
||||
"version": "0.0.38",
|
||||
"version": "0.0.40",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
|
||||
@@ -1,9 +1 @@
|
||||
{
|
||||
"root": [
|
||||
"./src/main.ts",
|
||||
"./vite.config.ts",
|
||||
"./tsconfig.json"
|
||||
],
|
||||
"errors": true,
|
||||
"version": "5.7.3"
|
||||
}
|
||||
{"root":["./src/main.ts","./vite.config.ts"],"version":"5.7.3"}
|
||||
@@ -1,5 +1,18 @@
|
||||
# @llamaindex/waku-query-engine-test
|
||||
|
||||
## 0.0.174
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.0.173
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
|
||||
## 0.0.172
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/waku-query-engine-test",
|
||||
"version": "0.0.172",
|
||||
"version": "0.0.174",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -10,7 +10,7 @@ import { mockLLMEvent } from "./utils.js";
|
||||
let llm: LLM;
|
||||
beforeEach(async () => {
|
||||
Settings.llm = new Anthropic({
|
||||
model: "claude-3-opus",
|
||||
model: "claude-3.5-sonnet",
|
||||
});
|
||||
llm = Settings.llm;
|
||||
});
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# examples
|
||||
|
||||
## 0.3.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [229cdeb]
|
||||
- Updated dependencies [47a7555]
|
||||
- @llamaindex/groq@0.0.79
|
||||
- @llamaindex/cloud@4.0.18
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 0.3.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d578889]
|
||||
- Updated dependencies [0fcc92f]
|
||||
- Updated dependencies [515a8b9]
|
||||
- Updated dependencies [3cd8a57]
|
||||
- Updated dependencies [f2dfd30]
|
||||
- @llamaindex/core@0.6.13
|
||||
- llamaindex@0.11.12
|
||||
- @llamaindex/tools@0.1.3
|
||||
- @llamaindex/bm25-retriever@0.0.2
|
||||
- @llamaindex/cloud@4.0.17
|
||||
- @llamaindex/node-parser@2.0.13
|
||||
- @llamaindex/anthropic@0.3.15
|
||||
- @llamaindex/assemblyai@0.1.12
|
||||
- @llamaindex/clip@0.0.63
|
||||
- @llamaindex/cohere@0.0.27
|
||||
- @llamaindex/deepinfra@0.0.63
|
||||
- @llamaindex/discord@0.1.12
|
||||
- @llamaindex/google@0.3.12
|
||||
- @llamaindex/huggingface@0.1.17
|
||||
- @llamaindex/jinaai@0.0.23
|
||||
- @llamaindex/mistral@0.1.13
|
||||
- @llamaindex/mixedbread@0.0.27
|
||||
- @llamaindex/notion@0.1.12
|
||||
- @llamaindex/ollama@0.1.13
|
||||
- @llamaindex/openai@0.4.7
|
||||
- @llamaindex/perplexity@0.0.20
|
||||
- @llamaindex/portkey-ai@0.0.55
|
||||
- @llamaindex/replicate@0.0.55
|
||||
- @llamaindex/astra@0.0.27
|
||||
- @llamaindex/azure@0.1.24
|
||||
- @llamaindex/chroma@0.0.27
|
||||
- @llamaindex/elastic-search@0.1.13
|
||||
- @llamaindex/firestore@1.0.20
|
||||
- @llamaindex/milvus@0.1.22
|
||||
- @llamaindex/mongodb@0.0.28
|
||||
- @llamaindex/pinecone@0.1.13
|
||||
- @llamaindex/postgres@0.0.56
|
||||
- @llamaindex/qdrant@0.1.23
|
||||
- @llamaindex/supabase@0.1.13
|
||||
- @llamaindex/upstash@0.0.27
|
||||
- @llamaindex/weaviate@0.0.28
|
||||
- @llamaindex/vercel@0.1.13
|
||||
- @llamaindex/voyage-ai@1.0.19
|
||||
- @llamaindex/readers@3.1.12
|
||||
- @llamaindex/workflow@1.1.13
|
||||
- @llamaindex/deepseek@0.0.23
|
||||
- @llamaindex/fireworks@0.0.23
|
||||
- @llamaindex/groq@0.0.78
|
||||
- @llamaindex/together@0.0.23
|
||||
- @llamaindex/vllm@0.0.49
|
||||
- @llamaindex/xai@0.0.10
|
||||
|
||||
## 0.3.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { createMemory, staticBlock } from "llamaindex";
|
||||
|
||||
// Simple example: Agent with Predefined Memory
|
||||
async function simpleAgentMemoryExample() {
|
||||
console.log("=== Simple Agent Memory Example ===");
|
||||
|
||||
const memory = createMemory({
|
||||
memoryBlocks: [
|
||||
staticBlock({
|
||||
content:
|
||||
"The user is a software engineer who loves TypeScript and LlamaIndex.",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// Create agent workflow
|
||||
const workflow = agent({
|
||||
name: "assistant",
|
||||
llm: openai({ model: "gpt-4.1-nano" }),
|
||||
memory,
|
||||
});
|
||||
|
||||
// Test - agent should remember John and the shopping cart context
|
||||
console.log("\n--- Testing Memory Context ---");
|
||||
const result = await workflow.run("Hi, my name is John. Do you know me?");
|
||||
|
||||
console.log("Assistant Response:", result.data.result);
|
||||
|
||||
const result2 = await workflow.run("What is my name?");
|
||||
console.log("Assistant Response:", result2.data.result);
|
||||
}
|
||||
|
||||
// Run the example
|
||||
simpleAgentMemoryExample().catch(console.error);
|
||||
@@ -0,0 +1,58 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { createMemory } from "llamaindex";
|
||||
|
||||
// Example: Basic Memory Usage with Factory
|
||||
async function basicMemoryExample() {
|
||||
console.log("\n=== Example: Basic Memory Usage with Factory ===");
|
||||
|
||||
const memory = createMemory({ tokenLimit: 30 });
|
||||
|
||||
// Add messages to memory
|
||||
await memory.add({
|
||||
role: "user",
|
||||
content: "Hi, my name is John and I'm a software engineer.",
|
||||
});
|
||||
|
||||
await memory.add({
|
||||
role: "assistant",
|
||||
content: "Hello John! Nice to meet you. How can I help you today?",
|
||||
});
|
||||
|
||||
await memory.add({
|
||||
role: "user",
|
||||
content: "I love working with TypeScript and React.",
|
||||
});
|
||||
// Not all messages are included because of token limit is set to 30
|
||||
const llmMessages = await memory.getLLM();
|
||||
console.log(
|
||||
`\nLLM messages (${llmMessages.length} messages) limited by a small token limit:`,
|
||||
);
|
||||
llmMessages.forEach((msg, idx) => {
|
||||
console.log(`${idx + 1}. ${msg.role}: ${msg.content}`);
|
||||
});
|
||||
|
||||
// But the token limit above will be the window size of an LLM instance if you use getLLM with LLM
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
const llmMessagesWithLLM = await memory.getLLM(llm);
|
||||
// Now all the messages are included because of the LLM window size of the model is much larger
|
||||
console.log(
|
||||
`\nLLM messages with LLM (${llmMessagesWithLLM.length} messages) limited by LLM window size:`,
|
||||
);
|
||||
llmMessagesWithLLM.forEach((msg, idx) => {
|
||||
console.log(`${idx + 1}. ${msg.role}: ${msg.content}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Main function
|
||||
async function main() {
|
||||
console.log("🧠 Basic Memory Factory Examples");
|
||||
console.log("===============================");
|
||||
|
||||
try {
|
||||
await basicMemoryExample();
|
||||
} catch (error) {
|
||||
console.error("Error running basic memory examples:", error);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,101 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { createMemory, factExtractionBlock } from "llamaindex";
|
||||
|
||||
// Configure OpenAI
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
|
||||
// Example: Memory with Fact Extraction
|
||||
async function factExtractionMemoryExample() {
|
||||
console.log("\n=== Memory with Fact Extraction ===");
|
||||
|
||||
// Create memory with a fact extraction
|
||||
const memory = createMemory([], {
|
||||
tokenLimit: 100,
|
||||
shortTermTokenLimitRatio: 0.7, // 70% for short-term, 30% for long-term
|
||||
memoryBlocks: [
|
||||
factExtractionBlock({
|
||||
id: "user-facts",
|
||||
priority: 5,
|
||||
llm: llm,
|
||||
maxFacts: 10,
|
||||
isLongTerm: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// Simulate a conversation with facts
|
||||
const conversationTurns = [
|
||||
{
|
||||
role: "user",
|
||||
content: "Hi, I'm Sarah and I work as a data scientist at Google.",
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content:
|
||||
"Hello Sarah! It's great to meet you. Data science at Google must be exciting!",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content:
|
||||
"Yes, I specialize in machine learning and natural language processing.",
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content: "That's impressive! ML and NLP are fascinating fields.",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content:
|
||||
"I have a PhD in Computer Science from Stanford, and I love hiking on weekends.",
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content:
|
||||
"Wow, Stanford PhD! And hiking is a great way to unwind from tech work.",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: "I also have two cats named Whiskers and Mittens.",
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content:
|
||||
"Cats make wonderful companions! Whiskers and Mittens are cute names.",
|
||||
},
|
||||
];
|
||||
|
||||
// Add conversation turns to memory
|
||||
console.log("Adding conversation to memory...");
|
||||
for (const turn of conversationTurns) {
|
||||
await memory.add(turn);
|
||||
}
|
||||
|
||||
// Get messages - facts should be extracted and included
|
||||
const messages = await memory.getLLM(llm);
|
||||
console.log("\nMessages with extracted facts:");
|
||||
messages.forEach((msg, idx) => {
|
||||
console.log(`${idx + 1}. ${msg.role ?? "unknown"}: ${msg.content}`);
|
||||
});
|
||||
//Messages with extracted facts:
|
||||
// 1. assistant: Cats make wonderful companions! Whiskers and Mittens are cute names.
|
||||
// 2. user: I also have two cats named Whiskers and Mittens.
|
||||
// 3. assistant: Wow, Stanford PhD! And hiking is a great way to unwind from tech work.
|
||||
// 4. memory: Sarah works as a data scientist at Google
|
||||
// Sarah specializes in machine learning and natural language processing
|
||||
// Sarah has a PhD in Computer Science from Stanford
|
||||
// Sarah enjoys hiking on weekends
|
||||
}
|
||||
|
||||
// Main function
|
||||
async function main() {
|
||||
console.log("🧠 Fact Extraction Memory Example");
|
||||
console.log("=================================");
|
||||
|
||||
try {
|
||||
await factExtractionMemoryExample();
|
||||
} catch (error) {
|
||||
console.error("Error running fact extraction memory example:", error);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,62 @@
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { createMemory, staticBlock } from "llamaindex";
|
||||
|
||||
// Configure OpenAI
|
||||
const llm = openai({ model: "gpt-4.1-mini" });
|
||||
|
||||
// Example: Memory with Static Blocks
|
||||
async function staticMemoryBlockExample() {
|
||||
console.log("\n=== Memory with Static Blocks ===");
|
||||
console.log("- Memory always include static block");
|
||||
console.log("- Memory cut off the messages within token limit\n");
|
||||
|
||||
// Create memory with a static block
|
||||
const memory = createMemory([], {
|
||||
tokenLimit: 30, // A small token limit which is not enough for the whole conversation below
|
||||
memoryBlocks: [
|
||||
staticBlock({
|
||||
content:
|
||||
"The user's name is John and he is a software engineer who loves TypeScript and LlamaIndex.",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// Add some messages to the memory
|
||||
await memory.add({
|
||||
role: "user",
|
||||
content: "What do you know about me?",
|
||||
});
|
||||
|
||||
await memory.add({
|
||||
role: "assistant",
|
||||
content:
|
||||
"Based on our conversation, I know you're John, a software engineer who enjoys working with TypeScript and LlamaIndex!",
|
||||
});
|
||||
|
||||
await memory.add({
|
||||
role: "user",
|
||||
content: "Which language does LlamaIndex support?",
|
||||
});
|
||||
|
||||
// Get messages
|
||||
// static block will always be included
|
||||
// only the last message will be included because of token limit set above
|
||||
const messages = await memory.getLLM(llm);
|
||||
messages.forEach((msg, idx) => {
|
||||
console.log(`${idx + 1}. ${msg.role}: ${msg.content}`);
|
||||
});
|
||||
// Messages with static block:
|
||||
// 1. user: The user's name is John and he is a software engineer who loves TypeScript and LlamaIndex.
|
||||
// 2. user: Which language does LlamaIndex support?
|
||||
}
|
||||
|
||||
// Main function
|
||||
async function main() {
|
||||
try {
|
||||
await staticMemoryBlockExample();
|
||||
} catch (error) {
|
||||
console.error("Error running static memory blocks example:", error);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -59,7 +59,7 @@ async function main() {
|
||||
|
||||
const anthropic = new Anthropic({
|
||||
apiKey: process.env.ANTHROPIC_API_KEY,
|
||||
model: "claude-3-opus",
|
||||
model: "claude-3.5-sonnet",
|
||||
});
|
||||
|
||||
// Create an ReActAgent with the function tools
|
||||
|
||||
@@ -61,7 +61,7 @@ async function main() {
|
||||
// Create an OpenAIAgent with the function tools
|
||||
const agent = new ReActAgent({
|
||||
llm: new Anthropic({
|
||||
model: "claude-3-opus",
|
||||
model: "claude-3.5-sonnet",
|
||||
}),
|
||||
tools: [functionTool, functionTool2],
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Anthropic } from "@llamaindex/anthropic";
|
||||
import { ChatMemoryBuffer, SimpleChatEngine } from "llamaindex";
|
||||
import { createMemory, SimpleChatEngine } from "llamaindex";
|
||||
import { stdin as input, stdout as output } from "node:process";
|
||||
import readline from "node:readline/promises";
|
||||
|
||||
@@ -9,14 +9,12 @@ import readline from "node:readline/promises";
|
||||
model: "claude-3-7-sonnet",
|
||||
});
|
||||
// chatHistory will store all the messages in the conversation
|
||||
const chatHistory = new ChatMemoryBuffer({
|
||||
chatHistory: [
|
||||
{
|
||||
content: "You want to talk in rhymes.",
|
||||
role: "system",
|
||||
},
|
||||
],
|
||||
});
|
||||
const chatHistory = createMemory([
|
||||
{
|
||||
content: "You want to talk in rhymes.",
|
||||
role: "system",
|
||||
},
|
||||
]);
|
||||
const chatEngine = new SimpleChatEngine({
|
||||
llm,
|
||||
memory: chatHistory,
|
||||
|
||||
+47
-46
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/examples",
|
||||
"version": "0.3.25",
|
||||
"version": "0.3.27",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
@@ -11,51 +11,52 @@
|
||||
"@azure/cosmos": "^4.1.1",
|
||||
"@azure/identity": "^4.4.1",
|
||||
"@azure/search-documents": "^12.1.0",
|
||||
"@llamaindex/anthropic": "^0.3.14",
|
||||
"@llamaindex/assemblyai": "^0.1.11",
|
||||
"@llamaindex/astra": "^0.0.26",
|
||||
"@llamaindex/azure": "^0.1.23",
|
||||
"@llamaindex/chroma": "^0.0.26",
|
||||
"@llamaindex/clip": "^0.0.62",
|
||||
"@llamaindex/cloud": "^4.0.16",
|
||||
"@llamaindex/cohere": "^0.0.26",
|
||||
"@llamaindex/core": "^0.6.12",
|
||||
"@llamaindex/deepinfra": "^0.0.62",
|
||||
"@llamaindex/deepseek": "^0.0.22",
|
||||
"@llamaindex/discord": "^0.1.11",
|
||||
"@llamaindex/elastic-search": "^0.1.12",
|
||||
"@llamaindex/anthropic": "^0.3.15",
|
||||
"@llamaindex/assemblyai": "^0.1.12",
|
||||
"@llamaindex/astra": "^0.0.27",
|
||||
"@llamaindex/azure": "^0.1.24",
|
||||
"@llamaindex/bm25-retriever": "^0.0.2",
|
||||
"@llamaindex/chroma": "^0.0.27",
|
||||
"@llamaindex/clip": "^0.0.63",
|
||||
"@llamaindex/cloud": "^4.0.18",
|
||||
"@llamaindex/cohere": "^0.0.27",
|
||||
"@llamaindex/core": "^0.6.13",
|
||||
"@llamaindex/deepinfra": "^0.0.63",
|
||||
"@llamaindex/deepseek": "^0.0.23",
|
||||
"@llamaindex/discord": "^0.1.12",
|
||||
"@llamaindex/elastic-search": "^0.1.13",
|
||||
"@llamaindex/env": "^0.1.30",
|
||||
"@llamaindex/firestore": "^1.0.19",
|
||||
"@llamaindex/fireworks": "^0.0.22",
|
||||
"@llamaindex/google": "^0.3.11",
|
||||
"@llamaindex/groq": "^0.0.77",
|
||||
"@llamaindex/huggingface": "^0.1.16",
|
||||
"@llamaindex/jinaai": "^0.0.22",
|
||||
"@llamaindex/milvus": "^0.1.21",
|
||||
"@llamaindex/mistral": "^0.1.12",
|
||||
"@llamaindex/mixedbread": "^0.0.26",
|
||||
"@llamaindex/mongodb": "^0.0.27",
|
||||
"@llamaindex/node-parser": "^2.0.12",
|
||||
"@llamaindex/notion": "^0.1.11",
|
||||
"@llamaindex/ollama": "^0.1.12",
|
||||
"@llamaindex/openai": "^0.4.6",
|
||||
"@llamaindex/perplexity": "^0.0.19",
|
||||
"@llamaindex/pinecone": "^0.1.12",
|
||||
"@llamaindex/portkey-ai": "^0.0.54",
|
||||
"@llamaindex/postgres": "^0.0.55",
|
||||
"@llamaindex/qdrant": "^0.1.22",
|
||||
"@llamaindex/readers": "^3.1.11",
|
||||
"@llamaindex/replicate": "^0.0.54",
|
||||
"@llamaindex/supabase": "^0.1.12",
|
||||
"@llamaindex/together": "^0.0.22",
|
||||
"@llamaindex/tools": "^0.1.1",
|
||||
"@llamaindex/upstash": "^0.0.26",
|
||||
"@llamaindex/vercel": "^0.1.12",
|
||||
"@llamaindex/vllm": "^0.0.48",
|
||||
"@llamaindex/voyage-ai": "^1.0.18",
|
||||
"@llamaindex/weaviate": "^0.0.27",
|
||||
"@llamaindex/workflow": "^1.1.12",
|
||||
"@llamaindex/xai": "workspace:^0.0.9",
|
||||
"@llamaindex/firestore": "^1.0.20",
|
||||
"@llamaindex/fireworks": "^0.0.23",
|
||||
"@llamaindex/google": "^0.3.12",
|
||||
"@llamaindex/groq": "^0.0.79",
|
||||
"@llamaindex/huggingface": "^0.1.17",
|
||||
"@llamaindex/jinaai": "^0.0.23",
|
||||
"@llamaindex/milvus": "^0.1.22",
|
||||
"@llamaindex/mistral": "^0.1.13",
|
||||
"@llamaindex/mixedbread": "^0.0.27",
|
||||
"@llamaindex/mongodb": "^0.0.28",
|
||||
"@llamaindex/node-parser": "^2.0.13",
|
||||
"@llamaindex/notion": "^0.1.12",
|
||||
"@llamaindex/ollama": "^0.1.13",
|
||||
"@llamaindex/openai": "^0.4.7",
|
||||
"@llamaindex/perplexity": "^0.0.20",
|
||||
"@llamaindex/pinecone": "^0.1.13",
|
||||
"@llamaindex/portkey-ai": "^0.0.55",
|
||||
"@llamaindex/postgres": "^0.0.56",
|
||||
"@llamaindex/qdrant": "^0.1.23",
|
||||
"@llamaindex/readers": "^3.1.12",
|
||||
"@llamaindex/replicate": "^0.0.55",
|
||||
"@llamaindex/supabase": "^0.1.13",
|
||||
"@llamaindex/together": "^0.0.23",
|
||||
"@llamaindex/tools": "^0.1.3",
|
||||
"@llamaindex/upstash": "^0.0.27",
|
||||
"@llamaindex/vercel": "^0.1.13",
|
||||
"@llamaindex/vllm": "^0.0.49",
|
||||
"@llamaindex/voyage-ai": "^1.0.19",
|
||||
"@llamaindex/weaviate": "^0.0.28",
|
||||
"@llamaindex/workflow": "^1.1.13",
|
||||
"@llamaindex/xai": "workspace:^0.0.10",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
"@pinecone-database/pinecone": "^4.0.0",
|
||||
"@vercel/postgres": "^0.10.0",
|
||||
@@ -64,7 +65,7 @@
|
||||
"commander": "^12.1.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"js-tiktoken": "^1.0.14",
|
||||
"llamaindex": "^0.11.11",
|
||||
"llamaindex": "^0.11.13",
|
||||
"mongodb": "6.7.0",
|
||||
"postgres": "^3.4.4",
|
||||
"wikipedia": "^2.1.2",
|
||||
|
||||
@@ -2,11 +2,7 @@ import { stdin as input, stdout as output } from "node:process";
|
||||
import readline from "node:readline/promises";
|
||||
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
ChatSummaryMemoryBuffer,
|
||||
Settings,
|
||||
SimpleChatEngine,
|
||||
} from "llamaindex";
|
||||
import { createMemory, Settings, SimpleChatEngine } from "llamaindex";
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
Settings.callbackManager.on("llm-end", (event) => {
|
||||
@@ -15,10 +11,13 @@ if (process.env.NODE_ENV === "development") {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// Set maxTokens to 75% of the context window size of 4096
|
||||
// This will trigger the summarizer once the chat history reaches 25% of the context window size (1024 tokens)
|
||||
const llm = new OpenAI({ model: "gpt-3.5-turbo", maxTokens: 4096 * 0.75 });
|
||||
const chatHistory = new ChatSummaryMemoryBuffer({ llm });
|
||||
const llm = new OpenAI({ model: "gpt-3.5-turbo" });
|
||||
const chatHistory = createMemory([
|
||||
{
|
||||
content: "You are a helpful assistant.",
|
||||
role: "system",
|
||||
},
|
||||
]);
|
||||
const chatEngine = new SimpleChatEngine({ llm });
|
||||
const rl = readline.createInterface({ input, output });
|
||||
|
||||
@@ -29,10 +28,6 @@ async function main() {
|
||||
chatHistory,
|
||||
stream: true,
|
||||
});
|
||||
if (chatHistory.getLastSummary()) {
|
||||
// Print the summary of the conversation so far that is produced by the SummaryChatHistory
|
||||
console.log(`Summary: ${chatHistory.getLastSummary()?.content}`);
|
||||
}
|
||||
for await (const chunk of stream) {
|
||||
process.stdout.write(chunk.response);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LlamaParseReader } from "@llamaindex/cloud";
|
||||
import { LlamaParseReader } from "@llamaindex/cloud/reader";
|
||||
import { openai, OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import { Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LlamaParseReader } from "@llamaindex/cloud";
|
||||
import { LlamaParseReader } from "@llamaindex/cloud/reader";
|
||||
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
|
||||
import { VectorStoreIndex } from "llamaindex";
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# BM25 Retriever
|
||||
|
||||
In this guide, we introduce a bm25 retriever that search documents using the bm25 method. BM25 (Best Matching 25) is a ranking function that extends TF-IDF by considering term frequency saturation and document length. BM25 effectively ranks documents based on query term occurrence and rarity across the corpus.
|
||||
|
||||
## Setup
|
||||
|
||||
1. `cd` Into the `examples` directory
|
||||
2. run `npm i`
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
`npx tsx ./retrievers/bm25/example.ts`
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Bm25Retriever } from "@llamaindex/bm25-retriever";
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import { PDFReader } from "@llamaindex/readers/pdf";
|
||||
import { MetadataMode, Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
Settings.embedModel = new OpenAIEmbedding();
|
||||
|
||||
async function main() {
|
||||
// Load PDF
|
||||
const reader = new PDFReader();
|
||||
const documents = await reader.loadData("./data/brk-2022.pdf");
|
||||
|
||||
// Split text and create embeddings. Store them in a VectorStoreIndex
|
||||
const index = await VectorStoreIndex.fromDocuments(documents);
|
||||
|
||||
const retriever = new Bm25Retriever({
|
||||
docStore: index.docStore,
|
||||
topK: 3,
|
||||
});
|
||||
|
||||
// Query the data
|
||||
const response = await retriever.retrieve({
|
||||
query: "What mistakes did Warren E. Buffett make?",
|
||||
});
|
||||
|
||||
// Output response
|
||||
response.forEach((r) => {
|
||||
console.log(`Score: ${r.score}`);
|
||||
console.log(`Text: ${r.node.getContent(MetadataMode.NONE)}`);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
Generated
+10114
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,18 @@
|
||||
# @llamaindex/autotool
|
||||
|
||||
## 8.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
|
||||
## 8.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
|
||||
## 8.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/autotool-01-node-example
|
||||
|
||||
## 0.0.121
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- llamaindex@0.11.13
|
||||
- @llamaindex/autotool@8.0.13
|
||||
|
||||
## 0.0.120
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [515a8b9]
|
||||
- llamaindex@0.11.12
|
||||
- @llamaindex/autotool@8.0.12
|
||||
|
||||
## 0.0.119
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
"scripts": {
|
||||
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
|
||||
},
|
||||
"version": "0.0.119"
|
||||
"version": "0.0.121"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"url": "git+https://github.com/run-llama/LlamaIndexTS.git",
|
||||
"directory": "packages/autotool"
|
||||
},
|
||||
"version": "8.0.11",
|
||||
"version": "8.0.13",
|
||||
"description": "auto transpile your JS function to LLM Agent compatible",
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/cloud
|
||||
|
||||
## 4.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 47a7555: chore: bump sdk version
|
||||
|
||||
## 4.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d578889]
|
||||
- Updated dependencies [0fcc92f]
|
||||
- Updated dependencies [515a8b9]
|
||||
- @llamaindex/core@0.6.13
|
||||
|
||||
## 4.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+2534
-114
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloud",
|
||||
"version": "4.0.16",
|
||||
"version": "4.0.18",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -171,6 +171,14 @@ export class LlamaParseReader extends FileReader {
|
||||
replace_failed_page_with_error_message_suffix?: string | undefined;
|
||||
save_images?: boolean | undefined;
|
||||
preset?: string | undefined;
|
||||
high_res_ocr?: boolean | undefined;
|
||||
outlined_table_extraction?: boolean | undefined;
|
||||
hide_headers?: boolean | undefined;
|
||||
hide_footers?: boolean | undefined;
|
||||
page_header_prefix?: string | undefined;
|
||||
page_header_suffix?: string | undefined;
|
||||
page_footer_prefix?: string | undefined;
|
||||
page_footer_suffix?: string | undefined;
|
||||
|
||||
constructor(
|
||||
params: Partial<Omit<LlamaParseReader, "language" | "apiKey">> & {
|
||||
@@ -352,6 +360,14 @@ export class LlamaParseReader extends FileReader {
|
||||
this.replace_failed_page_with_error_message_suffix,
|
||||
save_images: this.save_images,
|
||||
preset: this.preset,
|
||||
high_res_ocr: this.high_res_ocr,
|
||||
outlined_table_extraction: this.outlined_table_extraction,
|
||||
hide_headers: this.hide_headers,
|
||||
hide_footers: this.hide_footers,
|
||||
page_header_prefix: this.page_header_prefix,
|
||||
page_header_suffix: this.page_header_suffix,
|
||||
page_footer_prefix: this.page_footer_prefix,
|
||||
page_footer_suffix: this.page_footer_suffix,
|
||||
} satisfies {
|
||||
[Key in keyof BodyUploadFileApiParsingUploadPost]-?:
|
||||
| BodyUploadFileApiParsingUploadPost[Key]
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @llamaindex/core
|
||||
|
||||
## 0.6.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d578889: Add new memory API
|
||||
- 0fcc92f: Fix: split sentences must not trim whitespaces
|
||||
- 515a8b9: Fix: logging for fromPersistPath
|
||||
|
||||
## 0.6.12
|
||||
|
||||
### Patch Changes
|
||||
@@ -426,7 +434,6 @@
|
||||
### Patch Changes
|
||||
|
||||
- 8b7fdba: refactor: move chat engine & retriever into core.
|
||||
|
||||
- `chatHistory` in BaseChatEngine now returns `ChatMessage[] | Promise<ChatMessage[]>`, instead of `BaseMemory`
|
||||
- update `retrieve-end` type
|
||||
|
||||
@@ -452,7 +459,6 @@
|
||||
### Patch Changes
|
||||
|
||||
- 2cd1383: refactor: align `response-synthesizers` & `chat-engine` module
|
||||
|
||||
- builtin event system
|
||||
- correct class extends
|
||||
- aligin APIs, naming with llama-index python
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/core",
|
||||
"type": "module",
|
||||
"version": "0.6.12",
|
||||
"version": "0.6.13",
|
||||
"description": "LlamaIndex Core Module",
|
||||
"exports": {
|
||||
"./agent": {
|
||||
|
||||
@@ -152,6 +152,7 @@ export type AgentParamsBase<
|
||||
|
||||
/**
|
||||
* Worker will schedule tasks and handle the task execution
|
||||
* @deprecated Use agent instead.
|
||||
*/
|
||||
export abstract class AgentWorker<
|
||||
AI extends LLM,
|
||||
@@ -250,6 +251,7 @@ export abstract class AgentWorker<
|
||||
|
||||
/**
|
||||
* Runner will manage the task execution and provide a high-level API for the user
|
||||
* @deprecated Use agent instead.
|
||||
*/
|
||||
export abstract class AgentRunner<
|
||||
AI extends LLM,
|
||||
|
||||
@@ -62,6 +62,9 @@ export class LLMAgentWorker extends AgentWorker<LLM> {
|
||||
taskHandler = AgentRunner.defaultTaskHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use agent instead.
|
||||
*/
|
||||
export class LLMAgent extends AgentRunner<LLM> {
|
||||
constructor(params: LLMAgentParams<LLM>) {
|
||||
validateAgentParams(params);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ChatMessage, MessageContent } from "../llms";
|
||||
import type { BaseMemory } from "../memory";
|
||||
import type { Memory } from "../memory";
|
||||
import { EngineResponse } from "../schema";
|
||||
|
||||
export interface BaseChatEngineParams<
|
||||
@@ -9,9 +9,7 @@ export interface BaseChatEngineParams<
|
||||
/**
|
||||
* Optional chat history if you want to customize the chat history.
|
||||
*/
|
||||
chatHistory?:
|
||||
| ChatMessage<AdditionalMessageOptions>[]
|
||||
| BaseMemory<AdditionalMessageOptions>;
|
||||
chatHistory?: ChatMessage<AdditionalMessageOptions>[] | Memory;
|
||||
}
|
||||
|
||||
export interface StreamingChatEngineParams<
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { wrapEventCaller } from "../decorator";
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage, LLM, MessageContent, MessageType } from "../llms";
|
||||
import { BaseMemory, ChatMemoryBuffer } from "../memory";
|
||||
import { Memory, createMemory } from "../memory";
|
||||
import type { BaseNodePostprocessor } from "../postprocessor";
|
||||
import {
|
||||
type ContextSystemPrompt,
|
||||
@@ -23,7 +23,7 @@ import type { ContextGenerator } from "./type";
|
||||
export type ContextChatEngineOptions = {
|
||||
retriever: BaseRetriever;
|
||||
chatModel?: LLM | undefined;
|
||||
chatHistory?: ChatMessage[] | undefined;
|
||||
chatHistory?: ChatMessage[] | Memory | undefined;
|
||||
contextSystemPrompt?: ContextSystemPrompt | undefined;
|
||||
nodePostprocessors?: BaseNodePostprocessor[] | undefined;
|
||||
systemPrompt?: string | undefined;
|
||||
@@ -37,18 +37,21 @@ export type ContextChatEngineOptions = {
|
||||
*/
|
||||
export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
|
||||
chatModel: LLM;
|
||||
memory: BaseMemory;
|
||||
memory: Memory;
|
||||
contextGenerator: ContextGenerator & PromptMixin;
|
||||
systemPrompt?: string | undefined;
|
||||
|
||||
get chatHistory() {
|
||||
return this.memory.getMessages();
|
||||
return this.memory.getLLM();
|
||||
}
|
||||
|
||||
constructor(init: ContextChatEngineOptions) {
|
||||
super();
|
||||
this.chatModel = init.chatModel ?? Settings.llm;
|
||||
this.memory = new ChatMemoryBuffer({ chatHistory: init?.chatHistory });
|
||||
this.memory =
|
||||
init?.chatHistory instanceof Memory
|
||||
? init.chatHistory
|
||||
: createMemory(init?.chatHistory ?? []);
|
||||
this.contextGenerator = new DefaultContextGenerator({
|
||||
retriever: init.retriever,
|
||||
contextSystemPrompt: init?.contextSystemPrompt,
|
||||
@@ -87,12 +90,9 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
|
||||
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
|
||||
const { message, stream } = params;
|
||||
const chatHistory = params.chatHistory
|
||||
? new ChatMemoryBuffer({
|
||||
chatHistory:
|
||||
params.chatHistory instanceof BaseMemory
|
||||
? await params.chatHistory.getMessages()
|
||||
: params.chatHistory,
|
||||
})
|
||||
? params.chatHistory instanceof Memory
|
||||
? params.chatHistory
|
||||
: createMemory(params.chatHistory)
|
||||
: this.memory;
|
||||
const requestMessages = await this.prepareRequestMessages(
|
||||
message,
|
||||
@@ -110,7 +110,7 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
|
||||
initialValue: "",
|
||||
reducer: (accumulator, part) => (accumulator += part.delta),
|
||||
finished: (accumulator) => {
|
||||
chatHistory.put({ content: accumulator, role: "assistant" });
|
||||
void chatHistory.add({ content: accumulator, role: "assistant" });
|
||||
},
|
||||
}),
|
||||
(r) => EngineResponse.fromChatResponseChunk(r, requestMessages.nodes),
|
||||
@@ -120,26 +120,26 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
|
||||
messages: requestMessages.messages,
|
||||
additionalChatOptions: params.chatOptions as object,
|
||||
});
|
||||
chatHistory.put(response.message);
|
||||
await chatHistory.add(response.message);
|
||||
return EngineResponse.fromChatResponse(response, requestMessages.nodes);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.memory.reset();
|
||||
async reset() {
|
||||
await this.memory.clear();
|
||||
}
|
||||
|
||||
private async prepareRequestMessages(
|
||||
message: MessageContent,
|
||||
chatHistory: BaseMemory,
|
||||
chatHistory: Memory,
|
||||
) {
|
||||
chatHistory.put({
|
||||
await chatHistory.add({
|
||||
content: message,
|
||||
role: "user",
|
||||
});
|
||||
const textOnly = extractText(message);
|
||||
const context = await this.contextGenerator.generate(textOnly);
|
||||
const systemMessage = this.prependSystemPrompt(context.message);
|
||||
const messages = await chatHistory.getMessages([systemMessage]);
|
||||
const messages = await chatHistory.getLLM(this.chatModel, [systemMessage]);
|
||||
return { nodes: context.nodes, messages };
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { LLM } from "../llms";
|
||||
import { BaseMemory, ChatMemoryBuffer } from "../memory";
|
||||
import { createMemory, Memory } from "../memory";
|
||||
import { EngineResponse } from "../schema";
|
||||
import { streamConverter, streamReducer } from "../utils";
|
||||
import type {
|
||||
@@ -16,20 +16,16 @@ import { Settings } from "../global";
|
||||
*/
|
||||
|
||||
export class SimpleChatEngine implements BaseChatEngine {
|
||||
memory: BaseMemory;
|
||||
memory: Memory;
|
||||
llm: LLM;
|
||||
|
||||
get chatHistory() {
|
||||
return this.memory.getMessages();
|
||||
return this.memory.getLLM();
|
||||
}
|
||||
|
||||
constructor(init?: Partial<SimpleChatEngine>) {
|
||||
this.llm = init?.llm ?? Settings.llm;
|
||||
this.memory =
|
||||
init?.memory ??
|
||||
new ChatMemoryBuffer({
|
||||
llm: this.llm,
|
||||
});
|
||||
this.memory = init?.memory ?? createMemory();
|
||||
}
|
||||
|
||||
chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
|
||||
@@ -43,19 +39,15 @@ export class SimpleChatEngine implements BaseChatEngine {
|
||||
const { message, stream } = params;
|
||||
|
||||
const chatHistory = params.chatHistory
|
||||
? new ChatMemoryBuffer({
|
||||
llm: this.llm,
|
||||
chatHistory:
|
||||
params.chatHistory instanceof BaseMemory
|
||||
? await params.chatHistory.getMessages()
|
||||
: params.chatHistory,
|
||||
})
|
||||
? params.chatHistory instanceof Memory
|
||||
? params.chatHistory
|
||||
: createMemory(params.chatHistory)
|
||||
: this.memory;
|
||||
chatHistory.put({ content: message, role: "user" });
|
||||
await chatHistory.add({ content: message, role: "user" });
|
||||
|
||||
if (stream) {
|
||||
const stream = await this.llm.chat({
|
||||
messages: await chatHistory.getMessages(),
|
||||
messages: await chatHistory.getLLM(this.llm),
|
||||
stream: true,
|
||||
});
|
||||
return streamConverter(
|
||||
@@ -64,7 +56,7 @@ export class SimpleChatEngine implements BaseChatEngine {
|
||||
initialValue: "",
|
||||
reducer: (accumulator, part) => accumulator + part.delta,
|
||||
finished: (accumulator) => {
|
||||
chatHistory.put({ content: accumulator, role: "assistant" });
|
||||
void chatHistory.add({ content: accumulator, role: "assistant" });
|
||||
},
|
||||
}),
|
||||
EngineResponse.fromChatResponseChunk,
|
||||
@@ -73,13 +65,13 @@ export class SimpleChatEngine implements BaseChatEngine {
|
||||
|
||||
const response = await this.llm.chat({
|
||||
stream: false,
|
||||
messages: await chatHistory.getMessages(),
|
||||
messages: await chatHistory.getLLM(this.llm),
|
||||
});
|
||||
chatHistory.put(response.message);
|
||||
await chatHistory.add(response.message);
|
||||
return EngineResponse.fromChatResponse(response);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.memory.reset();
|
||||
async reset() {
|
||||
await this.memory.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { MemoryMessage } from "../types";
|
||||
|
||||
export interface MessageAdapter<T, TMessageOptions extends object = object> {
|
||||
fromMemory(message: MemoryMessage<TMessageOptions>): T;
|
||||
toMemory(message: T): MemoryMessage<TMessageOptions>;
|
||||
isCompatible(message: unknown): message is T;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import type { ChatMessage } from "../../llms";
|
||||
import type { MemoryMessage } from "../types";
|
||||
import { type MessageAdapter } from "./base";
|
||||
|
||||
export class ChatMessageAdapter<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> implements
|
||||
MessageAdapter<
|
||||
ChatMessage<AdditionalMessageOptions>,
|
||||
AdditionalMessageOptions
|
||||
>
|
||||
{
|
||||
fromMemory(
|
||||
message: MemoryMessage<AdditionalMessageOptions>,
|
||||
): ChatMessage<AdditionalMessageOptions> {
|
||||
return {
|
||||
content: message.content,
|
||||
role: message.role,
|
||||
options: message.options,
|
||||
};
|
||||
}
|
||||
toMemory(
|
||||
message: ChatMessage<AdditionalMessageOptions>,
|
||||
): MemoryMessage<AdditionalMessageOptions> {
|
||||
return {
|
||||
id: randomUUID(),
|
||||
createdAt: new Date(),
|
||||
...message,
|
||||
};
|
||||
}
|
||||
isCompatible(
|
||||
message: unknown,
|
||||
): message is ChatMessage<AdditionalMessageOptions> {
|
||||
return !!(
|
||||
message &&
|
||||
typeof message === "object" &&
|
||||
"role" in message &&
|
||||
message.role &&
|
||||
"content" in message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./base";
|
||||
export * from "./chat";
|
||||
export * from "./vercel";
|
||||
@@ -0,0 +1,198 @@
|
||||
import type {
|
||||
ChatMessage,
|
||||
MessageContent,
|
||||
MessageContentDetail,
|
||||
} from "../../llms";
|
||||
import { extractText } from "../../utils";
|
||||
import type { MemoryMessage } from "../types";
|
||||
import type { MessageAdapter } from "./base";
|
||||
|
||||
// UIMessage from the vercel/ai package (external)
|
||||
export type VercelMessage = {
|
||||
id: string;
|
||||
role: "system" | "user" | "assistant" | "data";
|
||||
content: string;
|
||||
createdAt?: Date | undefined;
|
||||
annotations?: Array<unknown> | undefined;
|
||||
parts: Array<{ type: string; [key: string]: unknown }>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility class for converting between LlamaIndex ChatMessage and Vercel UI Message formats
|
||||
*/
|
||||
export class VercelMessageAdapter<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> implements MessageAdapter<VercelMessage, AdditionalMessageOptions>
|
||||
{
|
||||
/**
|
||||
* Convert LlamaIndex ChatMessage to Vercel UI Message format
|
||||
*/
|
||||
fromMemory(memoryMessage: MemoryMessage<object>): VercelMessage {
|
||||
const parts = this.convertMessageContentToVercelParts(
|
||||
memoryMessage.content,
|
||||
);
|
||||
|
||||
// Convert role to UI message role
|
||||
let role: VercelMessage["role"];
|
||||
switch (memoryMessage.role) {
|
||||
case "system":
|
||||
case "user":
|
||||
case "assistant":
|
||||
role = memoryMessage.role;
|
||||
break;
|
||||
case "memory":
|
||||
role = "system";
|
||||
break;
|
||||
case "developer":
|
||||
role = "user";
|
||||
break;
|
||||
default:
|
||||
role = "user"; // Default fallback, should not happen
|
||||
}
|
||||
|
||||
return {
|
||||
id: memoryMessage.id,
|
||||
role,
|
||||
content: extractText(memoryMessage.content),
|
||||
parts,
|
||||
createdAt: memoryMessage.createdAt,
|
||||
annotations: memoryMessage.annotations,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert Vercel UI Message to LlamaIndex ChatMessage format
|
||||
*/
|
||||
toMemory(uiMessage: VercelMessage): MemoryMessage<AdditionalMessageOptions> {
|
||||
// Convert UI message role to MessageType
|
||||
let role: ChatMessage["role"];
|
||||
switch (uiMessage.role) {
|
||||
case "system":
|
||||
case "user":
|
||||
case "assistant":
|
||||
role = uiMessage.role;
|
||||
break;
|
||||
case "data":
|
||||
role = "user"; // Map data role to user
|
||||
break;
|
||||
default:
|
||||
role = "user"; // Default fallback, should not happen
|
||||
}
|
||||
|
||||
// Convert parts to MessageContent
|
||||
const content = this.convertVercelPartsToMessageContent(uiMessage.parts);
|
||||
|
||||
return {
|
||||
id: uiMessage.id,
|
||||
content: content ?? uiMessage.content,
|
||||
role,
|
||||
createdAt: uiMessage.createdAt,
|
||||
annotations: uiMessage.annotations,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if object matches VercelMessage structure
|
||||
*/
|
||||
isCompatible(message: unknown): message is VercelMessage {
|
||||
return !!(
|
||||
message &&
|
||||
typeof message === "object" &&
|
||||
"role" in message &&
|
||||
"content" in message &&
|
||||
"parts" in message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert UI parts to MessageContent
|
||||
*/
|
||||
private convertVercelPartsToMessageContent(
|
||||
parts: VercelMessage["parts"],
|
||||
): MessageContent | null {
|
||||
if (parts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const details: MessageContentDetail[] = [];
|
||||
|
||||
for (const part of parts) {
|
||||
switch (part.type) {
|
||||
case "file": {
|
||||
details.push({
|
||||
type: "file",
|
||||
data: part.data as string,
|
||||
mimeType: part.mimeType as string,
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// For other part types, convert to text
|
||||
details.push({
|
||||
type: "text",
|
||||
text: part.text as string,
|
||||
});
|
||||
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 convertMessageContentToVercelParts(
|
||||
content: MessageContent,
|
||||
): VercelMessage["parts"] {
|
||||
if (typeof content === "string") {
|
||||
return [
|
||||
{
|
||||
type: "text",
|
||||
text: content,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const parts: VercelMessage["parts"] = [];
|
||||
|
||||
for (const detail of content) {
|
||||
switch (detail.type) {
|
||||
case "text":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: detail.text,
|
||||
});
|
||||
break;
|
||||
case "image_url":
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: `[Image URL: ${detail.image_url.url}]`,
|
||||
});
|
||||
break;
|
||||
case "audio":
|
||||
case "video":
|
||||
case "image":
|
||||
case "file":
|
||||
parts.push({
|
||||
type: "file",
|
||||
data: detail.data,
|
||||
mimeType: detail.type,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
// For unknown types, create a text representation
|
||||
parts.push({
|
||||
type: "text",
|
||||
text: JSON.stringify(detail),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import type { MemoryMessage } from "../types";
|
||||
|
||||
export type MemoryBlockOptions = {
|
||||
/**
|
||||
* The id of the memory block.
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* The priority of the memory block.
|
||||
* Note: if priority is 0, the block content is always included in the memory context.
|
||||
*/
|
||||
priority: number;
|
||||
/**
|
||||
* Whether the memory block is long term.
|
||||
* Default is true.
|
||||
*/
|
||||
isLongTerm?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* A base class for memory blocks.
|
||||
*/
|
||||
export abstract class BaseMemoryBlock<
|
||||
TAdditionalMessageOptions extends object = object,
|
||||
> {
|
||||
public readonly id: string;
|
||||
public readonly priority: number;
|
||||
public readonly isLongTerm: boolean;
|
||||
|
||||
constructor(options: MemoryBlockOptions) {
|
||||
this.id = options.id ?? `memory-block-${randomUUID()}`;
|
||||
this.priority = options.priority;
|
||||
this.isLongTerm = options.isLongTerm ?? true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the memory block content (async).
|
||||
*
|
||||
* @returns The memory block content as an array of ChatMessage.
|
||||
*/
|
||||
abstract get(): Promise<MemoryMessage<TAdditionalMessageOptions>[]>;
|
||||
|
||||
/**
|
||||
* Store the messages in the memory block.
|
||||
*/
|
||||
abstract put(
|
||||
messages: MemoryMessage<TAdditionalMessageOptions>[],
|
||||
): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import type { LLM, MessageType } from "../../llms";
|
||||
import type { MemoryMessage } from "../types";
|
||||
import { BaseMemoryBlock, type MemoryBlockOptions } from "./base";
|
||||
|
||||
const DEFAULT_EXTRACTION_PROMPT = `
|
||||
You are a precise fact extraction system designed to identify key information from conversations.
|
||||
|
||||
CONVERSATION SEGMENT:
|
||||
{{conversation}}
|
||||
|
||||
EXISTING FACTS:
|
||||
{{existing_facts}}
|
||||
|
||||
INSTRUCTIONS:
|
||||
1. Review the conversation segment provided above.
|
||||
2. Extract specific, concrete facts the user has disclosed or important information discovered
|
||||
3. Focus on factual information like preferences, personal details, requirements, constraints, or context
|
||||
4. Do not include opinions, summaries, or interpretations - only extract explicit information
|
||||
5. Do not duplicate facts that are already in the existing facts list
|
||||
|
||||
Respond with the new facts from the conversation segment using the following JSON format:
|
||||
{
|
||||
"facts": ["fact1", "fact2", "fact3", ...]
|
||||
}
|
||||
`;
|
||||
|
||||
const DEFAULT_SUMMARY_PROMPT = `
|
||||
You are a precise fact condensing system designed to summarize facts in a concise manner.
|
||||
|
||||
EXISTING FACTS:
|
||||
{{existing_facts}}
|
||||
|
||||
INSTRUCTIONS:
|
||||
1. Review the current list of existing facts
|
||||
2. Condense the facts into a more concise list, less than {{ max_facts }} facts
|
||||
3. Focus on factual information like preferences, personal details, requirements, constraints, or context
|
||||
4. Do not include opinions, summaries, or interpretations - only extract explicit information
|
||||
5. Do not duplicate facts that are already in the existing facts list
|
||||
|
||||
Respond with the condensed facts using the following JSON format:
|
||||
{
|
||||
"facts": ["fact1", "fact2", "fact3", ...]
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* The options for the fact extraction memory block.
|
||||
*/
|
||||
export type FactExtractionMemoryBlockOptions = {
|
||||
/**
|
||||
* The fact extraction model to use.
|
||||
*/
|
||||
llm: LLM;
|
||||
/**
|
||||
* The maximum number of facts to extract.
|
||||
*/
|
||||
maxFacts: number;
|
||||
/**
|
||||
* The prompt to use for fact extraction.
|
||||
*/
|
||||
extractionPrompt?: string;
|
||||
/**
|
||||
* The prompt to use for fact summary.
|
||||
*/
|
||||
summaryPrompt?: string;
|
||||
} & MemoryBlockOptions & {
|
||||
isLongTerm?: true;
|
||||
};
|
||||
|
||||
/**
|
||||
* A memory block that stores facts extracted from conversations.
|
||||
*/
|
||||
export class FactExtractionMemoryBlock<
|
||||
TAdditionalMessageOptions extends object = object,
|
||||
> extends BaseMemoryBlock<TAdditionalMessageOptions> {
|
||||
private readonly llm: LLM;
|
||||
private facts: string[] = [];
|
||||
private readonly maxFacts: number;
|
||||
private readonly extractionPrompt: string;
|
||||
private readonly summaryPrompt: string;
|
||||
|
||||
constructor(options: FactExtractionMemoryBlockOptions) {
|
||||
super(options);
|
||||
this.llm = options.llm;
|
||||
this.maxFacts = options.maxFacts;
|
||||
this.extractionPrompt =
|
||||
options.extractionPrompt ?? DEFAULT_EXTRACTION_PROMPT;
|
||||
this.summaryPrompt = options.summaryPrompt ?? DEFAULT_SUMMARY_PROMPT;
|
||||
}
|
||||
|
||||
async get(): Promise<MemoryMessage<TAdditionalMessageOptions>[]> {
|
||||
const fact = {
|
||||
id: this.id,
|
||||
content: this.facts.join("\n"),
|
||||
role: "memory" as MessageType,
|
||||
};
|
||||
return [fact];
|
||||
}
|
||||
|
||||
async put(
|
||||
messages: MemoryMessage<TAdditionalMessageOptions>[],
|
||||
): Promise<void> {
|
||||
if (messages.length === 0) {
|
||||
return;
|
||||
}
|
||||
// Format existing facts
|
||||
const existingFactsStr = `{ facts: [${this.facts.join(", ")}] }`;
|
||||
// Format conversation
|
||||
const conversation = `\n\t${messages.map((m) => m.content).join("\n\t")}`;
|
||||
// Format prompt
|
||||
const prompt = this.extractionPrompt
|
||||
.replace("{{conversation}}", conversation)
|
||||
.replace("{{existing_facts}}", existingFactsStr);
|
||||
// Call the LLM
|
||||
const response = await this.llm.complete({
|
||||
prompt,
|
||||
});
|
||||
// Parse and validate the response
|
||||
const newFacts = JSON.parse(response.text);
|
||||
if (newFacts.facts === undefined || !Array.isArray(newFacts.facts)) {
|
||||
throw new Error(
|
||||
`[FactExtraction] Invalid response from LLM: ${response.text}`,
|
||||
);
|
||||
}
|
||||
// No new facts, so no need to update the facts
|
||||
if (newFacts.facts.length === 0) {
|
||||
return;
|
||||
}
|
||||
// Update the facts
|
||||
this.facts.push(...newFacts.facts);
|
||||
|
||||
// Condense the facts
|
||||
if (this.facts.length > this.maxFacts) {
|
||||
const existingFactsStr = `{ facts: [${this.facts.join(", ")}] }`;
|
||||
const prompt = this.summaryPrompt
|
||||
.replace("{{existing_facts}}", existingFactsStr)
|
||||
.replace("{{max_facts}}", this.maxFacts.toString());
|
||||
const response = await this.llm.complete({
|
||||
prompt,
|
||||
});
|
||||
const condensedFacts = JSON.parse(response.text);
|
||||
if (
|
||||
condensedFacts.facts === undefined ||
|
||||
!Array.isArray(condensedFacts.facts) ||
|
||||
condensedFacts.facts.length === 0
|
||||
) {
|
||||
throw new Error("Invalid response from LLM");
|
||||
}
|
||||
// Only get the first maxFacts facts (in case the LLM returned more)
|
||||
this.facts = condensedFacts.facts.slice(0, this.maxFacts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export { BaseMemoryBlock } from "./base";
|
||||
export { FactExtractionMemoryBlock } from "./fact";
|
||||
export { StaticMemoryBlock } from "./static";
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { MessageContent, MessageType } from "../../llms";
|
||||
import type { MemoryMessage } from "../types";
|
||||
import { BaseMemoryBlock, type MemoryBlockOptions } from "./base";
|
||||
|
||||
export type StaticMemoryBlockOptions = {
|
||||
/**
|
||||
* The static content to store.
|
||||
*/
|
||||
content: MessageContent;
|
||||
/**
|
||||
* The role of the message.
|
||||
*/
|
||||
messageRole?: MessageType;
|
||||
} & Omit<MemoryBlockOptions, "priority" | "isLongTerm">;
|
||||
|
||||
/**
|
||||
* A memory block that stores static content that doesn't change.
|
||||
* Static content is always included in the memory context.
|
||||
*/
|
||||
export class StaticMemoryBlock<
|
||||
TAdditionalMessageOptions extends object = object,
|
||||
> extends BaseMemoryBlock<TAdditionalMessageOptions> {
|
||||
private readonly content: MessageContent;
|
||||
private readonly messageRole: MessageType;
|
||||
|
||||
constructor(options: StaticMemoryBlockOptions) {
|
||||
super({ ...options, priority: 0, isLongTerm: false });
|
||||
this.content = options.content;
|
||||
this.messageRole = options.messageRole ?? "user";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the static content.
|
||||
* The messages parameter is ignored since this block contains static content.
|
||||
*/
|
||||
async get(): Promise<MemoryMessage<TAdditionalMessageOptions>[]> {
|
||||
return [
|
||||
{
|
||||
id: this.id,
|
||||
role: this.messageRole,
|
||||
content: this.content,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
async put(
|
||||
_messages: MemoryMessage<TAdditionalMessageOptions>[],
|
||||
): Promise<void> {
|
||||
// No-op: static content doesn't change
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage } from "../llms";
|
||||
import { type BaseChatStore, SimpleChatStore } from "../storage/chat-store";
|
||||
import { extractText } from "../utils";
|
||||
import { Settings } from "../../global";
|
||||
import type { ChatMessage } from "../../llms";
|
||||
import { type BaseChatStore, SimpleChatStore } from "../../storage/chat-store";
|
||||
import { extractText } from "../../utils";
|
||||
|
||||
export const DEFAULT_TOKEN_LIMIT_RATIO = 0.75;
|
||||
export const DEFAULT_CHAT_STORE_KEY = "chat_history";
|
||||
|
||||
/**
|
||||
* A ChatMemory is used to keep the state of back and forth chat messages
|
||||
* @deprecated Use Memory instead.
|
||||
*/
|
||||
export abstract class BaseMemory<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
@@ -55,6 +56,9 @@ export abstract class BaseMemory<
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Memory with snapshot feature with your own storage instead.
|
||||
*/
|
||||
export abstract class BaseChatStoreMemory<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends BaseMemory<AdditionalMessageOptions> {
|
||||
+6
-3
@@ -1,6 +1,6 @@
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage, LLM } from "../llms";
|
||||
import { type BaseChatStore } from "../storage/chat-store";
|
||||
import { Settings } from "../../global";
|
||||
import type { ChatMessage, LLM } from "../../llms";
|
||||
import { type BaseChatStore } from "../../storage/chat-store";
|
||||
import { BaseChatStoreMemory, DEFAULT_TOKEN_LIMIT_RATIO } from "./base";
|
||||
|
||||
type ChatMemoryBufferOptions<AdditionalMessageOptions extends object = object> =
|
||||
@@ -12,6 +12,9 @@ type ChatMemoryBufferOptions<AdditionalMessageOptions extends object = object> =
|
||||
llm?: LLM<object, AdditionalMessageOptions> | undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use Memory instead.
|
||||
*/
|
||||
export class ChatMemoryBuffer<
|
||||
AdditionalMessageOptions extends object = object,
|
||||
> extends BaseChatStoreMemory<AdditionalMessageOptions> {
|
||||
+7
-4
@@ -1,10 +1,13 @@
|
||||
import { type Tokenizer, tokenizers } from "@llamaindex/env/tokenizers";
|
||||
import { Settings } from "../global";
|
||||
import type { ChatMessage, LLM, MessageType } from "../llms";
|
||||
import { defaultSummaryPrompt, type SummaryPrompt } from "../prompts";
|
||||
import { extractText, messagesToHistory } from "../utils";
|
||||
import { Settings } from "../../global";
|
||||
import type { ChatMessage, LLM, MessageType } from "../../llms";
|
||||
import { defaultSummaryPrompt, type SummaryPrompt } from "../../prompts";
|
||||
import { extractText, messagesToHistory } from "../../utils";
|
||||
import { BaseMemory } from "./base";
|
||||
|
||||
/**
|
||||
* @deprecated Use Memory instead.
|
||||
*/
|
||||
export class ChatSummaryMemoryBuffer extends BaseMemory {
|
||||
/**
|
||||
* Tokenizer function that converts text to tokens,
|
||||
@@ -0,0 +1,136 @@
|
||||
import type { ChatMessage } from "../llms";
|
||||
import { ChatMessageAdapter } from "./adapter/chat";
|
||||
import {
|
||||
FactExtractionMemoryBlock,
|
||||
type FactExtractionMemoryBlockOptions,
|
||||
} from "./block/fact";
|
||||
import {
|
||||
StaticMemoryBlock,
|
||||
type StaticMemoryBlockOptions,
|
||||
} from "./block/static";
|
||||
import { DEFAULT_TOKEN_LIMIT, Memory, type MemoryOptions } from "./memory";
|
||||
import type { MemoryMessage } from "./types";
|
||||
|
||||
/**
|
||||
* Create a Memory instance with default options
|
||||
* @returns A new Memory instance with default configuration
|
||||
*/
|
||||
export function createMemory<TMessageOptions extends object = object>(): Memory<
|
||||
Record<string, never>,
|
||||
TMessageOptions
|
||||
>;
|
||||
|
||||
/**
|
||||
* Create a Memory instance with options only
|
||||
* @param options - Memory configuration options
|
||||
* @returns A new Memory instance
|
||||
*/
|
||||
export function createMemory<TMessageOptions extends object = object>(
|
||||
options: MemoryOptions<TMessageOptions>,
|
||||
): Memory<Record<string, never>, TMessageOptions>;
|
||||
|
||||
/**
|
||||
* Create a Memory instance with ChatMessage array (IDs will be generated)
|
||||
* @param messages - Initial ChatMessage array for the memory
|
||||
* @param options - Memory configuration options
|
||||
* @returns A new Memory instance
|
||||
*/
|
||||
export function createMemory<TMessageOptions extends object = object>(
|
||||
messages: ChatMessage<TMessageOptions>[],
|
||||
options?: MemoryOptions<TMessageOptions>,
|
||||
): Memory<Record<string, never>, TMessageOptions>;
|
||||
|
||||
/**
|
||||
* Create a Memory instance with MemoryMessage array and options
|
||||
* @param messages - Initial MemoryMessage array for the memory
|
||||
* @param options - Memory configuration options
|
||||
* @returns A new Memory instance
|
||||
*/
|
||||
export function createMemory<TMessageOptions extends object = object>(
|
||||
messages: MemoryMessage<TMessageOptions>[],
|
||||
options: MemoryOptions<TMessageOptions>,
|
||||
): Memory<Record<string, never>, TMessageOptions>;
|
||||
|
||||
/**
|
||||
* Create a Memory instance
|
||||
* @param messagesOrOptions - Either initial messages or options
|
||||
* @param options - Memory configuration options (when first param is messages)
|
||||
* @returns A new Memory instance
|
||||
*/
|
||||
export function createMemory<TMessageOptions extends object = object>(
|
||||
messagesOrOptions:
|
||||
| ChatMessage<TMessageOptions>[]
|
||||
| MemoryMessage<TMessageOptions>[]
|
||||
| MemoryOptions<TMessageOptions> = [],
|
||||
options: MemoryOptions<TMessageOptions> = {},
|
||||
): Memory<Record<string, never>, TMessageOptions> {
|
||||
let messages: MemoryMessage<TMessageOptions>[] = [];
|
||||
|
||||
if (Array.isArray(messagesOrOptions)) {
|
||||
const firstMessage = messagesOrOptions[0];
|
||||
if (firstMessage) {
|
||||
if ("id" in firstMessage) {
|
||||
messages = messagesOrOptions as MemoryMessage<TMessageOptions>[];
|
||||
} else {
|
||||
const adapter = new ChatMessageAdapter<TMessageOptions>();
|
||||
messages = messagesOrOptions.map((chatMessage) =>
|
||||
adapter.toMemory(chatMessage),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Memory<Record<string, never>, TMessageOptions>(messages, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a StaticMemoryBlock
|
||||
* @param options - Configuration options for the static memory block
|
||||
* @returns A new StaticMemoryBlock instance
|
||||
*/
|
||||
export function staticBlock<TMessageOptions extends object = object>(
|
||||
options: StaticMemoryBlockOptions,
|
||||
): StaticMemoryBlock<TMessageOptions> {
|
||||
return new StaticMemoryBlock<TMessageOptions>(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a FactExtractionMemoryBlock
|
||||
* @param options - Configuration options for the fact extraction memory block
|
||||
* @returns A new FactExtractionMemoryBlock instance
|
||||
*/
|
||||
export function factExtractionBlock<TMessageOptions extends object = object>(
|
||||
options: FactExtractionMemoryBlockOptions,
|
||||
): FactExtractionMemoryBlock<TMessageOptions> {
|
||||
return new FactExtractionMemoryBlock<TMessageOptions>(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Memory instance from a snapshot
|
||||
* @param snapshot The snapshot to load from
|
||||
* @param options Optional MemoryOptions to apply when loading (including memory blocks)
|
||||
* @returns A new Memory instance with the snapshot data and provided options
|
||||
*/
|
||||
export function loadMemory<TMessageOptions extends object = object>(
|
||||
snapshot: string,
|
||||
options?: MemoryOptions<TMessageOptions>,
|
||||
): Memory<Record<string, never>, TMessageOptions> {
|
||||
const { messages, tokenLimit, memoryCursor } = JSON.parse(snapshot);
|
||||
|
||||
// Merge snapshot data with provided options
|
||||
const mergedOptions: MemoryOptions<TMessageOptions> = {
|
||||
tokenLimit: options?.tokenLimit ?? tokenLimit ?? DEFAULT_TOKEN_LIMIT,
|
||||
...(options?.shortTermTokenLimitRatio && {
|
||||
shortTermTokenLimitRatio: options.shortTermTokenLimitRatio,
|
||||
}),
|
||||
...(options?.customAdapters && {
|
||||
customAdapters: options.customAdapters,
|
||||
}),
|
||||
memoryBlocks: options?.memoryBlocks ?? [],
|
||||
memoryCursor: memoryCursor ?? 0,
|
||||
};
|
||||
|
||||
return new Memory<Record<string, never>, TMessageOptions>(
|
||||
messages,
|
||||
mergedOptions,
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
export { BaseMemory } from "./base";
|
||||
export { ChatMemoryBuffer } from "./chat-memory-buffer";
|
||||
export { ChatSummaryMemoryBuffer } from "./summary-memory";
|
||||
export { BaseMemory } from "./deprecated/base";
|
||||
export { ChatMemoryBuffer } from "./deprecated/chat-memory-buffer";
|
||||
export { ChatSummaryMemoryBuffer } from "./deprecated/summary-memory";
|
||||
|
||||
export * from "./adapter";
|
||||
export * from "./block";
|
||||
export * from "./factories";
|
||||
export { Memory } from "./memory";
|
||||
export * from "./types";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user