Compare commits

..

7 Commits

Author SHA1 Message Date
Alex Yang 733c0e3057 fix: interrupt 2024-11-13 11:01:28 -08:00
Alex Yang 628be9eb66 Merge remote-tracking branch 'origin/main' into himself65/20241113/warn 2024-11-13 01:18:19 -08:00
Alex Yang 1c103921ae changeset 2024-11-13 01:09:30 -08:00
Alex Yang f4cf37b643 feat: recoverable data with error handling 2024-11-13 01:08:34 -08:00
Alex Yang 463bf8b630 fix: code 2024-11-13 00:48:03 -08:00
Alex Yang 236828a331 Merge remote-tracking branch 'origin/main' into himself65/20241113/warn 2024-11-13 00:47:03 -08:00
Alex Yang b86208b703 docs: update 2024-11-13 00:27:05 -08:00
100 changed files with 1996 additions and 1638 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@llamaindex/workflow": patch
---
fix: output event check
+5
View File
@@ -0,0 +1,5 @@
---
"@llamaindex/workflow": patch
---
feat: recoverable context with error handling
+3 -7
View File
@@ -1,16 +1,12 @@
<p align="center">
<img height="100" width="100" alt="LlamaIndex logo" src="https://ts.llamaindex.ai/square.svg" />
</p>
<h1 align="center">LlamaIndex.TS</h1>
<h3 align="center">
Data framework for your LLM application.
</h3>
# LlamaIndex.TS
[![NPM Version](https://img.shields.io/npm/v/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![NPM License](https://img.shields.io/npm/l/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![NPM Downloads](https://img.shields.io/npm/dm/llamaindex)](https://www.npmjs.com/package/llamaindex)
[![Discord](https://img.shields.io/discord/1059199217496772688)](https://discord.com/invite/eN6D2HQ4aX)
LlamaIndex is a data framework for your LLM application.
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in JS runtime environments with TypeScript support.
Documentation: https://ts.llamaindex.ai/
-28
View File
@@ -1,33 +1,5 @@
# docs
## 0.0.120
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.119
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.118
### Patch Changes
- llamaindex@0.8.13
- @llamaindex/examples@0.0.16
## 0.0.117
### Patch Changes
- @llamaindex/examples@0.0.15
## 0.0.116
### Patch Changes
-6
View File
@@ -62,12 +62,6 @@ const config = {
({
// Replace with your project's social card
image: "img/favicon.png", // TODO change this
announcementBar: {
id: "migrate_to_next",
content:
'We are migrating to Next.js based documentation. Check it out <a href="https://ts.llamaindex.ai/docs/llamaindex">here</a>!',
isCloseable: false,
},
navbar: {
title: "LlamaIndex.TS",
logo: {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.120",
"version": "0.0.116",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
-38
View File
@@ -1,43 +1,5 @@
# @llamaindex/doc
## 0.0.18
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.17
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.16
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [ee20c44]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
- @llamaindex/workflow@0.0.6
- llamaindex@0.8.13
- @llamaindex/cloud@2.0.10
- @llamaindex/node-parser@0.0.11
- @llamaindex/openai@0.1.35
- @llamaindex/readers@1.0.11
## 0.0.15
### Patch Changes
- Updated dependencies [ea92b69]
- Updated dependencies [fadc8b8]
- @llamaindex/workflow@0.0.5
## 0.0.14
### Patch Changes
+10 -2
View File
@@ -6,7 +6,16 @@ const withMDX = createMDX();
const config = {
reactStrictMode: true,
transpilePackages: ["monaco-editor"],
serverExternalPackages: ["@huggingface/transformers"],
images: {
remotePatterns: [
{
protocol: "https",
hostname: "mermaid.ink",
port: "",
pathname: "/**",
},
],
},
webpack: (config, { isServer }) => {
if (Array.isArray(config.target) && config.target.includes("web")) {
config.target = ["web", "es2020"];
@@ -27,7 +36,6 @@ const config = {
}),
);
}
config.resolve.alias["replicate"] = false;
return config;
},
};
+5 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/doc",
"version": "0.0.18",
"version": "0.0.14",
"private": true,
"scripts": {
"build": "pnpm run build:docs && next build",
@@ -12,7 +12,7 @@
},
"dependencies": {
"@icons-pack/react-simple-icons": "^10.1.0",
"@llamaindex/chat-ui": "0.0.8",
"@llamaindex/chat-ui": "0.0.5",
"@llamaindex/cloud": "workspace:*",
"@llamaindex/core": "workspace:*",
"@llamaindex/node-parser": "workspace:*",
@@ -24,6 +24,8 @@
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-icons": "^1.3.1",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slider": "^1.2.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
@@ -52,6 +54,7 @@
"react-text-transition": "^3.1.0",
"react-use-measure": "^2.1.1",
"rehype-katex": "^7.0.1",
"rehype-mermaid": "^3.0.0",
"remark-math": "^6.0.0",
"rimraf": "^6.0.1",
"shiki": "^1.22.2",
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.3 KiB

+1 -4
View File
@@ -1,10 +1,7 @@
import { llm } from "@/lib/utils";
import { LlamaIndexAdapter, type Message } from "ai";
import { Settings, SimpleChatEngine, type ChatMessage } from "llamaindex";
import { SimpleChatEngine, type ChatMessage } from "llamaindex";
import { NextResponse, type NextRequest } from "next/server";
Settings.llm = llm;
export async function POST(request: NextRequest) {
try {
const { messages } = (await request.json()) as { messages: Message[] };
+8
View File
@@ -0,0 +1,8 @@
"use client";
import { ChatSection } from "@llamaindex/chat-ui";
import { useChat } from "ai/react";
export const ChatDemo = () => {
const handler = useChat();
return <ChatSection handler={handler} />;
};
@@ -1,16 +0,0 @@
"use client";
import { ChatInput, ChatMessages, ChatSection } from "@llamaindex/chat-ui";
import { useChat } from "ai/react";
export const ChatDemo = () => {
const handler = useChat();
return (
<ChatSection handler={handler}>
<ChatMessages>
<ChatMessages.List className="h-auto max-h-[400px]" />
<ChatMessages.Actions />
</ChatMessages>
<ChatInput />
</ChatSection>
);
};
@@ -1,57 +0,0 @@
import { llm } from "@/lib/utils";
import { Markdown } from "@llamaindex/chat-ui/widgets";
import { generateId, Message } from "ai";
import { createAI, createStreamableUI, getMutableAIState } from "ai/rsc";
import { type ChatMessage, Settings, SimpleChatEngine } from "llamaindex";
import { ReactNode } from "react";
type ServerState = Message[];
type FrontendState = Array<Message & { display: ReactNode }>;
type Actions = {
chat: (message: Message) => Promise<Message & { display: ReactNode }>;
};
Settings.llm = llm;
export const AI = createAI<ServerState, FrontendState, Actions>({
initialAIState: [],
initialUIState: [],
actions: {
chat: async (message: Message) => {
"use server";
const aiState = getMutableAIState<typeof AI>();
aiState.update((prev) => [...prev, message]);
const uiStream = createStreamableUI();
const chatEngine = new SimpleChatEngine();
const assistantMessage: Message = {
id: generateId(),
role: "assistant",
content: "",
};
// run the async function without blocking
(async () => {
const chatResponse = await chatEngine.chat({
stream: true,
message: message.content,
chatHistory: aiState.get() as ChatMessage[],
});
for await (const chunk of chatResponse) {
assistantMessage.content += chunk.delta;
uiStream.update(<Markdown content={assistantMessage.content} />);
}
aiState.done([...aiState.get(), assistantMessage]);
uiStream.done();
})();
return {
...assistantMessage,
display: uiStream.value,
};
},
},
});
@@ -1,33 +0,0 @@
"use client";
import {
ChatInput,
ChatMessage,
ChatMessages,
ChatSection as ChatSectionUI,
} from "@llamaindex/chat-ui";
import { useChatRSC } from "./use-chat-rsc";
export const ChatSectionRSC = () => {
const handler = useChatRSC();
return (
<ChatSectionUI handler={handler}>
<ChatMessages>
<ChatMessages.List className="h-auto max-h-[400px]">
{handler.messages.map((message, index) => (
<ChatMessage
key={index}
message={message}
isLast={index === handler.messages.length - 1}
>
<ChatMessage.Avatar />
<ChatMessage.Content>{message.display}</ChatMessage.Content>
</ChatMessage>
))}
<ChatMessages.Loading />
</ChatMessages.List>
</ChatMessages>
<ChatInput />
</ChatSectionUI>
);
};
@@ -1,8 +0,0 @@
import { AI } from "./ai-action";
import { ChatSectionRSC } from "./chat-section";
export const ChatDemoRSC = () => (
<AI>
<ChatSectionRSC />
</AI>
);
@@ -1,41 +0,0 @@
"use client";
import { useActions } from "ai/rsc";
import { generateId, Message } from "ai";
import { useUIState } from "ai/rsc";
import { useState } from "react";
import { AI } from "./ai-action";
export function useChatRSC() {
const [input, setInput] = useState<string>("");
const [isLoading, setIsLoading] = useState<boolean>(false);
const [messages, setMessages] = useUIState<typeof AI>();
const { chat } = useActions<typeof AI>();
const append = async (message: Omit<Message, "id">) => {
const newMsg: Message = { ...message, id: generateId() };
setIsLoading(true);
try {
setMessages((prev) => [...prev, { ...newMsg, display: message.content }]);
const assistantMsg = await chat(newMsg);
setMessages((prev) => [...prev, assistantMsg]);
} catch (error) {
console.error(error);
}
setIsLoading(false);
setInput("");
return message.content;
};
return {
input,
setInput,
isLoading,
messages,
setMessages,
append,
};
}
+213
View File
@@ -0,0 +1,213 @@
"use client";
import type { ShippingInfo } from "@/components/demo/checkout/shpping";
import {
StartEvent,
StopEvent,
Workflow,
WorkflowContext,
WorkflowEvent,
} from "@llamaindex/workflow";
import { ReactNode, useCallback, useState } from "react";
import { Button } from "../ui/button";
import {
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
} from "../ui/card";
import { Separator } from "../ui/separator";
type Context = {
userId: string;
items: { name: string; price: number; quantity: number }[];
// utility functions with frontend
update: (ui: ReactNode) => void;
interrupt: () => void;
};
type UserInfo = {
id: string;
name: string;
email: string;
shippingAddress: ShippingInfo;
};
const getUser = async (userId: string): Promise<UserInfo | null> => {
await new Promise((resolve) => setTimeout(resolve, 1000));
const user = localStorage.getItem(`workflow-demo-user:${userId}`);
if (user !== null) {
return JSON.parse(user) as UserInfo;
} else {
return null;
}
};
const checkoutWorkflow = new Workflow<Context, void, void>({});
// 1. User click checkout button
// 2. Check if user has correct information
// - If not, show shipping information form
// 3. Proceed to payment
// 4. Confirm the order
// 5. Send confirmation email
class ShowShippingInformationFormEvent extends WorkflowEvent<void> {}
class ProceedToPaymentEvent extends WorkflowEvent<void> {}
class ConfirmOrderEvent extends WorkflowEvent<void> {}
class SendConfirmationEmailEvent extends WorkflowEvent<void> {}
checkoutWorkflow.addStep(
{
inputs: [StartEvent],
outputs: [ProceedToPaymentEvent, ShowShippingInformationFormEvent],
},
async ({ data }, _) => {
const user = await getUser(data.userId);
if (user === null) {
return new ShowShippingInformationFormEvent();
}
// todo
return new ProceedToPaymentEvent();
},
);
checkoutWorkflow.addStep(
{
inputs: [ShowShippingInformationFormEvent],
outputs: [ProceedToPaymentEvent],
},
async ({ data }) => {
const user = await getUser(data.userId);
if (user === null) {
data.update("TODO");
data.interrupt();
}
return new ProceedToPaymentEvent();
},
);
checkoutWorkflow.addStep(
{
inputs: [ProceedToPaymentEvent],
outputs: [ConfirmOrderEvent],
},
async () => {
return new ConfirmOrderEvent();
},
);
checkoutWorkflow.addStep(
{
inputs: [ConfirmOrderEvent],
outputs: [SendConfirmationEmailEvent],
},
async () => {
return new SendConfirmationEmailEvent();
},
);
checkoutWorkflow.addStep(
{
inputs: [SendConfirmationEmailEvent],
outputs: [StopEvent<void>],
},
async () => {
return new StopEvent(void 0);
},
);
async function runContext(context: WorkflowContext<void, void, Context>) {
try {
await context;
} catch (e) {
if (e instanceof Error && e.message === "Interrupted") {
const snapshot = context.snapshot();
// for each step, save the snapshot into the local storage
localStorage.setItem(
"workflow-snapshot",
new TextDecoder().decode(snapshot),
);
} else {
throw e;
}
}
}
export const CheckoutDemo = () => {
const items = [
{ name: "T-Shirt", price: 19.99, quantity: 2 },
{ name: "Jeans", price: 49.99, quantity: 1 },
{ name: "Sneakers", price: 79.99, quantity: 1 },
];
const [ui, setUI] = useState<ReactNode>(null);
const [contextData, setContextData] = useState<Context>({
userId: "1",
items: items,
update: (ui) => setUI(ui),
interrupt: () => {
throw new Error("Interrupted");
},
});
const subtotal = items.reduce(
(acc, item) => acc + item.price * item.quantity,
0,
);
const tax = subtotal * 0.1; // Assuming 10% tax
const total = subtotal + tax;
const onClickStartCheckout = useCallback(() => {
const context = checkoutWorkflow.run().with(contextData);
runContext(context);
}, []);
return (
<div>
{ui}
<Card className="w-full max-w-md mx-auto">
<CardHeader>
<CardTitle>Your Order</CardTitle>
</CardHeader>
<CardContent>
<ul className="space-y-2">
{items.map((item, index) => (
<li key={index} className="flex justify-between items-center">
<span>
{item.name} x{item.quantity}
</span>
<span>${(item.price * item.quantity).toFixed(2)}</span>
</li>
))}
</ul>
<Separator className="my-4" />
<div className="space-y-2">
<div className="flex justify-between">
<span>Subtotal</span>
<span>${subtotal.toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span>Tax</span>
<span>${tax.toFixed(2)}</span>
</div>
<div className="flex justify-between font-bold">
<span>Total</span>
<span>${total.toFixed(2)}</span>
</div>
</div>
</CardContent>
<CardFooter>
<Button className="w-full" onClick={onClickStartCheckout}>
Proceed to Checkout
</Button>
</CardFooter>
</Card>
</div>
);
};
@@ -0,0 +1,126 @@
"use client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useState } from "react";
export function ShippingForm({
onSubmit,
}: {
onSubmit: (data: ShippingInfo) => void;
}) {
const [formData, setFormData] = useState<ShippingInfo>({
fullName: "",
address: "",
city: "",
state: "",
zipCode: "",
country: "",
});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};
const handleCountryChange = (value: string) => {
setFormData((prev) => ({ ...prev, country: value }));
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(formData);
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<Label htmlFor="fullName">Full Name</Label>
<Input
id="fullName"
name="fullName"
value={formData.fullName}
onChange={handleChange}
required
/>
</div>
<div>
<Label htmlFor="address">Address</Label>
<Input
id="address"
name="address"
value={formData.address}
onChange={handleChange}
required
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<Label htmlFor="city">City</Label>
<Input
id="city"
name="city"
value={formData.city}
onChange={handleChange}
required
/>
</div>
<div>
<Label htmlFor="state">State</Label>
<Input
id="state"
name="state"
value={formData.state}
onChange={handleChange}
required
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<Label htmlFor="zipCode">ZIP Code</Label>
<Input
id="zipCode"
name="zipCode"
value={formData.zipCode}
onChange={handleChange}
required
/>
</div>
<div>
<Label htmlFor="country">Country</Label>
<Select onValueChange={handleCountryChange} value={formData.country}>
<SelectTrigger id="country">
<SelectValue placeholder="Select country" />
</SelectTrigger>
<SelectContent>
<SelectItem value="us">United States</SelectItem>
<SelectItem value="ca">Canada</SelectItem>
<SelectItem value="uk">United Kingdom</SelectItem>
{/* Add more countries as needed */}
</SelectContent>
</Select>
</div>
</div>
<Button type="submit" className="w-full">
Save Shipping Information
</Button>
</form>
);
}
export interface ShippingInfo {
fullName: string;
address: string;
city: string;
state: string;
zipCode: string;
country: string;
}
+83
View File
@@ -0,0 +1,83 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
className,
)}
{...props}
/>
));
Card.displayName = "Card";
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
));
CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("font-semibold leading-none tracking-tight", className)}
{...props}
/>
));
CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
));
CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
));
CardFooter.displayName = "CardFooter";
export {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
};
+162
View File
@@ -0,0 +1,162 @@
"use client";
import { cn } from "@/lib/utils";
import {
CheckIcon,
ChevronDownIcon,
ChevronUpIcon,
} from "@radix-ui/react-icons";
import * as SelectPrimitive from "@radix-ui/react-select";
import * as React from "react";
const Select = SelectPrimitive.Root;
const SelectGroup = SelectPrimitive.Group;
const SelectValue = SelectPrimitive.Value;
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDownIcon className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className,
)}
{...props}
>
<ChevronUpIcon className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
className,
)}
{...props}
>
<ChevronDownIcon className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName;
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className,
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = SelectPrimitive.Content.displayName;
const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("px-2 py-1.5 text-sm font-semibold", className)}
{...props}
/>
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
{...props}
>
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<CheckIcon className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;
const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
export {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectScrollDownButton,
SelectScrollUpButton,
SelectSeparator,
SelectTrigger,
SelectValue,
};
+31
View File
@@ -0,0 +1,31 @@
"use client";
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import * as React from "react";
import { cn } from "@/lib/utils";
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(
(
{ className, orientation = "horizontal", decorative = true, ...props },
ref,
) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
"shrink-0 bg-border",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className,
)}
{...props}
/>
),
);
Separator.displayName = SeparatorPrimitive.Root.displayName;
export { Separator };
@@ -1,8 +1,8 @@
---
title: Using API Route
description: Chat interface for your LlamaIndexTS application using API Route
title: Chat-UI
description: Use chat-ui to add a chat interface to your LlamaIndexTS application.
---
import { ChatDemo } from '../../../../../components/demo/chat/api/demo';
import { ChatDemo } from '../../../../components/demo/chat';
import "@llamaindex/chat-ui/styles/code.css";
import "@llamaindex/chat-ui/styles/katex.css";
@@ -26,7 +26,7 @@ This is the simplest way to add a chat interface to your application. Copy the f
```json doc-gen:file
{
"file": "./src/components/demo/chat/api/demo.tsx",
"file": "./src/components/demo/chat.tsx",
"codeblock": true
}
```
@@ -37,7 +37,6 @@ Combining both, you're getting a fully functional chat interface:
<ChatDemo />
## Next Steps
The steps above are the bare minimum to get a chat interface working. From here, you can go two ways:
@@ -1,6 +0,0 @@
{
"title": "Chat-UI",
"description": "Use chat-ui to add a chat interface to your LlamaIndexTS application.",
"defaultOpen": false,
"pages": ["chat", "rsc"]
}
@@ -1,68 +0,0 @@
---
title: Using Next.js RSC
description: Chat interface for your LlamaIndexTS application using Next.js RSC
---
import { ChatDemoRSC } from '../../../../../components/demo/chat/rsc/demo';
import "@llamaindex/chat-ui/styles/code.css";
import "@llamaindex/chat-ui/styles/katex.css";
Using [chat-ui](https://github.com/run-llama/chat-ui), it's easy to add a chat interface to your LlamaIndexTS application using [Next.js RSC](https://nextjs.org/docs/app/building-your-application/rendering/server-components) and [Vercel AI RSC](https://sdk.vercel.ai/docs/ai-sdk-rsc/overview).
With RSC, the chat messages are not returned as JSON from the server (like when using an [API route](./chat)), instead the chat message components are rendered on the server side.
This is for example useful for rendering a whole chat history on the server before sending it to the client. [Check here](https://sdk.vercel.ai/docs/getting-started/navigating-the-library#when-to-use-ai-sdk-rsc), for a discussion of when to use use RSC.
For implementing a chat interface with RSC, you need to create an AI action and then connect the chat interface to use it.
## Create an AI action
First, define an [AI context provider](https://sdk.vercel.ai/examples/rsc/state-management/ai-ui-states) with a chat server action:
```json doc-gen:file
{
"file": "./src/components/demo/chat/rsc/ai-action.tsx",
"codeblock": true
}
```
The chat server action is using LlamaIndexTS to generate a response based on the chat history and the user input.
## Create the chat UI
The entrypoint of our application initializes the AI provider for the application and adds a `ChatSection` component:
```json doc-gen:file
{
"file": "./src/components/demo/chat/rsc/demo.tsx",
"codeblock": true
}
```
The `ChatSection` component is created by using chat components from @llamaindex/chat-ui:
```json doc-gen:file
{
"file": "./src/components/demo/chat/rsc/chat-section.tsx",
"codeblock": true
}
```
It is using a `useChatRSC` hook to conntect the chat interface to the `chat` AI action that we defined earlier:
```json doc-gen:file
{
"file": "./src/components/demo/chat/rsc/use-chat-rsc.tsx",
"codeblock": true
}
```
## Try RSC Chat ⬇️
<ChatDemoRSC />
## Next Steps
The steps above are the bare minimum to get a chat interface working with RSC. From here, you can go two ways:
1. Use our [full-stack RSC example](https://github.com/run-llama/nextjs-rsc) based on [create-llama](https://github.com/run-llama/create-llama) to get started quickly with a fully working chat interface or
2. Learn more about [AI RSC](https://sdk.vercel.ai/examples/rsc), [chat-ui](https://github.com/run-llama/chat-ui) and [LlamaIndexTS](https://github.com/run-llama/llamaindex-ts) to customize the chat interface and AI actions to your needs.
@@ -0,0 +1,19 @@
---
title: Event Step Handler
description: Learn how to design a good event handler for your workflow.
---
import { CheckoutDemo } from '../../../../../components/demo/checkout'
Let's start an checkout workflow.
<div className='grid grid-cols-2 gap-4'>
<CheckoutDemo/>
<div
className='border p-4'
style={{
borderColor: 'hsl(var(--border))'
}}
>
[![](https://mermaid.ink/img/pako:eNptkd9ugyAUxl-FcN2-gEu2zD9t7dKtmcuSDXtB5KikCgaPWxrruw_RtmkyruB8Pz7O4etppgVQjxaGNyX5CB9SRex6ZglygyQoITvqDg9kuXwkPvuU8EsCqxwmznf1gEUKwZCklE0jVUFilWtTc5RazWDgwJAlUEGGN3IHWGoxQ6GDotltz081KPzHLHLcir3Dz9jPmxFgZmnlpHUft1OZBNoY--LTMOnrUT9_QXsmG7aveAZ31yf5VZ-JPxU2zi9mFzOVy_teYgds7WBK3OkkqrmsZmrrqBc7mbj9aarogtZgeSlsBP2IphRLqCGlnt0Kbo4pTdVgOd6hTk4qox6aDhbU6K4oqZfzqrWnrhEcIZTc5lhfkIarb62vRxAStdlNebvYhz_ob6Ka?type=png)](https://mermaid.live/edit#pako:eNptkd9ugyAUxl-FcN2-gEu2zD9t7dKtmcuSDXtB5KikCgaPWxrruw_RtmkyruB8Pz7O4etppgVQjxaGNyX5CB9SRex6ZglygyQoITvqDg9kuXwkPvuU8EsCqxwmznf1gEUKwZCklE0jVUFilWtTc5RazWDgwJAlUEGGN3IHWGoxQ6GDotltz081KPzHLHLcir3Dz9jPmxFgZmnlpHUft1OZBNoY--LTMOnrUT9_QXsmG7aveAZ31yf5VZ-JPxU2zi9mFzOVy_teYgds7WBK3OkkqrmsZmrrqBc7mbj9aarogtZgeSlsBP2IphRLqCGlnt0Kbo4pTdVgOd6hTk4qox6aDhbU6K4oqZfzqrWnrhEcIZTc5lhfkIarb62vRxAStdlNebvYhz_ob6Ka)
</div>
</div>
@@ -2,5 +2,12 @@
"title": "Workflow",
"description": "See how to use @llamaindex/workflow",
"defaultOpen": false,
"pages": ["index", "different-inputs-outputs", "streaming"]
"pages": [
"index",
"different-inputs-outputs",
"streaming",
"---Advanced concept---",
"handler",
"..."
]
}
+2 -30
View File
@@ -1,34 +1,6 @@
import { clsx, type ClassValue } from "clsx";
import { LLM, LLMMetadata } from "llamaindex";
import { twMerge } from "tailwind-merge";
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
class MockLLM {
metadata: LLMMetadata = {
model: "MockLLM",
temperature: 0.5,
topP: 0.5,
contextWindow: 1024,
tokenizer: undefined,
};
chat() {
const mockResponse = "Hello! This is a mock response";
return Promise.resolve(
new ReadableStream({
async start(controller) {
for (const char of mockResponse) {
controller.enqueue({ delta: char });
await new Promise((resolve) => setTimeout(resolve, 20));
}
controller.close();
},
}),
);
}
}
export const llm = new MockLLM() as unknown as LLM;
@@ -1,26 +1,5 @@
# @llamaindex/cloudflare-worker-agent-test
## 0.0.111
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.110
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.109
### Patch Changes
- llamaindex@0.8.13
## 0.0.108
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.111",
"version": "0.0.108",
"type": "module",
"private": true,
"scripts": {
@@ -1,11 +1,5 @@
# @llamaindex/llama-parse-browser-test
## 0.0.30
### Patch Changes
- @llamaindex/cloud@2.0.10
## 0.0.29
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/llama-parse-browser-test",
"private": true,
"version": "0.0.30",
"version": "0.0.29",
"type": "module",
"scripts": {
"dev": "vite",
-21
View File
@@ -1,26 +1,5 @@
# @llamaindex/next-agent-test
## 0.1.111
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.1.110
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.1.109
### Patch Changes
- llamaindex@0.8.13
## 0.1.108
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.111",
"version": "0.1.108",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,26 +1,5 @@
# test-edge-runtime
## 0.1.110
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.1.109
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.1.108
### Patch Changes
- llamaindex@0.8.13
## 0.1.107
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.110",
"version": "0.1.107",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,26 +1,5 @@
# @llamaindex/next-node-runtime
## 0.0.92
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.91
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.90
### Patch Changes
- llamaindex@0.8.13
## 0.0.89
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.0.92",
"version": "0.0.89",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,26 +1,5 @@
# @llamaindex/waku-query-engine-test
## 0.0.111
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.110
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.109
### Patch Changes
- llamaindex@0.8.13
## 0.0.108
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.111",
"version": "0.0.108",
"type": "module",
"private": true,
"scripts": {
-20
View File
@@ -1,25 +1,5 @@
# examples
## 0.0.16
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [ee20c44]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
- @llamaindex/workflow@0.0.6
- llamaindex@0.8.13
- @llamaindex/readers@1.0.11
## 0.0.15
### Patch Changes
- Updated dependencies [ea92b69]
- Updated dependencies [fadc8b8]
- @llamaindex/workflow@0.0.5
## 0.0.14
### Patch Changes
-38
View File
@@ -1,38 +0,0 @@
import { Anthropic } from "llamaindex";
async function main() {
const anthropic = new Anthropic({
model: "claude-3-5-sonnet-20241022",
});
const entireBook = await fetch(
"https://www.gutenberg.org/files/1342/1342-0.txt",
).then((response) => response.text());
const response = await anthropic.chat({
messages: [
{
content:
"You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n",
role: "system",
},
{
content: entireBook,
role: "system",
options: {
cache_control: {
type: "ephemeral",
},
},
},
{
content: "analyze the major themes in Pride and Prejudice.",
role: "user",
},
],
});
console.log(response.message.content);
}
main().catch(console.error);
+5 -5
View File
@@ -1,15 +1,15 @@
{
"name": "@llamaindex/examples",
"private": true,
"version": "0.0.16",
"version": "0.0.14",
"dependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
"@azure/cosmos": "^4.1.1",
"@azure/identity": "^4.4.1",
"@datastax/astra-db-ts": "^1.4.1",
"@llamaindex/core": "^0.4.10",
"@llamaindex/readers": "^1.0.11",
"@llamaindex/workflow": "^0.0.6",
"@llamaindex/core": "^0.4.7",
"@llamaindex/readers": "^1.0.8",
"@llamaindex/workflow": "^0.0.4",
"@notionhq/client": "^2.2.15",
"@pinecone-database/pinecone": "^3.0.2",
"@vercel/postgres": "^0.10.0",
@@ -18,7 +18,7 @@
"commander": "^12.1.0",
"dotenv": "^16.4.5",
"js-tiktoken": "^1.0.14",
"llamaindex": "^0.8.13",
"llamaindex": "^0.8.10",
"mongodb": "^6.7.0",
"pathe": "^1.1.2",
"postgres": "^3.4.4"
-21
View File
@@ -1,26 +1,5 @@
# @llamaindex/autotool
## 5.0.15
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 5.0.14
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 5.0.13
### Patch Changes
- llamaindex@0.8.13
## 5.0.12
### Patch Changes
@@ -1,29 +1,5 @@
# @llamaindex/autotool-01-node-example
## 0.0.58
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
- @llamaindex/autotool@5.0.15
## 0.0.57
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
- @llamaindex/autotool@5.0.14
## 0.0.56
### Patch Changes
- llamaindex@0.8.13
- @llamaindex/autotool@5.0.13
## 0.0.55
### Patch Changes
@@ -13,5 +13,5 @@
"scripts": {
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
},
"version": "0.0.58"
"version": "0.0.55"
}
@@ -1,29 +1,5 @@
# @llamaindex/autotool-02-next-example
## 0.1.102
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
- @llamaindex/autotool@5.0.15
## 0.1.101
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
- @llamaindex/autotool@5.0.14
## 0.1.100
### Patch Changes
- llamaindex@0.8.13
- @llamaindex/autotool@5.0.13
## 0.1.99
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool-02-next-example",
"private": true,
"version": "0.1.102",
"version": "0.1.99",
"scripts": {
"dev": "next dev",
"build": "next build",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool",
"type": "module",
"version": "5.0.15",
"version": "5.0.12",
"description": "auto transpile your JS function to LLM Agent compatible",
"files": [
"dist",
-8
View File
@@ -1,13 +1,5 @@
# @llamaindex/cloud
## 2.0.10
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 2.0.9
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloud",
"version": "2.0.10",
"version": "2.0.9",
"type": "module",
"license": "MIT",
"scripts": {
-8
View File
@@ -1,13 +1,5 @@
# @llamaindex/community
## 0.0.68
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.0.67
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/community",
"description": "Community package for LlamaIndexTS",
"version": "0.0.68",
"version": "0.0.67",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
-7
View File
@@ -1,12 +1,5 @@
# @llamaindex/core
## 0.4.10
### Patch Changes
- a7b0ac3: fix: update tool call llm type
- c69605f: feat: add async support to BaseChatStore and BaseChatStoreMemory
## 0.4.9
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/core",
"type": "module",
"version": "0.4.10",
"version": "0.4.9",
"description": "LlamaIndex Core Module",
"exports": {
"./agent": {
+1 -3
View File
@@ -66,8 +66,6 @@ export abstract class BaseLLM<
export abstract class ToolCallLLM<
AdditionalChatOptions extends object = object,
AdditionalMessageOptions extends
ToolCallLLMMessageOptions = ToolCallLLMMessageOptions,
> extends BaseLLM<AdditionalChatOptions, AdditionalMessageOptions> {
> extends BaseLLM<AdditionalChatOptions, ToolCallLLMMessageOptions> {
abstract supportToolCall: boolean;
}
+3 -3
View File
@@ -71,15 +71,15 @@ export abstract class BaseChatStoreMemory<
return this.chatStore.getMessages(this.chatStoreKey);
}
put(messages: ChatMessage<AdditionalMessageOptions>): void | Promise<void> {
put(messages: ChatMessage<AdditionalMessageOptions>) {
this.chatStore.addMessage(this.chatStoreKey, messages);
}
set(messages: ChatMessage<AdditionalMessageOptions>[]): void | Promise<void> {
set(messages: ChatMessage<AdditionalMessageOptions>[]) {
this.chatStore.setMessages(this.chatStoreKey, messages);
}
reset(): void | Promise<void> {
reset() {
this.chatStore.deleteMessages(this.chatStoreKey);
}
}
@@ -19,7 +19,5 @@ export abstract class BaseChatStore<
): void;
abstract deleteMessages(key: string): void;
abstract deleteMessage(key: string, idx: number): void;
abstract getKeys():
| IterableIterator<string>
| Promise<IterableIterator<string>>;
abstract getKeys(): IterableIterator<string>;
}
-21
View File
@@ -1,26 +1,5 @@
# @llamaindex/experimental
## 0.0.127
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.126
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.125
### Patch Changes
- llamaindex@0.8.13
## 0.0.124
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/experimental",
"description": "Experimental package for LlamaIndexTS",
"version": "0.0.127",
"version": "0.0.124",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
-35
View File
@@ -1,40 +1,5 @@
# llamaindex
## 0.8.15
### Patch Changes
- 3d503cb: Update azure cosmos db
- 5dae534: fix: propagate queryStr to concrete vectorStore
## 0.8.14
### Patch Changes
- 630b425: feat: add Azure CosmosDB NoSql Chat store
## 0.8.13
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/anthropic@0.0.19
- @llamaindex/core@0.4.10
- @llamaindex/cloud@2.0.10
- @llamaindex/node-parser@0.0.11
- @llamaindex/clip@0.0.19
- @llamaindex/deepinfra@0.0.19
- @llamaindex/huggingface@0.0.19
- @llamaindex/ollama@0.0.26
- @llamaindex/openai@0.1.35
- @llamaindex/portkey-ai@0.0.19
- @llamaindex/replicate@0.0.19
- @llamaindex/readers@1.0.11
- @llamaindex/groq@0.0.34
- @llamaindex/vllm@0.0.5
## 0.8.12
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llamaindex",
"version": "0.8.15",
"version": "0.8.12",
"license": "MIT",
"type": "module",
"keywords": [
@@ -18,7 +18,6 @@ import {
type NodeWithScore,
} from "@llamaindex/core/schema";
import type { BaseIndexStore } from "@llamaindex/core/storage/index-store";
import { extractText } from "@llamaindex/core/utils";
import type { ServiceContext } from "../../ServiceContext.js";
import { nodeParserFromSettingsOrContext } from "../../Settings.js";
import { RetrieverQueryEngine } from "../../engines/query/RetrieverQueryEngine.js";
@@ -450,13 +449,8 @@ export class VectorIndexRetriever extends BaseRetriever {
filters?: MetadataFilters,
): Promise<NodeWithScore[]> {
// convert string message to multi-modal format
let queryStr = query;
if (typeof query === "string") {
queryStr = query;
query = [{ type: "text", text: queryStr }];
} else {
queryStr = extractText(query);
query = [{ type: "text", text: query }];
}
// overwrite embed model if specified, otherwise use the one from the vector store
const embedModel = this.index.embedModel ?? vectorStore.embedModel;
@@ -466,7 +460,6 @@ export class VectorIndexRetriever extends BaseRetriever {
const queryEmbedding = await embedModel.getQueryEmbedding(item);
if (queryEmbedding) {
const result = await vectorStore.query({
queryStr,
queryEmbedding,
mode: VectorStoreQueryMode.DEFAULT,
similarityTopK: this.topK[type]!,
@@ -1,345 +0,0 @@
import { CosmosClient, type Container, type Database } from "@azure/cosmos";
import { DefaultAzureCredential, type TokenCredential } from "@azure/identity";
import type {
ChatMessage,
MessageContent,
MessageType,
} from "@llamaindex/core/llms";
import { BaseChatStore } from "@llamaindex/core/storage/chat-store";
import { getEnv } from "@llamaindex/env";
const USER_AGENT_SUFFIX = "llamaindex-cdbnosql-chatstore-javascript";
const DEFAULT_CHAT_DATABASE = "ChatMessagesDB";
const DEFAULT_CHAT_CONTAINER = "ChatMessagesContainer";
const DEFAULT_OFFER_THROUGHPUT = 400;
function parseConnectionString(connectionString: string): {
endpoint: string;
key: string;
} {
const parts = connectionString.split(";");
let endpoint = "";
let accountKey = "";
parts.forEach((part) => {
const [key, value] = part.split("=");
if (key && key.trim() === "AccountEndpoint") {
endpoint = value?.trim() ?? "";
} else if ((key ?? "").trim() === "AccountKey") {
accountKey = value?.trim() ?? "";
}
});
if (!endpoint || !accountKey) {
throw new Error(
"Invalid connection string: missing AccountEndpoint or AccountKey.",
);
}
return { endpoint, key: accountKey };
}
export interface AzureCosmosChatDatabaseProperties {
throughput?: number;
}
export interface AzureCosmosChatContainerProperties {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
export interface AzureCosmosNoSqlChatStoreConfig {
cosmosClient?: CosmosClient;
dbName?: string;
containerName?: string;
userId?: string;
sessionId?: string;
cosmosContainerProperties?: AzureCosmosChatContainerProperties;
cosmosDatabaseProperties?: AzureCosmosChatDatabaseProperties;
ttlInSeconds?: number;
}
export class AzureCosmosNoSqlChatStore<
AdditionalMessageOptions extends object = object,
> extends BaseChatStore<AdditionalMessageOptions> {
private userId: string;
private ttl: number;
private cosmosClient: CosmosClient;
private database!: Database;
private container!: Container;
private initPromise?: Promise<void>;
private dbName: string;
private containerName: string;
private cosmosContainerProperties: AzureCosmosChatContainerProperties;
private cosmosDatabaseProperties: AzureCosmosChatDatabaseProperties;
private initialize: () => Promise<void>;
constructor({
cosmosClient,
dbName = DEFAULT_CHAT_DATABASE,
containerName = DEFAULT_CHAT_CONTAINER,
cosmosContainerProperties = { partitionKey: "/userId" },
cosmosDatabaseProperties = {},
ttlInSeconds = -1,
}: AzureCosmosNoSqlChatStoreConfig) {
super();
if (!cosmosClient) {
throw new Error(
"CosmosClient is required for AzureCosmosDBNoSQLChatStore initialization",
);
}
this.ttl = ttlInSeconds;
this.userId = cosmosContainerProperties.userId || "anonymous";
this.cosmosClient = cosmosClient;
this.dbName = dbName;
this.containerName = containerName;
this.cosmosContainerProperties = cosmosContainerProperties;
this.cosmosDatabaseProperties = cosmosDatabaseProperties;
this.initialize = () => {
if (this.initPromise === undefined) {
this.initPromise = this.init().catch((error) => {
console.error(
"Error during AzureCosmosDBNoSQLChatStore initialization",
error,
);
});
}
return this.initPromise;
};
}
client(): CosmosClient {
return this.cosmosClient;
}
// Asynchronous initialization method to create database and container
private async init(): Promise<void> {
// Set default throughput if not provided
const throughput =
this.cosmosDatabaseProperties?.throughput || DEFAULT_OFFER_THROUGHPUT;
// Create the database if it doesn't exist
const { database } = await this.cosmosClient.databases.createIfNotExists({
id: this.dbName,
throughput,
});
this.database = database;
// Create the container if it doesn't exist
const { container } = await this.database.containers.createIfNotExists({
id: this.containerName,
throughput: this.cosmosContainerProperties?.throughput,
partitionKey: "/userId",
indexingPolicy: this.cosmosContainerProperties?.indexingPolicy,
defaultTtl: this.ttl,
uniqueKeyPolicy: this.cosmosContainerProperties?.uniqueKeyPolicy,
conflictResolutionPolicy:
this.cosmosContainerProperties?.conflictResolutionPolicy,
computedProperties: this.cosmosContainerProperties?.computedProperties,
});
this.container = container;
}
/**
* Static method for creating an instance using a connection string.
* If no connection string is provided, it will attempt to use the env variable `AZURE_COSMOSDB_NOSQL_CONNECTION_STRING` as connection string.
* @returns Instance of AzureCosmosNoSqlKVStore
*/
static fromConnectionString(
config: {
connectionString?: string;
} & AzureCosmosNoSqlChatStoreConfig = {},
): AzureCosmosNoSqlChatStore {
const cosmosConnectionString =
config.connectionString ||
(getEnv("AZURE_COSMOSDB_NOSQL_CONNECTION_STRING") as string);
if (!cosmosConnectionString) {
throw new Error("Azure CosmosDB connection string must be provided");
}
const { endpoint, key } = parseConnectionString(cosmosConnectionString);
const cosmosClient = new CosmosClient({
endpoint,
key,
userAgentSuffix: USER_AGENT_SUFFIX,
});
return new AzureCosmosNoSqlChatStore({
...config,
cosmosClient,
});
}
/**
* Static method for creating an instance using a account endpoint and key.
* If no endpoint and key is provided, it will attempt to use the env variable `AZURE_COSMOSDB_NOSQL_ACCOUNT_ENDPOINT` as enpoint and `AZURE_COSMOSDB_NOSQL_ACCOUNT_KEY` as key.
* @returns Instance of AzureCosmosNoSqlKVStore
*/
static fromAccountAndKey(
config: {
endpoint?: string;
key?: string;
} & AzureCosmosNoSqlChatStoreConfig = {},
): AzureCosmosNoSqlChatStore {
const cosmosEndpoint =
config.endpoint ||
(getEnv("AZURE_COSMOSDB_NOSQL_ACCOUNT_ENDPOINT") as string);
const cosmosKey =
config.key || (getEnv("AZURE_COSMOSDB_NOSQL_ACCOUNT_KEY") as string);
if (!cosmosEndpoint || !cosmosKey) {
throw new Error(
"Azure CosmosDB account endpoint and key must be provided",
);
}
const cosmosClient = new CosmosClient({
endpoint: cosmosEndpoint,
key: cosmosKey,
userAgentSuffix: USER_AGENT_SUFFIX,
});
return new AzureCosmosNoSqlChatStore({
...config,
cosmosClient,
});
}
/**
* Static method for creating an instance using AAD token.
* If no endpoint and credentials are provided, it will attempt to use the env variable `AZURE_COSMOSDB_NOSQL_ACCOUNT_ENDPOINT` as endpoint and use DefaultAzureCredential() as credentials.
* @returns Instance of AzureCosmosNoSqlKVStore
*/
static fromAadToken(
config: {
endpoint?: string;
credential?: TokenCredential;
} & AzureCosmosNoSqlChatStoreConfig = {},
): AzureCosmosNoSqlChatStore {
const cosmosEndpoint =
config.endpoint ||
(getEnv("AZURE_COSMOSDB_NOSQL_CONNECTION_STRING") as string);
if (!cosmosEndpoint) {
throw new Error("Azure CosmosDB account endpoint must be provided");
}
const credentials = config.credential ?? new DefaultAzureCredential();
const cosmosClient = new CosmosClient({
endpoint: cosmosEndpoint,
aadCredentials: credentials,
userAgentSuffix: USER_AGENT_SUFFIX,
});
return new AzureCosmosNoSqlChatStore({
...config,
cosmosClient,
});
}
private convertToChatMessage(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
message: any,
): ChatMessage<AdditionalMessageOptions> {
return {
content: message.content as MessageContent,
role: message.role as MessageType,
options: message.options as AdditionalMessageOptions,
} as ChatMessage<AdditionalMessageOptions>;
}
private convertToCosmosMessage(
message: ChatMessage<AdditionalMessageOptions>,
): // eslint-disable-next-line @typescript-eslint/no-explicit-any
any {
return {
content: message.content,
role: message.role,
options: message.options,
};
}
/**
* Set messages for a given key.
*/
async setMessages(
key: string,
messages: ChatMessage<AdditionalMessageOptions>[],
): Promise<void> {
await this.initialize();
const inputMessages = messages.map(this.convertToCosmosMessage);
await this.container.items.upsert({
id: key,
messages: inputMessages,
userId: this.userId,
});
}
/**
* Get messages for a given key.
*/
async getMessages(
key: string,
): Promise<ChatMessage<AdditionalMessageOptions>[]> {
await this.initialize();
const res = await this.container.item(key, this.userId).read();
const messageHistory = res?.resource?.messages ?? [];
const result = messageHistory.map(this.convertToChatMessage);
return result;
}
/**
* Add a message for a given key.
*/
async addMessage(
key: string,
message: ChatMessage<AdditionalMessageOptions>,
idx?: number,
): Promise<void> {
await this.initialize();
const res = await this.container.item(key, this.userId).read();
const messageHistory = res?.resource?.messages ?? [];
if (idx === undefined) {
messageHistory.push(this.convertToCosmosMessage(message));
} else {
messageHistory.splice(idx, 0, this.convertToCosmosMessage(message));
}
await this.setMessages(key, messageHistory);
}
/**
* Deletes all messages for a given key.
*/
async deleteMessages(key: string): Promise<void> {
await this.initialize();
try {
await this.container.item(key, this.userId).delete();
// eslint-disable-next-line no-empty
} catch (e) {}
}
/**
* Deletes one message at idx index for a given key.
*/
async deleteMessage(key: string, idx: number): Promise<void> {
await this.initialize();
const res = await this.container.item(key, this.userId).read();
const messageHistory = res?.resource?.messages ?? [];
if (idx >= 0 && idx < messageHistory.length) {
messageHistory.splice(idx, 1);
await this.setMessages(key, messageHistory);
}
}
/**
* Get all keys.
*/
async getKeys(): Promise<IterableIterator<string>> {
await this.initialize();
const result = await this.container.items
.query("Select c.id from c")
.fetchAll();
const keys = result.resources.map((res: { id: string }) => res.id);
function* keyGenerator(): IterableIterator<string> {
for (const key of keys) {
yield key;
}
}
return keyGenerator();
}
}
-1
View File
@@ -2,7 +2,6 @@ export * from "@llamaindex/core/storage/chat-store";
export * from "@llamaindex/core/storage/doc-store";
export * from "@llamaindex/core/storage/index-store";
export * from "@llamaindex/core/storage/kv-store";
export * from "./chatStore/AzureCosmosNoSqlChatStore.js";
export * from "./docStore/AzureCosmosNoSqlDocumentStore.js";
export { PostgresDocumentStore } from "./docStore/PostgresDocumentStore.js";
export { SimpleDocumentStore } from "./docStore/SimpleDocumentStore.js";
@@ -3,7 +3,7 @@ import { Container, CosmosClient, Database } from "@azure/cosmos";
import { DefaultAzureCredential, type TokenCredential } from "@azure/identity";
import { BaseKVStore } from "@llamaindex/core/storage/kv-store";
import { getEnv } from "@llamaindex/env";
const USER_AGENT_SUFFIX = "llamaindex-cdbnosql-kvstore-javascript";
const USER_AGENT_SUFFIX = "LlamaIndex-CDBNoSQL-KVStore-JavaScript";
const DEFAULT_CHAT_DATABASE = "KVStoreDB";
const DEFAULT_CHAT_CONTAINER = "KVStoreContainer";
const DEFAULT_OFFER_THROUGHPUT = 400;
@@ -82,7 +82,7 @@ export class AzureCosmosNoSqlKVStore extends BaseKVStore {
super();
if (!cosmosClient) {
throw new Error(
"CosmosClient is required for AzureCosmosDBNoSQLKVStore initialization",
"CosmosClient is required for AzureCosmosDBNoSQLVectorStore initialization",
);
}
this.cosmosClient = cosmosClient;
@@ -56,7 +56,7 @@ export interface AzureCosmosDBNoSQLConfig
readonly idKey?: string;
}
const USER_AGENT_SUFFIX = "llamaindex-cdbnosql-vectorstore-javascript";
const USER_AGENT_SUFFIX = "LlamaIndex-CDBNoSQL-VectorStore-JavaScript";
const DEFAULT_VECTOR_EMBEDDING_POLICY = {
vectorEmbeddings: [
-8
View File
@@ -1,13 +1,5 @@
# @llamaindex/node-parser
## 0.0.11
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.0.10
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/node-parser",
"version": "0.0.11",
"version": "0.0.10",
"description": "Node parser for LlamaIndex",
"type": "module",
"exports": {
@@ -1,14 +1,5 @@
# @llamaindex/anthropic
## 0.0.19
### Patch Changes
- a7b0ac3: feat(anthropic): support prompt caching
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.0.18
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/anthropic",
"description": "Anthropic Adapter for LlamaIndex",
"version": "0.0.19",
"version": "0.0.18",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -33,7 +33,7 @@
"bunchee": "5.6.1"
},
"dependencies": {
"@anthropic-ai/sdk": "0.32.1",
"@anthropic-ai/sdk": "0.27.1",
"@llamaindex/core": "workspace:*",
"@llamaindex/env": "workspace:*",
"remeda": "^2.12.0"
+23 -76
View File
@@ -1,9 +1,5 @@
import type { ClientOptions } from "@anthropic-ai/sdk";
import { Anthropic as SDKAnthropic } from "@anthropic-ai/sdk";
import type {
BetaCacheControlEphemeral,
BetaTextBlockParam,
} from "@anthropic-ai/sdk/resources/beta/index";
import type {
TextBlock,
TextBlockParam,
@@ -12,7 +8,6 @@ import type {
ImageBlockParam,
MessageCreateParamsNonStreaming,
MessageParam,
Model,
Tool,
ToolResultBlockParam,
ToolUseBlock,
@@ -80,9 +75,6 @@ export const ALL_AVAILABLE_ANTHROPIC_LEGACY_MODELS = {
"claude-2.1": {
contextWindow: 200000,
},
"claude-2.0": {
contextWindow: 100000,
},
"claude-instant-1.2": {
contextWindow: 100000,
},
@@ -90,30 +82,18 @@ export const ALL_AVAILABLE_ANTHROPIC_LEGACY_MODELS = {
export const ALL_AVAILABLE_V3_MODELS = {
"claude-3-opus": { contextWindow: 200000 },
"claude-3-opus-latest": { contextWindow: 200000 },
"claude-3-opus-20240229": { contextWindow: 200000 },
"claude-3-sonnet": { contextWindow: 200000 },
"claude-3-sonnet-20240229": { contextWindow: 200000 },
"claude-3-haiku": { contextWindow: 200000 },
"claude-3-haiku-20240307": { contextWindow: 200000 },
};
export const ALL_AVAILABLE_V3_5_MODELS = {
"claude-3-5-sonnet": { contextWindow: 200000 },
"claude-3-5-sonnet-20241022": { contextWindow: 200000 },
"claude-3-5-sonnet-20240620": { contextWindow: 200000 },
"claude-3-5-sonnet-latest": { contextWindow: 200000 },
"claude-3-5-haiku": { contextWindow: 200000 },
"claude-3-5-haiku-latest": { contextWindow: 200000 },
"claude-3-5-haiku-20241022": { contextWindow: 200000 },
};
export const ALL_AVAILABLE_ANTHROPIC_MODELS = {
...ALL_AVAILABLE_ANTHROPIC_LEGACY_MODELS,
...ALL_AVAILABLE_V3_MODELS,
...ALL_AVAILABLE_V3_5_MODELS,
} satisfies {
[key in Model]: { contextWindow: number };
};
const AVAILABLE_ANTHROPIC_MODELS_WITHOUT_DATE: { [key: string]: string } = {
@@ -124,16 +104,10 @@ const AVAILABLE_ANTHROPIC_MODELS_WITHOUT_DATE: { [key: string]: string } = {
} as { [key in keyof typeof ALL_AVAILABLE_ANTHROPIC_MODELS]: string };
export type AnthropicAdditionalChatOptions = object;
export type AnthropicToolCallLLMMessageOptions = ToolCallLLMMessageOptions & {
cache_control?: BetaCacheControlEphemeral | null;
};
export class Anthropic extends ToolCallLLM<
AnthropicAdditionalChatOptions,
AnthropicToolCallLLMMessageOptions
> {
export class Anthropic extends ToolCallLLM<AnthropicAdditionalChatOptions> {
// Per completion Anthropic params
model: keyof typeof ALL_AVAILABLE_ANTHROPIC_MODELS | ({} & string);
model: keyof typeof ALL_AVAILABLE_ANTHROPIC_MODELS;
temperature: number;
topP: number;
maxTokens?: number | undefined;
@@ -173,12 +147,7 @@ export class Anthropic extends ToolCallLLM<
temperature: this.temperature,
topP: this.topP,
maxTokens: this.maxTokens,
contextWindow:
this.model in ALL_AVAILABLE_ANTHROPIC_MODELS
? ALL_AVAILABLE_ANTHROPIC_MODELS[
this.model as keyof typeof ALL_AVAILABLE_ANTHROPIC_MODELS
].contextWindow
: 200000,
contextWindow: ALL_AVAILABLE_ANTHROPIC_MODELS[this.model].contextWindow,
tokenizer: undefined,
};
}
@@ -322,74 +291,56 @@ export class Anthropic extends ToolCallLLM<
chat(
params: LLMChatParamsStreaming<
AnthropicAdditionalChatOptions,
AnthropicToolCallLLMMessageOptions
ToolCallLLMMessageOptions
>,
): Promise<
AsyncIterable<ChatResponseChunk<AnthropicToolCallLLMMessageOptions>>
>;
): Promise<AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>>>;
chat(
params: LLMChatParamsNonStreaming<
AnthropicAdditionalChatOptions,
AnthropicToolCallLLMMessageOptions
ToolCallLLMMessageOptions
>,
): Promise<ChatResponse<AnthropicToolCallLLMMessageOptions>>;
): Promise<ChatResponse<ToolCallLLMMessageOptions>>;
@wrapLLMEvent
async chat(
params:
| LLMChatParamsNonStreaming<
AnthropicAdditionalChatOptions,
AnthropicToolCallLLMMessageOptions
ToolCallLLMMessageOptions
>
| LLMChatParamsStreaming<
AnthropicAdditionalChatOptions,
AnthropicToolCallLLMMessageOptions
ToolCallLLMMessageOptions
>,
): Promise<
| ChatResponse<AnthropicToolCallLLMMessageOptions>
| AsyncIterable<ChatResponseChunk<AnthropicToolCallLLMMessageOptions>>
| ChatResponse<ToolCallLLMMessageOptions>
| AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>>
> {
let { messages } = params;
const { stream, tools } = params;
let systemPrompt: string | Array<BetaTextBlockParam> | null = null;
let systemPrompt: string | null = null;
const systemMessages = messages.filter(
(message) => message.role === "system",
);
if (systemMessages.length > 0) {
systemPrompt = systemMessages.map((message) =>
message.options && "cache_control" in message.options
? {
type: "text",
text: extractText(message.content),
cache_control: message.options.cache_control,
}
: {
type: "text",
text: extractText(message.content),
},
);
systemPrompt = systemMessages
.map((message) => message.content)
.join("\n");
messages = messages.filter((message) => message.role !== "system");
}
const beta =
systemPrompt?.find((message) => "cache_control" in message) !== undefined;
// case: Non-streaming
let anthropic = this.session.anthropic;
if (beta) {
// @ts-expect-error type casting
anthropic = anthropic.beta.promptCaching;
}
// case: Streaming
if (stream) {
if (tools) {
console.error("Tools are not supported in streaming mode");
}
return this.streamChat(messages, systemPrompt, anthropic);
return this.streamChat(messages, systemPrompt);
}
// case: Non-streaming
const anthropic = this.session.anthropic;
if (tools) {
const params: MessageCreateParamsNonStreaming = {
@@ -427,10 +378,7 @@ export class Anthropic extends ToolCallLLM<
toolCall: toolUseBlock.map((block) => ({
id: block.id,
name: block.name,
input:
typeof block.input === "object"
? JSON.stringify(block.input)
: `${block.input}`,
input: block.input,
})),
}
: {},
@@ -463,11 +411,10 @@ export class Anthropic extends ToolCallLLM<
}
protected async *streamChat(
messages: ChatMessage<AnthropicToolCallLLMMessageOptions>[],
systemPrompt: string | Array<BetaTextBlockParam> | null,
anthropic: SDKAnthropic,
): AsyncIterable<ChatResponseChunk<AnthropicToolCallLLMMessageOptions>> {
const stream = await anthropic.messages.create({
messages: ChatMessage<ToolCallLLMMessageOptions>[],
systemPrompt?: string | null,
): AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>> {
const stream = await this.session.anthropic.messages.create({
model: this.getModelName(this.model),
messages: this.formatMessages(messages),
max_tokens: this.maxTokens ?? 4096,
-9
View File
@@ -1,14 +1,5 @@
# @llamaindex/clip
## 0.0.19
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
- @llamaindex/openai@0.1.35
## 0.0.18
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/clip",
"description": "Clip Embedding Adapter for LlamaIndex",
"version": "0.0.19",
"version": "0.0.18",
"type": "module",
"types": "dist/index.d.ts",
"main": "dist/index.cjs",
@@ -1,14 +1,5 @@
# @llamaindex/deepinfra
## 0.0.19
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
- @llamaindex/openai@0.1.35
## 0.0.18
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/deepinfra",
"description": "Deepinfra Adapter for LlamaIndex",
"version": "0.0.19",
"version": "0.0.18",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
-6
View File
@@ -1,11 +1,5 @@
# @llamaindex/groq
## 0.0.34
### Patch Changes
- @llamaindex/openai@0.1.35
## 0.0.33
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/groq",
"description": "Groq Adapter for LlamaIndex",
"version": "0.0.34",
"version": "0.0.33",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -1,14 +1,5 @@
# @llamaindex/huggingface
## 0.0.19
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
- @llamaindex/openai@0.1.35
## 0.0.18
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/huggingface",
"description": "Huggingface Adapter for LlamaIndex",
"version": "0.0.19",
"version": "0.0.18",
"type": "module",
"types": "dist/index.d.ts",
"main": "dist/index.cjs",
-8
View File
@@ -1,13 +1,5 @@
# @llamaindex/ollama
## 0.0.26
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.0.25
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/ollama",
"description": "Ollama Adapter for LlamaIndex",
"version": "0.0.26",
"version": "0.0.25",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
-8
View File
@@ -1,13 +1,5 @@
# @llamaindex/openai
## 0.1.35
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.1.34
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/openai",
"description": "OpenAI Adapter for LlamaIndex",
"version": "0.1.35",
"version": "0.1.34",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -1,13 +1,5 @@
# @llamaindex/portkey-ai
## 0.0.19
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.0.18
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/portkey-ai",
"description": "Portkey Adapter for LlamaIndex",
"version": "0.0.19",
"version": "0.0.18",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
@@ -1,13 +1,5 @@
# @llamaindex/replicate
## 0.0.19
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 0.0.18
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/replicate",
"description": "Replicate Adapter for LlamaIndex",
"version": "0.0.19",
"version": "0.0.18",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
-6
View File
@@ -1,11 +1,5 @@
# @llamaindex/vllm
## 0.0.5
### Patch Changes
- @llamaindex/openai@0.1.35
## 0.0.4
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/vllm",
"description": "vLLM Adapter for LlamaIndex",
"version": "0.0.5",
"version": "0.0.4",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
-8
View File
@@ -1,13 +1,5 @@
# @llamaindex/readers
## 1.0.11
### Patch Changes
- Updated dependencies [a7b0ac3]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
## 1.0.10
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/readers",
"description": "LlamaIndex Readers",
"version": "1.0.11",
"version": "1.0.10",
"type": "module",
"exports": {
"./node/hook": "./node/dist/hook.js",
-13
View File
@@ -1,18 +1,5 @@
# @llamaindex/workflow
## 0.0.6
### Patch Changes
- ee20c44: feat(workflow): allow send event with no output
## 0.0.5
### Patch Changes
- ea92b69: fix: output event check
- fadc8b8: feat: recoverable context with error handling
## 0.0.4
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/workflow",
"description": "Workflow API",
"version": "0.0.6",
"version": "0.0.4",
"type": "module",
"types": "dist/index.d.ts",
"module": "dist/index.js",
+95 -102
View File
@@ -13,18 +13,19 @@ export type StepHandler<
AnyWorkflowEventConstructor | StartEventConstructor,
...(AnyWorkflowEventConstructor | StopEventConstructor)[],
] = [AnyWorkflowEventConstructor | StartEventConstructor],
Out extends (AnyWorkflowEventConstructor | StopEventConstructor)[] = [],
Out extends [
AnyWorkflowEventConstructor | StartEventConstructor,
...(AnyWorkflowEventConstructor | StopEventConstructor)[],
] = [AnyWorkflowEventConstructor | StopEventConstructor],
> = (
context: HandlerContext<Data>,
...events: {
[K in keyof Inputs]: InstanceType<Inputs[K]>;
}
) => Promise<
Out extends []
? void
: {
[K in keyof Out]: InstanceType<Out[K]>;
}[number]
{
[K in keyof Out]: InstanceType<Out[K]>;
}[number]
>;
export type ReadonlyStepMap<Data> = ReadonlyMap<
@@ -274,7 +275,7 @@ export class WorkflowContext<Start = string, Stop = string, Data = unknown>
*/
#createStreamEvents(): AsyncIterableIterator<WorkflowEvent<unknown>> {
const isPendingEvents = new WeakSet<WorkflowEvent<unknown>>();
const pendingTasks = new Set<Promise<WorkflowEvent<unknown> | void>>();
const pendingTasks = new Set<Promise<WorkflowEvent<unknown>>>();
const enqueuedEvents = new Set<WorkflowEvent<unknown>>();
const stream = new ReadableStream<WorkflowEvent<unknown>>({
start: async (controller) => {
@@ -324,104 +325,102 @@ export class WorkflowContext<Start = string, Stop = string, Data = unknown>
}
const [steps, inputsMap, outputsMap] =
this.#getStepFunction(event);
const nextEventPromises: Promise<WorkflowEvent<unknown> | void>[] =
[...steps]
.map((step) => {
const inputs = [...(inputsMap.get(step) ?? [])];
const acceptableInputs: WorkflowEvent<unknown>[] =
this.#pendingInputQueue.filter((event) =>
inputs.some((input) => event instanceof input),
);
const events: WorkflowEvent<unknown>[] = flattenEvents(
inputs,
[event, ...acceptableInputs],
const nextEventPromises: Promise<WorkflowEvent<unknown>>[] = [
...steps,
]
.map((step) => {
const inputs = [...(inputsMap.get(step) ?? [])];
const acceptableInputs: WorkflowEvent<unknown>[] =
this.#pendingInputQueue.filter((event) =>
inputs.some((input) => event instanceof input),
);
// remove the event from the queue, in case of infinite loop
events.forEach((event) => {
const protocolIdx = this.#queue.findIndex(
(protocol) =>
protocol.type === "event" &&
protocol.event === event,
);
if (protocolIdx !== -1) {
this.#queue.splice(protocolIdx, 1);
}
});
if (events.length !== inputs.length) {
if (this.#verbose) {
console.log(
`Not enough inputs for step ${step.name}, waiting for more events`,
);
}
// not enough to run the step, push back to the queue
this.#sendEvent(event);
isPendingEvents.add(event);
return null;
}
if (isPendingEvents.has(event)) {
isPendingEvents.delete(event);
const events: WorkflowEvent<unknown>[] = flattenEvents(
inputs,
[event, ...acceptableInputs],
);
// remove the event from the queue, in case of infinite loop
events.forEach((event) => {
const protocolIdx = this.#queue.findIndex(
(protocol) =>
protocol.type === "event" &&
protocol.event === event,
);
if (protocolIdx !== -1) {
this.#queue.splice(protocolIdx, 1);
}
});
if (events.length !== inputs.length) {
if (this.#verbose) {
console.log(
`Running step ${step.name} with inputs ${events}`,
`Not enough inputs for step ${step.name}, waiting for more events`,
);
}
const data = this.data;
return (step as StepHandler<Data>)
.call(
null,
{
get data() {
return data;
},
sendEvent: this.#sendEvent,
requireEvent: this.#requireEvent,
// not enough to run the step, push back to the queue
this.#sendEvent(event);
isPendingEvents.add(event);
return null;
}
if (isPendingEvents.has(event)) {
isPendingEvents.delete(event);
}
if (this.#verbose) {
console.log(
`Running step ${step.name} with inputs ${events}`,
);
}
const data = this.data;
return (step as StepHandler<Data>)
.call(
null,
{
get data() {
return data;
},
// @ts-expect-error IDK why
...events.sort((a, b) => {
const aIndex = inputs.indexOf(
a.constructor as AnyWorkflowEventConstructor,
sendEvent: this.#sendEvent,
requireEvent: this.#requireEvent,
},
// @ts-expect-error IDK why
...events.sort((a, b) => {
const aIndex = inputs.indexOf(
a.constructor as AnyWorkflowEventConstructor,
);
const bIndex = inputs.indexOf(
b.constructor as AnyWorkflowEventConstructor,
);
return aIndex - bIndex;
}),
)
.then((nextEvent) => {
if (this.#verbose) {
console.log(
`Step ${step.name} completed, next event is ${nextEvent}`,
);
}
const outputs = outputsMap.get(step) ?? [];
if (
!outputs.some(
(output) => nextEvent.constructor === output,
)
) {
if (this.#strict) {
const error = Error(
`Step ${step.name} returned an unexpected output event ${nextEvent}`,
);
const bIndex = inputs.indexOf(
b.constructor as AnyWorkflowEventConstructor,
);
return aIndex - bIndex;
}),
)
.then((nextEvent: void | WorkflowEvent<unknown>) => {
if (nextEvent === undefined) {
return;
}
if (this.#verbose) {
console.log(
`Step ${step.name} completed, next event is ${nextEvent}`,
controller.error(error);
} else {
console.warn(
`Step ${step.name} returned an unexpected output event ${nextEvent}`,
);
}
const outputs = outputsMap.get(step) ?? [];
if (
!outputs.some(
(output) => nextEvent.constructor === output,
)
) {
if (this.#strict) {
const error = Error(
`Step ${step.name} returned an unexpected output event ${nextEvent}`,
);
controller.error(error);
} else {
console.warn(
`Step ${step.name} returned an unexpected output event ${nextEvent}`,
);
}
}
if (!(nextEvent instanceof StopEvent)) {
this.#pendingInputQueue.unshift(nextEvent);
this.#sendEvent(nextEvent);
}
return nextEvent;
});
})
.filter((promise) => promise !== null);
}
if (!(nextEvent instanceof StopEvent)) {
this.#pendingInputQueue.unshift(nextEvent);
this.#sendEvent(nextEvent);
}
return nextEvent;
});
})
.filter((promise) => promise !== null);
nextEventPromises.forEach((promise) => {
pendingTasks.add(promise);
promise
@@ -434,9 +433,6 @@ export class WorkflowContext<Start = string, Stop = string, Data = unknown>
});
Promise.race(nextEventPromises)
.then((fastestNextEvent) => {
if (fastestNextEvent === undefined) {
return;
}
if (!enqueuedEvents.has(fastestNextEvent)) {
controller.enqueue(fastestNextEvent);
enqueuedEvents.add(fastestNextEvent);
@@ -445,10 +441,7 @@ export class WorkflowContext<Start = string, Stop = string, Data = unknown>
})
.then(async (fastestNextEvent) =>
Promise.all(nextEventPromises).then((nextEvents) => {
const events = nextEvents.filter(
(event) => event !== undefined,
);
for (const nextEvent of events) {
for (const nextEvent of nextEvents) {
// do not enqueue the same event twice
if (fastestNextEvent !== nextEvent) {
if (!enqueuedEvents.has(nextEvent)) {
+7 -6
View File
@@ -57,7 +57,10 @@ export class Workflow<ContextData, Start, Stop> {
AnyWorkflowEventConstructor | StartEventConstructor,
...(AnyWorkflowEventConstructor | StopEventConstructor)[],
],
const Out extends (AnyWorkflowEventConstructor | StopEventConstructor)[],
const Out extends [
AnyWorkflowEventConstructor | StopEventConstructor,
...(AnyWorkflowEventConstructor | StopEventConstructor)[],
],
>(
parameters: StepParameters<In, Out>,
stepFn: (
@@ -66,11 +69,9 @@ export class Workflow<ContextData, Start, Stop> {
[K in keyof In]: InstanceType<In[K]>;
}
) => Promise<
Out extends []
? void
: {
[K in keyof Out]: InstanceType<Out[K]>;
}[number]
{
[K in keyof Out]: InstanceType<Out[K]>;
}[number]
>,
): this {
const { inputs, outputs } = parameters;
+1142 -203
View File
File diff suppressed because it is too large Load Diff
-39
View File
@@ -1,44 +1,5 @@
# @llamaindex/unit-test
## 0.0.25
### Patch Changes
- Updated dependencies [3d503cb]
- Updated dependencies [5dae534]
- llamaindex@0.8.15
## 0.0.24
### Patch Changes
- Updated dependencies [630b425]
- llamaindex@0.8.14
## 0.0.23
### Patch Changes
- ee20c44: feat(workflow): allow send event with no output
- Updated dependencies [a7b0ac3]
- Updated dependencies [ee20c44]
- Updated dependencies [c69605f]
- @llamaindex/core@0.4.10
- @llamaindex/workflow@0.0.6
- llamaindex@0.8.13
- @llamaindex/cloud@2.0.10
- @llamaindex/node-parser@0.0.11
- @llamaindex/openai@0.1.35
- @llamaindex/readers@1.0.11
## 0.0.22
### Patch Changes
- Updated dependencies [ea92b69]
- Updated dependencies [fadc8b8]
- @llamaindex/workflow@0.0.5
## 0.0.21
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/unit-test",
"private": true,
"version": "0.0.25",
"version": "0.0.21",
"type": "module",
"scripts": {
"test": "vitest run"
-15
View File
@@ -531,21 +531,6 @@ describe("workflow basic", () => {
const result = await myWorkflow.run("start");
expect(result.data).toBe("query result");
});
test("allow output with send event", async () => {
const myFlow = new Workflow<unknown, string, string>({ verbose: true });
myFlow.addStep(
{
inputs: [StartEvent<string>],
outputs: [],
},
async (context, ev) => {
context.sendEvent(new StopEvent(`Hello ${ev.data}!`));
},
);
const result = myFlow.run("world");
expect((await result).data).toBe("Hello world!");
});
});
describe("workflow event loop", () => {