Compare commits

...

7 Commits

Author SHA1 Message Date
github-actions[bot] 2065a16a07 Release 0.8.15 (#1494)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-15 11:27:52 -08:00
Wassim Chegham 5dae534f8d fix: propagate queryStr to concrete vectorStore (#1495)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-11-15 11:16:32 -08:00
Aman Rao 3d503cb810 chore: update azure cosmos db (#1484)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-11-15 00:55:32 -08:00
Thuc Pham daf8522bec feat: use mock llm (#1492) 2024-11-15 14:50:49 +08:00
github-actions[bot] 223f3136b4 Release 0.8.14 (#1491)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-14 21:49:37 -08:00
Thuc Pham c6bad7d951 docs(next): chat UI with rsc example (#1481)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-11-14 21:33:30 -08:00
Aman Rao 630b425545 feat: add Azure CosmosDB NoSql Chat store (#1490)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-11-14 21:30:55 -08:00
44 changed files with 895 additions and 52 deletions
+15
View File
@@ -1,5 +1,20 @@
# 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.118",
"version": "0.0.120",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
+15
View File
@@ -1,5 +1,20 @@
# @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
+2
View File
@@ -6,6 +6,7 @@ const withMDX = createMDX();
const config = {
reactStrictMode: true,
transpilePackages: ["monaco-editor"],
serverExternalPackages: ["@huggingface/transformers"],
webpack: (config, { isServer }) => {
if (Array.isArray(config.target) && config.target.includes("web")) {
config.target = ["web", "es2020"];
@@ -26,6 +27,7 @@ const config = {
}),
);
}
config.resolve.alias["replicate"] = false;
return config;
},
};
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/doc",
"version": "0.0.16",
"version": "0.0.18",
"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.5",
"@llamaindex/chat-ui": "0.0.8",
"@llamaindex/cloud": "workspace:*",
"@llamaindex/core": "workspace:*",
"@llamaindex/node-parser": "workspace:*",
+4 -1
View File
@@ -1,7 +1,10 @@
import { llm } from "@/lib/utils";
import { LlamaIndexAdapter, type Message } from "ai";
import { SimpleChatEngine, type ChatMessage } from "llamaindex";
import { Settings, 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
@@ -1,8 +0,0 @@
"use client";
import { ChatSection } from "@llamaindex/chat-ui";
import { useChat } from "ai/react";
export const ChatDemo = () => {
const handler = useChat();
return <ChatSection handler={handler} />;
};
@@ -0,0 +1,16 @@
"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>
);
};
@@ -0,0 +1,57 @@
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,
};
},
},
});
@@ -0,0 +1,33 @@
"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>
);
};
@@ -0,0 +1,8 @@
import { AI } from "./ai-action";
import { ChatSectionRSC } from "./chat-section";
export const ChatDemoRSC = () => (
<AI>
<ChatSectionRSC />
</AI>
);
@@ -0,0 +1,41 @@
"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,
};
}
@@ -1,8 +1,8 @@
---
title: Chat-UI
description: Use chat-ui to add a chat interface to your LlamaIndexTS application.
title: Using API Route
description: Chat interface for your LlamaIndexTS application using API Route
---
import { ChatDemo } from '../../../../components/demo/chat';
import { ChatDemo } from '../../../../../components/demo/chat/api/demo';
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.tsx",
"file": "./src/components/demo/chat/api/demo.tsx",
"codeblock": true
}
```
@@ -37,6 +37,7 @@ 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:
@@ -0,0 +1,6 @@
{
"title": "Chat-UI",
"description": "Use chat-ui to add a chat interface to your LlamaIndexTS application.",
"defaultOpen": false,
"pages": ["chat", "rsc"]
}
@@ -0,0 +1,68 @@
---
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.
+30 -2
View File
@@ -1,6 +1,34 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
import { clsx, type ClassValue } from "clsx";
import { LLM, LLMMetadata } from "llamaindex";
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,5 +1,20 @@
# @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
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.109",
"version": "0.0.111",
"type": "module",
"private": true,
"scripts": {
+15
View File
@@ -1,5 +1,20 @@
# @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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.109",
"version": "0.1.111",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,20 @@
# 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
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.108",
"version": "0.1.110",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,20 @@
# @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
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.0.90",
"version": "0.0.92",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,20 @@
# @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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.109",
"version": "0.0.111",
"type": "module",
"private": true,
"scripts": {
+15
View File
@@ -1,5 +1,20 @@
# @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
@@ -1,5 +1,22 @@
# @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
@@ -13,5 +13,5 @@
"scripts": {
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
},
"version": "0.0.56"
"version": "0.0.58"
}
@@ -1,5 +1,22 @@
# @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
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool-02-next-example",
"private": true,
"version": "0.1.100",
"version": "0.1.102",
"scripts": {
"dev": "next dev",
"build": "next build",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool",
"type": "module",
"version": "5.0.13",
"version": "5.0.15",
"description": "auto transpile your JS function to LLM Agent compatible",
"files": [
"dist",
+15
View File
@@ -1,5 +1,20 @@
# @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
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/experimental",
"description": "Experimental package for LlamaIndexTS",
"version": "0.0.125",
"version": "0.0.127",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
+13
View File
@@ -1,5 +1,18 @@
# 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llamaindex",
"version": "0.8.13",
"version": "0.8.15",
"license": "MIT",
"type": "module",
"keywords": [
@@ -18,6 +18,7 @@ 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";
@@ -449,8 +450,13 @@ export class VectorIndexRetriever extends BaseRetriever {
filters?: MetadataFilters,
): Promise<NodeWithScore[]> {
// convert string message to multi-modal format
let queryStr = query;
if (typeof query === "string") {
query = [{ type: "text", text: query }];
queryStr = query;
query = [{ type: "text", text: queryStr }];
} else {
queryStr = extractText(query);
}
// overwrite embed model if specified, otherwise use the one from the vector store
const embedModel = this.index.embedModel ?? vectorStore.embedModel;
@@ -460,6 +466,7 @@ 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]!,
@@ -0,0 +1,345 @@
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,6 +2,7 @@ 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 AzureCosmosDBNoSQLVectorStore initialization",
"CosmosClient is required for AzureCosmosDBNoSQLKVStore 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: [
+57 -19
View File
@@ -127,8 +127,8 @@ importers:
specifier: ^10.1.0
version: 10.1.0(react@18.3.1)
'@llamaindex/chat-ui':
specifier: 0.0.5
version: 0.0.5(@types/react-dom@18.3.1)(@types/react@18.3.12)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
specifier: 0.0.8
version: 0.0.8(@types/react-dom@18.3.1)(@types/react@18.3.12)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@llamaindex/cloud':
specifier: workspace:*
version: link:../../packages/cloud
@@ -173,10 +173,10 @@ importers:
version: 1.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@vercel/functions':
specifier: ^1.5.0
version: 1.5.0(@aws-sdk/credential-provider-web-identity@3.679.0(@aws-sdk/client-sts@3.682.0))
version: 1.5.0(@aws-sdk/credential-provider-web-identity@3.679.0)
ai:
specifier: ^3.4.31
version: 3.4.31(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
version: 3.4.31(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
class-variance-authority:
specifier: ^0.7.0
version: 0.7.0
@@ -257,7 +257,7 @@ importers:
version: 1.22.2
shiki-magic-move:
specifier: ^0.5.0
version: 0.5.0(react@18.3.1)(shiki@1.22.2)(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))
version: 0.5.0(react@18.3.1)(shiki@1.22.2)(vue@3.5.12(typescript@5.6.3))
swr:
specifier: ^2.2.5
version: 2.2.5(react@18.3.1)
@@ -428,7 +428,7 @@ importers:
dependencies:
ai:
specifier: ^3.3.21
version: 3.4.31(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
version: 3.4.31(openai@4.69.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
llamaindex:
specifier: workspace:*
version: link:../../../packages/llamaindex
@@ -606,7 +606,7 @@ importers:
version: 2.4.9
chromadb:
specifier: ^1.8.1
version: 1.9.2(cohere-ai@7.14.0(encoding@0.1.13))(encoding@0.1.13)(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
version: 1.9.2(cohere-ai@7.14.0(encoding@0.1.13))(encoding@0.1.13)(openai@4.69.0(encoding@0.1.13))
commander:
specifier: ^12.1.0
version: 12.1.0
@@ -738,7 +738,7 @@ importers:
version: 1.1.0(@types/react@18.3.12)(react@18.3.1)
ai:
specifier: ^3.3.21
version: 3.4.31(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
version: 3.4.31(openai@4.69.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
class-variance-authority:
specifier: ^0.7.0
version: 0.7.0
@@ -3755,8 +3755,8 @@ packages:
'@leichtgewicht/ip-codec@2.0.5':
resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==}
'@llamaindex/chat-ui@0.0.5':
resolution: {integrity: sha512-nGlhtAeIlVBtHAsCtBN5f+/iJpIHQ7uFf43ebye/wATf5tT12HUl3tP5O/+XC7nyXXwByjk5KAEN+hk3aC1Cug==}
'@llamaindex/chat-ui@0.0.8':
resolution: {integrity: sha512-yTWgxDzJD6F8w17CNIIJkSBE+hyd+WRqhF6lSElqo3k7CQyhtYr8cOD7cS6K8gBqaI3Xha5EPqvqV0+enJA0Mg==}
peerDependencies:
react: ^18.2.0
@@ -16534,7 +16534,7 @@ snapshots:
'@leichtgewicht/ip-codec@2.0.5': {}
'@llamaindex/chat-ui@0.0.5(@types/react-dom@18.3.1)(@types/react@18.3.12)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@llamaindex/chat-ui@0.0.8(@types/react-dom@18.3.1)(@types/react@18.3.12)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@llamaindex/pdf-viewer': 1.2.0(@types/react@18.3.12)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-collapsible': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -18616,7 +18616,7 @@ snapshots:
'@upstash/vector@1.1.7': {}
'@vercel/functions@1.5.0(@aws-sdk/credential-provider-web-identity@3.679.0(@aws-sdk/client-sts@3.682.0))':
'@vercel/functions@1.5.0(@aws-sdk/credential-provider-web-identity@3.679.0)':
optionalDependencies:
'@aws-sdk/credential-provider-web-identity': 3.679.0(@aws-sdk/client-sts@3.682.0)
@@ -18894,7 +18894,7 @@ snapshots:
clean-stack: 2.2.0
indent-string: 4.0.0
ai@3.4.31(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8):
ai@3.4.31(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.3.1)(sswr@2.1.0)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8):
dependencies:
'@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
@@ -18913,6 +18913,30 @@ snapshots:
openai: 4.69.0(encoding@0.1.13)(zod@3.23.8)
react: 18.3.1
sswr: 2.1.0(svelte@5.1.9)
zod: 3.23.8
transitivePeerDependencies:
- solid-js
- vue
ai@3.4.31(openai@4.69.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@5.1.9))(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8):
dependencies:
'@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
'@ai-sdk/react': 0.0.70(react@18.3.1)(zod@3.23.8)
'@ai-sdk/solid': 0.0.54(zod@3.23.8)
'@ai-sdk/svelte': 0.0.57(svelte@5.1.9)(zod@3.23.8)
'@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
'@ai-sdk/vue': 0.0.59(vue@3.5.12(typescript@5.6.3))(zod@3.23.8)
'@opentelemetry/api': 1.9.0
eventsource-parser: 1.1.2
json-schema: 0.4.0
jsondiffpatch: 0.6.0
secure-json-parse: 2.7.0
zod-to-json-schema: 3.23.5(zod@3.23.8)
optionalDependencies:
openai: 4.69.0(zod@3.23.8)
react: 18.3.1
sswr: 2.1.0(svelte@5.1.9)
svelte: 5.1.9
zod: 3.23.8
transitivePeerDependencies:
@@ -19600,7 +19624,7 @@ snapshots:
transitivePeerDependencies:
- encoding
chromadb@1.9.2(cohere-ai@7.14.0(encoding@0.1.13))(encoding@0.1.13)(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)):
chromadb@1.9.2(cohere-ai@7.14.0(encoding@0.1.13))(encoding@0.1.13)(openai@4.69.0(encoding@0.1.13)):
dependencies:
cliui: 8.0.1
isomorphic-fetch: 3.0.0(encoding@0.1.13)
@@ -20687,7 +20711,7 @@ snapshots:
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 9.14.0(jiti@2.4.0)
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.0))
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.0)))(eslint@9.14.0(jiti@2.4.0))
fast-glob: 3.3.2
get-tsconfig: 4.8.1
is-bun-module: 1.1.0
@@ -20700,7 +20724,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.0)):
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.0)))(eslint@9.14.0(jiti@2.4.0)):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -20722,7 +20746,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.14.0(jiti@2.4.0)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.0))
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.0)))(eslint@9.14.0(jiti@2.4.0))
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
@@ -24388,6 +24412,21 @@ snapshots:
transitivePeerDependencies:
- encoding
openai@4.69.0(zod@3.23.8):
dependencies:
'@types/node': 18.19.64
'@types/node-fetch': 2.6.11
abort-controller: 3.0.0
agentkeepalive: 4.5.0
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.7.0(encoding@0.1.13)
optionalDependencies:
zod: 3.23.8
transitivePeerDependencies:
- encoding
optional: true
openapi-sampler@1.5.1:
dependencies:
'@types/json-schema': 7.0.15
@@ -26259,14 +26298,13 @@ snapshots:
interpret: 1.4.0
rechoir: 0.6.2
shiki-magic-move@0.5.0(react@18.3.1)(shiki@1.22.2)(svelte@5.1.9)(vue@3.5.12(typescript@5.6.3)):
shiki-magic-move@0.5.0(react@18.3.1)(shiki@1.22.2)(vue@3.5.12(typescript@5.6.3)):
dependencies:
diff-match-patch-es: 0.1.1
ohash: 1.1.4
optionalDependencies:
react: 18.3.1
shiki: 1.22.2
svelte: 5.1.9
vue: 3.5.12(typescript@5.6.3)
shiki@1.22.2:
+15
View File
@@ -1,5 +1,20 @@
# @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
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/unit-test",
"private": true,
"version": "0.0.23",
"version": "0.0.25",
"type": "module",
"scripts": {
"test": "vitest run"