diff --git a/.changeset/cuddly-bulldogs-drive.md b/.changeset/cuddly-bulldogs-drive.md new file mode 100644 index 0000000000000000000000000000000000000000..f926a1865aa0ef770f74e8e8d77dc46c6d5ecd78 --- /dev/null +++ b/.changeset/cuddly-bulldogs-drive.md @@ -0,0 +1,5 @@ +--- +"@llamaindex/core": patch +--- + +fix: include additional options for context chat engine diff --git a/.changeset/early-singers-look.md b/.changeset/early-singers-look.md new file mode 100644 index 0000000000000000000000000000000000000000..e8e1a4e88d6038a886aa3fc7c6996b87a17c0262 --- /dev/null +++ b/.changeset/early-singers-look.md @@ -0,0 +1,5 @@ +--- +"@llamaindex/google": patch +--- + +fix: don't ignore parts that only have inline data for google studio diff --git a/.changeset/wise-goats-scream.md b/.changeset/wise-goats-scream.md new file mode 100644 index 0000000000000000000000000000000000000000..20f9c1898acff21ab080a31439409109e5443cd7 --- /dev/null +++ b/.changeset/wise-goats-scream.md @@ -0,0 +1,5 @@ +--- +"@llamaindex/mongodb": patch +--- + +Added mongo db document and key value store diff --git a/.changeset/yellow-walls-happen.md b/.changeset/yellow-walls-happen.md new file mode 100644 index 0000000000000000000000000000000000000000..2385a69f5aead09a74249f2af21c12f2f8ef5283 --- /dev/null +++ b/.changeset/yellow-walls-happen.md @@ -0,0 +1,5 @@ +--- +"@llamaindex/workflow": patch +--- + +Fix: multi-agent handover diff --git a/apps/next/src/content/docs/llamaindex/modules/data_stores/vector_stores/qdrant.mdx b/apps/next/src/content/docs/llamaindex/modules/data_stores/vector_stores/qdrant.mdx index 5b86585b102a519392db4017755e853845465123..05e506b4b5309159006e81da758058c9a3b404d5 100644 --- a/apps/next/src/content/docs/llamaindex/modules/data_stores/vector_stores/qdrant.mdx +++ b/apps/next/src/content/docs/llamaindex/modules/data_stores/vector_stores/qdrant.mdx @@ -56,10 +56,10 @@ const vectorStore = new QdrantVectorStore({ ```ts const document = new Document({ text: essay, id_: path }); - -const index = await VectorStoreIndex.fromDocuments([document], { - vectorStore, -}); +const storageContext = await storageContextFromDefaults({ vectorStore }); + const index = await VectorStoreIndex.fromDocuments([document], { + storageContext, + }); ``` ## Query the index @@ -91,11 +91,11 @@ async function main() { }); const document = new Document({ text: essay, id_: path }); - + const storageContext = await storageContextFromDefaults({ vectorStore }); const index = await VectorStoreIndex.fromDocuments([document], { - vectorStore, + storageContext, }); - + const queryEngine = index.asQueryEngine(); const response = await queryEngine.query({ diff --git a/packages/core/src/chat-engine/context-chat-engine.ts b/packages/core/src/chat-engine/context-chat-engine.ts index b1f1ff75ea0b896e3ca3fd0e894bc18fd3672f15..ff9be1a81518faf052094bec6922b693e5bfef35 100644 --- a/packages/core/src/chat-engine/context-chat-engine.ts +++ b/packages/core/src/chat-engine/context-chat-engine.ts @@ -102,6 +102,7 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine { const stream = await this.chatModel.chat({ messages: requestMessages.messages, stream: true, + additionalChatOptions: params.chatOptions as object, }); return streamConverter( streamReducer({ @@ -117,6 +118,7 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine { } const response = await this.chatModel.chat({ messages: requestMessages.messages, + additionalChatOptions: params.chatOptions as object, }); chatHistory.put(response.message); return EngineResponse.fromChatResponse(response, requestMessages.nodes); diff --git a/packages/providers/google/src/studio/utils.ts b/packages/providers/google/src/studio/utils.ts index 924bdb7c3dd653f018be65157b10dedcb79e5203..a6ec44a9cbbe7ca8f9cda3418822e6e07466a35a 100644 --- a/packages/providers/google/src/studio/utils.ts +++ b/packages/providers/google/src/studio/utils.ts @@ -124,7 +124,7 @@ export const mapChatMessagesToGoogleMessages = < return mapMessageContentToMessageContentDetails(msg.content) .map((detail: MessageContentDetail): ContentUnion | null => { const part = mapMessageContentDetailToGooglePart(detail); - if (!part.text) return null; + if (!part.text && !part.inlineData) return null; return { role: msg.role === "assistant" ? "model" : "user", diff --git a/packages/providers/storage/mongodb/package.json b/packages/providers/storage/mongodb/package.json index 2378fc48978b415961a95446bd800f3e2c03625d..80375d5dcdde45639cc7e2fe2a202fe1a4c7067f 100644 --- a/packages/providers/storage/mongodb/package.json +++ b/packages/providers/storage/mongodb/package.json @@ -35,10 +35,13 @@ }, "scripts": { "build": "bunchee", - "dev": "bunchee --watch" + "dev": "bunchee --watch", + "test": "vitest" }, "devDependencies": { - "bunchee": "6.4.0" + "bunchee": "6.4.0", + "vitest": "2.1.0", + "mongodb-memory-server": "^10.1.4" }, "dependencies": { "@llamaindex/core": "workspace:*", diff --git a/packages/providers/storage/mongodb/src/docStore/MongoDBDocumentStore.ts b/packages/providers/storage/mongodb/src/docStore/MongoDBDocumentStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..47f167ed53941a3014ab1107b181ec227bddb52a --- /dev/null +++ b/packages/providers/storage/mongodb/src/docStore/MongoDBDocumentStore.ts @@ -0,0 +1,76 @@ +import { KVDocumentStore } from "@llamaindex/core/storage/doc-store"; +import { MongoClient } from "mongodb"; +import { MongoKVStore } from "../kvStore/MongoKVStore"; + +const DEFAULT_DATABASE = "DocumentStoreDB"; +const DEFAULT_COLLECTION = "DocumentStoreCollection"; + +interface MongoDBDocumentStoreConfig { + mongoKVStore: MongoKVStore; + namespace?: string; +} + +export class MongoDocumentStore extends KVDocumentStore { + constructor({ mongoKVStore, namespace }: MongoDBDocumentStoreConfig) { + super(mongoKVStore, namespace); + } + + /** + * Static method for creating an instance using a MongoClient. + * @returns Instance of MongoDBDocumentStore + * @param mongoClient - MongoClient instance + * @param dbName - Database name + * @param collectionName - Collection name + * @example + * ```ts + * const mongoClient = new MongoClient("mongodb://localhost:27017"); + * const documentStore = MongoDBDocumentStore.fromMongoClient(mongoClient, "my_db", "my_collection"); + * ``` + */ + static fromMongoClient( + mongoClient: MongoClient, + dbName: string = DEFAULT_DATABASE, + collectionName: string = DEFAULT_COLLECTION, + ): MongoDocumentStore { + const mongoKVStore = new MongoKVStore({ + mongoClient, + dbName, + }); + + return new MongoDocumentStore({ + mongoKVStore, + namespace: `${dbName}.${collectionName}`, + }); + } + + /** + * Static method for creating an instance using a connection string. + * @returns Instance of MongoDBDocumentStore + * @param connectionString - MongoDB connection string + * @param dbName - Database name + * @param collectionName - Collection name + * @example + * ```ts + * const documentStore = MongoDBDocumentStore.fromConnectionString("mongodb://localhost:27017", "my_db", "my_collection"); + * ``` + */ + static fromConnectionString( + connectionString: string, + dbName: string = DEFAULT_DATABASE, + collectionName: string = DEFAULT_COLLECTION, + ): MongoDocumentStore { + const mongoClient = new MongoClient(connectionString, { + appName: "LLAMAINDEX_JS", + }); + + const mongoKVStore = new MongoKVStore({ + mongoClient, + dbName, + }); + + return new MongoDocumentStore({ + mongoKVStore, + namespace: `${dbName}.${collectionName}`, + }); + } +} diff --git a/packages/providers/storage/mongodb/src/index.ts b/packages/providers/storage/mongodb/src/index.ts index 513fcd77ff84e678918346935b876f3e0ef2266a..6b05ee34cca7ecf90d9da59df5a45e34476158c7 100644 --- a/packages/providers/storage/mongodb/src/index.ts +++ b/packages/providers/storage/mongodb/src/index.ts @@ -1 +1,3 @@ +export * from "./docStore/MongoDBDocumentStore"; +export * from "./kvStore/MongoKVStore"; export * from "./MongoDBAtlasVectorStore"; diff --git a/packages/providers/storage/mongodb/src/kvStore/MongoKVStore.ts b/packages/providers/storage/mongodb/src/kvStore/MongoKVStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..c506f6d4260c4ee77935c0a041527f67b88e8b93 --- /dev/null +++ b/packages/providers/storage/mongodb/src/kvStore/MongoKVStore.ts @@ -0,0 +1,93 @@ +import type { StoredValue } from "@llamaindex/core/schema"; +import { BaseKVStore } from "@llamaindex/core/storage/kv-store"; +import type { Collection, MongoClient } from "mongodb"; + +const DEFAULT_DB_NAME = "KVStoreDB"; +const DEFAULT_COLLECTION_NAME = "KVStoreCollection"; + +interface MongoKVStoreConfig { + mongoClient: MongoClient; + dbName?: string; +} + +export class MongoKVStore extends BaseKVStore { + private mongoClient: MongoClient; + private dbName: string; + + constructor({ mongoClient, dbName = DEFAULT_DB_NAME }: MongoKVStoreConfig) { + super(); + if (!mongoClient) { + throw new Error( + "MongoClient is required for MongoKVStore initialization", + ); + } + + this.mongoClient = mongoClient; + this.dbName = dbName; + } + + get client(): MongoClient { + return this.mongoClient; + } + + private async ensureCollection(collectionName: string): Promise<Collection> { + const collection = this.mongoClient + .db(this.dbName) + .collection(collectionName); + return collection; + } + + async put( + key: string, + val: Exclude<StoredValue, null>, + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<void> { + const collection = await this.ensureCollection(collectionName); + + await collection.updateOne({ id: key }, { $set: val }, { upsert: true }); + } + + async get( + key: string, + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<StoredValue> { + const collection = await this.ensureCollection(collectionName); + + const result = await collection.findOne( + { id: key }, + { projection: { _id: 0 } }, + ); + + if (!result) { + return null; + } + + return result; + } + + async getAll( + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<Record<string, StoredValue>> { + const collection = await this.ensureCollection(collectionName); + const cursor = collection.find({}, { projection: { _id: 0 } }); + + const output: Record<string, StoredValue> = {}; + + await cursor.forEach((item) => { + output[item.id] = item; + }); + + return output; + } + + async delete( + key: string, + collectionName: string = DEFAULT_COLLECTION_NAME, + ): Promise<boolean> { + const collection = await this.ensureCollection(collectionName); + + await collection.deleteOne({ id: key }); + + return true; + } +} diff --git a/packages/providers/storage/mongodb/src/tests/MongoDocumentStore.test.ts b/packages/providers/storage/mongodb/src/tests/MongoDocumentStore.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca30c0471fc6ff581c90774cb00802d9fba412cf --- /dev/null +++ b/packages/providers/storage/mongodb/src/tests/MongoDocumentStore.test.ts @@ -0,0 +1,150 @@ +import { Document, MetadataMode } from "@llamaindex/core/schema"; +import { MongoClient } from "mongodb"; +import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { MongoDocumentStore } from "../docStore/MongoDBDocumentStore"; +import { setupTestDb } from "./setuptTestDb"; + +describe("MongoDocumentStore", () => { + let cleanup: () => Promise<void>; + let mongoClient: MongoClient; + let documentStore: MongoDocumentStore; + let mongoUri: string; + + beforeAll(async () => { + const testDb = await setupTestDb(); + cleanup = testDb.cleanup; + mongoClient = testDb.mongoClient; + mongoUri = testDb.mongoUri; + documentStore = MongoDocumentStore.fromMongoClient(mongoClient); + }, 120000); + + afterAll(async () => { + await cleanup(); + }); + + describe("constructor", () => { + it("should create instance with mongoClient", () => { + const store = MongoDocumentStore.fromMongoClient(mongoClient); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + + it("should create instance with custom namespace", () => { + const store = MongoDocumentStore.fromMongoClient( + mongoClient, + "custom", + "namespace", + ); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + }); + + describe("static constructors", () => { + it("should create instance from connection string", () => { + const store = MongoDocumentStore.fromConnectionString(mongoUri); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + + it("should create instance from MongoClient", () => { + const store = MongoDocumentStore.fromMongoClient(mongoClient); + expect(store).toBeInstanceOf(MongoDocumentStore); + }); + }); + + describe("document operations", () => { + beforeEach(async () => { + await mongoClient.db("test").collection("test").deleteMany({}); + }); + + it("should store and retrieve a document", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + const retrievedDoc = await documentStore.getDocument("test_id"); + const text = retrievedDoc?.getContent(MetadataMode.ALL); + expect(text).toBe(doc.text); + }); + + it("should store and retrieve multiple documents", async () => { + const docs = [ + new Document({ text: "doc1", id_: "id1" }), + new Document({ text: "doc2", id_: "id2" }), + ]; + await documentStore.addDocuments(docs); + const retrievedDocs = await documentStore.getNodes(["id1", "id2"]); + expect(retrievedDocs.map((d) => d?.getContent(MetadataMode.ALL))).toEqual( + docs.map((d) => d.text), + ); + }); + + it("should handle missing documents", async () => { + const doc = await documentStore.getDocument("non_existent_id", false); + expect(doc).toBeUndefined(); + }); + }); + + describe("document updates", () => { + it("should update existing document when allowUpdate is true", async () => { + const doc1 = new Document({ text: "original", id_: "test_id" }); + const doc2 = new Document({ text: "updated", id_: "test_id" }); + await documentStore.addDocuments([doc1]); + await documentStore.addDocuments([doc2], true); + + const retrieved = await documentStore.getDocument("test_id"); + const text = retrieved?.getContent(MetadataMode.ALL); + expect(text).toBe("updated"); + }); + + it("should throw error when updating with allowUpdate false", async () => { + const doc1 = new Document({ text: "original", id_: "test_id" }); + await documentStore.addDocuments([doc1]); + + const doc2 = new Document({ text: "updated", id_: "test_id" }); + await expect(documentStore.addDocuments([doc2], false)).rejects.toThrow( + /doc_id.*already exists/, + ); + }); + }); + + describe("document deletion", () => { + it("should delete a document", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + await documentStore.deleteDocument("test_id"); + const retrieved = await documentStore.getDocument("test_id", false); + expect(retrieved).toBeUndefined(); + }); + + it("should handle deleting non-existent document", async () => { + await expect( + documentStore.deleteDocument("non_existent_id"), + ).resolves.not.toThrow(); + }); + }); + + describe("document existence", () => { + it("should check if document exists", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + const exists = await documentStore.documentExists("test_id"); + expect(exists).toBe(true); + }); + + it("should return false for non-existent document", async () => { + const exists = await documentStore.documentExists("non_existent_id"); + expect(exists).toBe(false); + }); + }); + + describe("document hash", () => { + it("should get document hash", async () => { + const doc = new Document({ text: "test document", id_: "test_id" }); + await documentStore.addDocuments([doc]); + const hash = await documentStore.getDocumentHash("test_id"); + expect(hash).toBe(doc.hash); + }); + + it("should return null for non-existent document hash", async () => { + const hash = await documentStore.getDocumentHash("non_existent_id"); + expect(hash).toBeUndefined(); + }); + }); +}); diff --git a/packages/providers/storage/mongodb/src/tests/MongokVStore.test.ts b/packages/providers/storage/mongodb/src/tests/MongokVStore.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..a34924ce733d4d43b3f87db8dc8f82808499dd9b --- /dev/null +++ b/packages/providers/storage/mongodb/src/tests/MongokVStore.test.ts @@ -0,0 +1,125 @@ +import type { MongoClient } from "mongodb"; +import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { MongoKVStore } from "../kvStore/MongoKVStore"; +import { setupTestDb } from "./setuptTestDb"; + +describe("MongoKVStore", () => { + let cleanUp: () => Promise<void>; + let mongoClient: MongoClient; + let mongoUri: string; + let kvStore: MongoKVStore; + + beforeAll(async () => { + const testDb = await setupTestDb(); + cleanUp = testDb.cleanup; + mongoClient = testDb.mongoClient; + mongoUri = testDb.mongoUri; + kvStore = new MongoKVStore({ + mongoClient, + dbName: "test", + }); + }, 120000); + + afterAll(async () => { + await cleanUp(); + }); + + describe("Mongod KV store constructor", () => { + it("should create instance with mongoClient", () => { + const kvStore = new MongoKVStore({ + mongoClient, + dbName: "test", + }); + + expect(kvStore).toBeInstanceOf(MongoKVStore); + }); + + it("should create db with custom db and collection name", () => { + const kvStore = new MongoKVStore({ + mongoClient, + dbName: "test", + }); + + expect(kvStore).toBeInstanceOf(MongoKVStore); + }); + }); + + describe("mongo kv store put ", () => { + it("should store a value", async () => { + const key = "test_key"; + + const value = { data: "test_value" }; + + await kvStore.put(key, value); + + const result = await kvStore.get(key); + expect(result).toMatchObject(value); + }); + + it("should update an existing value", async () => { + const key = "test_key2"; + + const value = { data: "test_value" }; + const value2 = { data: "test_value2" }; + await kvStore.put(key, value); + await kvStore.put(key, value2); + + const result = await kvStore.get(key); + + expect(result).toMatchObject(value2); + }); + }); + + describe("mongo kv store get", () => { + it("should return null for non-existent key", async () => { + const result = await kvStore.get("non_existent_key"); + expect(result).toBeNull(); + }); + + it("should return a value for stored key", async () => { + const key = "test_key"; + const value = { data: "test_value" }; + + const result = await kvStore.get(key); + expect(result).toMatchObject(value); + }); + }); + + describe("mongo kv store getAll", () => { + //reset the db before each test + beforeEach(async () => { + await mongoClient.db("test").collection("test").deleteMany({}); + }); + + it("should return all values", async () => { + const items = { + test_key1: { data: "test_value1" }, + test_key2: { data: "test_value2" }, + }; + + await Promise.all([ + kvStore.put("test_key1", items["test_key1"]), + kvStore.put("test_key2", items["test_key2"]), + ]); + + const result = await kvStore.getAll(); + + expect(result).toMatchObject(items); + }); + }); + + describe("mongo kv store delete", () => { + it("should delete a value", async () => { + const key = "test_key"; + const value = { data: "test_value" }; + + await kvStore.put(key, value); + const deleted = await kvStore.delete(key); + + const result = await kvStore.get(key); + + expect(result).toBeNull(); + expect(deleted).toBe(true); + }); + }); +}); diff --git a/packages/providers/storage/mongodb/src/tests/setuptTestDb.ts b/packages/providers/storage/mongodb/src/tests/setuptTestDb.ts new file mode 100644 index 0000000000000000000000000000000000000000..a9bf9e6e5055d92d7ec4adc5a3ede0f31c6e1c90 --- /dev/null +++ b/packages/providers/storage/mongodb/src/tests/setuptTestDb.ts @@ -0,0 +1,21 @@ +import { MongoClient } from "mongodb"; +import { MongoMemoryServer } from "mongodb-memory-server"; + +//setup a in memory test db for testing +export async function setupTestDb() { + const mongoServer = await MongoMemoryServer.create(); + const mongoUri = mongoServer.getUri(); + const mongoClient = new MongoClient(mongoUri); + await mongoClient.connect(); + + return { + mongoServer, + mongoClient, + mongoUri, + // return a cleanup function to close the db and stop the server + cleanup: async () => { + await mongoClient.close(); + await mongoServer.stop(); + }, + }; +} diff --git a/packages/workflow/src/agent/agent-workflow.ts b/packages/workflow/src/agent/agent-workflow.ts index a1a4a579df6c7ba8be190f0513978232cd062beb..0b2117c269c4188a6df21d922bae23b12051dea9 100644 --- a/packages/workflow/src/agent/agent-workflow.ts +++ b/packages/workflow/src/agent/agent-workflow.ts @@ -163,6 +163,24 @@ export class AgentWorkflow { this.addAgents(processedAgents); } + private addAgents(agents: BaseWorkflowAgent[]): void { + const agentNames = new Set(agents.map((a) => a.name)); + if (agentNames.size !== agents.length) { + throw new Error("The agent names must be unique!"); + } + + agents.forEach((agent) => { + this.agents.set(agent.name, agent); + }); + + if (agents.length > 1) { + agents.forEach((agent) => { + this.validateAgent(agent); + this.addHandoffTool(agent); + }); + } + } + private validateAgent(agent: BaseWorkflowAgent) { // Validate that all canHandoffTo agents exist const invalidAgents = agent.canHandoffTo.filter( @@ -176,7 +194,14 @@ export class AgentWorkflow { } private addHandoffTool(agent: BaseWorkflowAgent) { - const handoffTool = createHandoffTool(this.agents); + if (agent.tools.some((t) => t.metadata.name === "handOff")) { + return; + } + const toHandoffAgents: Map<string, BaseWorkflowAgent> = new Map(); + agent.canHandoffTo.forEach((name) => { + toHandoffAgents.set(name, this.agents.get(name)!); + }); + const handoffTool = createHandoffTool(toHandoffAgents); if ( agent.canHandoffTo.length > 0 && !agent.tools.some((t) => t.metadata.name === handoffTool.metadata.name) @@ -185,24 +210,6 @@ export class AgentWorkflow { } } - private addAgents(agents: BaseWorkflowAgent[]): void { - const agentNames = new Set(agents.map((a) => a.name)); - if (agentNames.size !== agents.length) { - throw new Error("The agent names must be unique!"); - } - - // First pass: add all agents to the map - agents.forEach((agent) => { - this.agents.set(agent.name, agent); - }); - - // Second pass: validate and setup handoff tools - agents.forEach((agent) => { - this.validateAgent(agent); - this.addHandoffTool(agent); - }); - } - /** * Adds a new agent to the workflow */ @@ -226,7 +233,6 @@ export class AgentWorkflow { * @param params - Parameters for the single agent workflow * @returns A new AgentWorkflow instance */ - static fromTools(params: SingleAgentParams): AgentWorkflow { const agent = new FunctionAgent({ name: params.name, @@ -234,6 +240,7 @@ export class AgentWorkflow { tools: params.tools, llm: params.llm, systemPrompt: params.systemPrompt, + canHandoffTo: params.canHandoffTo, }); const workflow = new AgentWorkflow({ diff --git a/packages/workflow/test/agent-workflow.test.ts b/packages/workflow/test/agent-workflow.test.ts index e467d691c9c845eaebb7c814faaa8b54aa724a07..cb9cc895da92043c3509ea65a446126a5bf8d80a 100644 --- a/packages/workflow/test/agent-workflow.test.ts +++ b/packages/workflow/test/agent-workflow.test.ts @@ -3,7 +3,7 @@ import { FunctionTool } from "@llamaindex/core/tools"; import { MockLLM } from "@llamaindex/core/utils"; import { describe, expect, test, vi } from "vitest"; import { z } from "zod"; -import { AgentWorkflow, FunctionAgent } from "../src/agent"; +import { AgentWorkflow, FunctionAgent, agent, multiAgent } from "../src/agent"; import { setupToolCallingMockLLM } from "./mock"; describe("AgentWorkflow", () => { @@ -157,3 +157,125 @@ describe("AgentWorkflow", () => { // }); }); + +describe("Multiple agents", () => { + test("multiple agents are set up correctly with handoff capabilities", () => { + // Create mock LLM + const mockLLM = new MockLLM(); + mockLLM.supportToolCall = true; + + // Create tools for agents + const addTool = FunctionTool.from( + (params: { x: number; y: number }) => params.x + params.y, + { + name: "add", + description: "Adds two numbers", + parameters: z.object({ + x: z.number(), + y: z.number(), + }), + }, + ); + + const multiplyTool = FunctionTool.from( + (params: { x: number; y: number }) => params.x * params.y, + { + name: "multiply", + description: "Multiplies two numbers", + parameters: z.object({ + x: z.number(), + y: z.number(), + }), + }, + ); + + const subtractTool = FunctionTool.from( + (params: { x: number; y: number }) => params.x - params.y, + { + name: "subtract", + description: "Subtracts two numbers", + parameters: z.object({ + x: z.number(), + y: z.number(), + }), + }, + ); + + // Create agents using the agent() function + const addAgent = agent({ + name: "AddAgent", + description: "Agent that can add numbers", + tools: [addTool], + llm: mockLLM, + }); + + const multiplyAgent = agent({ + name: "MultiplyAgent", + description: "Agent that can multiply numbers", + tools: [multiplyTool], + llm: mockLLM, + }); + + const mathAgent = agent({ + name: "MathAgent", + description: "Agent that can do various math operations", + tools: [addTool, multiplyTool, subtractTool], + llm: mockLLM, + canHandoffTo: ["AddAgent", "MultiplyAgent"], + }); + + // Create workflow with multiple agents using multiAgent + const workflow = multiAgent({ + agents: [mathAgent, addAgent, multiplyAgent], + rootAgent: mathAgent, + verbose: false, + }); + + // Verify agents are set up correctly + expect(workflow).toBeDefined(); + expect(workflow.getAgents().length).toBe(3); + + // Verify that the mathAgent has a handoff tool + const mathAgentInstance = workflow + .getAgents() + .find((agent) => agent.name === "MathAgent"); + expect(mathAgentInstance).toBeDefined(); + expect( + mathAgentInstance?.tools.some((tool) => tool.metadata.name === "handOff"), + ).toBe(true); + + // Verify that addAgent and multiplyAgent don't have handoff tools since they don't handoff to other agents + const addAgentInstance = workflow + .getAgents() + .find((agent) => agent.name === "AddAgent"); + expect(addAgentInstance).toBeDefined(); + expect( + addAgentInstance?.tools.some((tool) => tool.metadata.name === "handOff"), + ).toBe(false); + + const multiplyAgentInstance = workflow + .getAgents() + .find((agent) => agent.name === "MultiplyAgent"); + expect(multiplyAgentInstance).toBeDefined(); + expect( + multiplyAgentInstance?.tools.some( + (tool) => tool.metadata.name === "handOff", + ), + ).toBe(false); + + // Verify agent specific tools are preserved + expect( + mathAgentInstance?.tools.some( + (tool) => tool.metadata.name === "subtract", + ), + ).toBe(true); + expect( + addAgentInstance?.tools.some((tool) => tool.metadata.name === "add"), + ).toBe(true); + expect( + multiplyAgentInstance?.tools.some( + (tool) => tool.metadata.name === "multiply", + ), + ).toBe(true); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70faefcb16e669a0fa09aebac19ccefa11a4e9f1..ee14b98ae250d6ec87cab79313cad4510ffd124e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1519,6 +1519,12 @@ importers: bunchee: specifier: 6.4.0 version: 6.4.0(typescript@5.7.3) + mongodb-memory-server: + specifier: ^10.1.4 + version: 10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4) + vitest: + specifier: 2.1.0 + version: 2.1.0(@edge-runtime/vm@4.0.4)(@types/node@22.13.5)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(terser@5.38.2) packages/providers/storage/pinecone: dependencies: @@ -1728,64 +1734,6 @@ importers: specifier: ^13.4.8 version: 13.4.8 - packages/server: - dependencies: - '@llamaindex/chat-ui': - specifier: 0.3.1 - version: 0.3.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@llamaindex/core': - specifier: workspace:* - version: link:../core - '@llamaindex/workflow': - specifier: workspace:* - version: link:../workflow - ai: - specifier: ^4.2.0 - version: 4.2.0(react@19.0.0)(zod@3.24.2) - next: - specifier: 15.2.3 - version: 15.2.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: - specifier: ^19.0.0 - version: 19.0.0 - react-dom: - specifier: ^19.0.0 - version: 19.0.0(react@19.0.0) - devDependencies: - '@eslint/eslintrc': - specifier: ^3 - version: 3.3.0 - '@tailwindcss/postcss': - specifier: ^4 - version: 4.0.9 - '@types/node': - specifier: ^22.9.0 - version: 22.9.0 - '@types/react': - specifier: ^19 - version: 19.0.10 - '@types/react-dom': - specifier: ^19 - version: 19.0.4(@types/react@19.0.10) - bunchee: - specifier: 6.4.0 - version: 6.4.0(typescript@5.7.3) - eslint: - specifier: ^9 - version: 9.22.0(jiti@2.4.2) - eslint-config-next: - specifier: 15.2.3 - version: 15.2.3(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3) - tailwindcss: - specifier: ^4 - version: 4.0.9 - tsx: - specifier: ^4.19.3 - version: 4.19.3 - vitest: - specifier: ^2.1.5 - version: 2.1.5(@edge-runtime/vm@4.0.4)(@types/node@22.9.0)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.9.0)(typescript@5.7.3))(terser@5.38.2) - packages/tools: dependencies: '@apidevtools/swagger-parser': @@ -1969,12 +1917,6 @@ packages: zod: optional: true - '@ai-sdk/provider-utils@2.2.0': - resolution: {integrity: sha512-RX5BnDSqudjvZjwwpROcxVQElyX7rUn/xImBgaZLXekSGqq8f7/tefqDcQiRbDZjuCd4CVIfhrK8y/Pta8cPfQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.23.8 - '@ai-sdk/provider@0.0.26': resolution: {integrity: sha512-dQkfBDs2lTYpKM8389oopPdQgIU007GQyCbuPPrV+K6MtSII3HBfE0stUIMXUb44L+LK1t6GXPP7wjSzjO6uKg==} engines: {node: '>=18'} @@ -1983,10 +1925,6 @@ packages: resolution: {integrity: sha512-q1PJEZ0qD9rVR+8JFEd01/QM++csMT5UVwYXSN2u54BrVw/D8TZLTeg2FEfKK00DgAx0UtWd8XOhhwITP9BT5g==} engines: {node: '>=18'} - '@ai-sdk/provider@1.1.0': - resolution: {integrity: sha512-0M+qjp+clUD0R1E5eWQFhxEvWLNaOtGQRUaBn8CUABnSKredagq92hUS9VjOzGsTm37xLfpaxl97AVtbeOsHew==} - engines: {node: '>=18'} - '@ai-sdk/react@0.0.70': resolution: {integrity: sha512-GnwbtjW4/4z7MleLiW+TOZC2M29eCg1tOUpuEiYFMmFNZK8mkrqM0PFZMo6UsYeUYMWqEOOcPOU9OQVJMJh7IQ==} engines: {node: '>=18'} @@ -2011,16 +1949,6 @@ packages: zod: optional: true - '@ai-sdk/react@1.2.0': - resolution: {integrity: sha512-fUTZkAsxOMz8ijjWf87E/GfYkgsH4V5MH2yuj7EXh5ShjWe/oayn2ZJkyoqFMr4Jf8m5kptDaivmbIenDq5OXA==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - zod: ^3.23.8 - peerDependenciesMeta: - zod: - optional: true - '@ai-sdk/solid@0.0.54': resolution: {integrity: sha512-96KWTVK+opdFeRubqrgaJXoNiDP89gNxFRWUp0PJOotZW816AbhUf4EnDjBjXTLjXL1n0h8tGSE9sZsRkj9wQQ==} engines: {node: '>=18'} @@ -2057,12 +1985,6 @@ packages: zod: optional: true - '@ai-sdk/ui-utils@1.2.0': - resolution: {integrity: sha512-0IZwCqe7E+GkCASTDPAbzMr+POm9GDzWvFd37FvzpOeKNeibmge/LZEkTDbGSa+3b928H8wPwOLsOXBWPLUPDQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.23.8 - '@ai-sdk/vue@0.0.59': resolution: {integrity: sha512-+ofYlnqdc8c4F6tM0IKF0+7NagZRAiqBJpGDJ+6EYhDW8FHLUP/JFBgu32SjxSxC6IKFZxEnl68ZoP/Z38EMlw==} engines: {node: '>=18'} @@ -3670,11 +3592,6 @@ packages: peerDependencies: react: ^18.2.0 || ^19.0.0 || ^19.0.0-rc - '@llamaindex/chat-ui@0.3.1': - resolution: {integrity: sha512-sF6axN9LviewAxvBbqkF3u3K0yvIt74prio7uiVruFVT/AYkRlIk721QXTPBscf+ZvyzAqjh0Nx0BoGiZUzBCw==} - peerDependencies: - react: ^18.2.0 || ^19.0.0 || ^19.0.0-rc - '@llamaindex/pdf-viewer@1.3.0': resolution: {integrity: sha512-HJtjzmxn+erb3Vq89W5atPq0q6uyZMMCgzOnmstxudzaHW/Yj1dp1ojCuBh/wlP1tUnIRoe9RmvC0ahmqSwRUA==} peerDependencies: @@ -3825,15 +3742,9 @@ packages: '@next/env@15.2.1': resolution: {integrity: sha512-JmY0qvnPuS2NCWOz2bbby3Pe0VzdAQ7XpEB6uLIHmtXNfAsAO0KLQLkuAoc42Bxbo3/jMC3dcn9cdf+piCcG2Q==} - '@next/env@15.2.3': - resolution: {integrity: sha512-a26KnbW9DFEUsSxAxKBORR/uD9THoYoKbkpFywMN/AFvboTt94b8+g/07T8J6ACsdLag8/PDU60ov4rPxRAixw==} - '@next/eslint-plugin-next@15.1.0': resolution: {integrity: sha512-+jPT0h+nelBT6HC9ZCHGc7DgGVy04cv4shYdAe6tKlEbjQUtwU3LzQhzbDHQyY2m6g39m6B0kOFVuLGBrxxbGg==} - '@next/eslint-plugin-next@15.2.3': - resolution: {integrity: sha512-eNSOIMJtjs+dp4Ms1tB1PPPJUQHP3uZK+OQ7iFY9qXpGO6ojT6imCL+KcUOqE/GXGidWbBZJzYdgAdPHqeCEPA==} - '@next/swc-darwin-arm64@15.2.0': resolution: {integrity: sha512-rlp22GZwNJjFCyL7h5wz9vtpBVuCt3ZYjFWpEPBGzG712/uL1bbSkS675rVAUCRZ4hjoTJ26Q7IKhr5DfJrHDA==} engines: {node: '>= 10'} @@ -3846,12 +3757,6 @@ packages: cpu: [arm64] os: [darwin] - '@next/swc-darwin-arm64@15.2.3': - resolution: {integrity: sha512-uaBhA8aLbXLqwjnsHSkxs353WrRgQgiFjduDpc7YXEU0B54IKx3vU+cxQlYwPCyC8uYEEX7THhtQQsfHnvv8dw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - '@next/swc-darwin-x64@15.2.0': resolution: {integrity: sha512-DiU85EqSHogCz80+sgsx90/ecygfCSGl5P3b4XDRVZpgujBm5lp4ts7YaHru7eVTyZMjHInzKr+w0/7+qDrvMA==} engines: {node: '>= 10'} @@ -3864,12 +3769,6 @@ packages: cpu: [x64] os: [darwin] - '@next/swc-darwin-x64@15.2.3': - resolution: {integrity: sha512-pVwKvJ4Zk7h+4hwhqOUuMx7Ib02u3gDX3HXPKIShBi9JlYllI0nU6TWLbPT94dt7FSi6mSBhfc2JrHViwqbOdw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - '@next/swc-linux-arm64-gnu@15.2.0': resolution: {integrity: sha512-VnpoMaGukiNWVxeqKHwi8MN47yKGyki5q+7ql/7p/3ifuU2341i/gDwGK1rivk0pVYbdv5D8z63uu9yMw0QhpQ==} engines: {node: '>= 10'} @@ -3882,12 +3781,6 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-gnu@15.2.3': - resolution: {integrity: sha512-50ibWdn2RuFFkOEUmo9NCcQbbV9ViQOrUfG48zHBCONciHjaUKtHcYFiCwBVuzD08fzvzkWuuZkd4AqbvKO7UQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - '@next/swc-linux-arm64-musl@15.2.0': resolution: {integrity: sha512-ka97/ssYE5nPH4Qs+8bd8RlYeNeUVBhcnsNUmFM6VWEob4jfN9FTr0NBhXVi1XEJpj3cMfgSRW+LdE3SUZbPrw==} engines: {node: '>= 10'} @@ -3900,12 +3793,6 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.2.3': - resolution: {integrity: sha512-2gAPA7P652D3HzR4cLyAuVYwYqjG0mt/3pHSWTCyKZq/N/dJcUAEoNQMyUmwTZWCJRKofB+JPuDVP2aD8w2J6Q==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - '@next/swc-linux-x64-gnu@15.2.0': resolution: {integrity: sha512-zY1JduE4B3q0k2ZCE+DAF/1efjTXUsKP+VXRtrt/rJCTgDlUyyryx7aOgYXNc1d8gobys/Lof9P9ze8IyRDn7Q==} engines: {node: '>= 10'} @@ -3918,12 +3805,6 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-gnu@15.2.3': - resolution: {integrity: sha512-ODSKvrdMgAJOVU4qElflYy1KSZRM3M45JVbeZu42TINCMG3anp7YCBn80RkISV6bhzKwcUqLBAmOiWkaGtBA9w==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - '@next/swc-linux-x64-musl@15.2.0': resolution: {integrity: sha512-QqvLZpurBD46RhaVaVBepkVQzh8xtlUN00RlG4Iq1sBheNugamUNPuZEH1r9X1YGQo1KqAe1iiShF0acva3jHQ==} engines: {node: '>= 10'} @@ -3936,12 +3817,6 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.2.3': - resolution: {integrity: sha512-ZR9kLwCWrlYxwEoytqPi1jhPd1TlsSJWAc+H/CJHmHkf2nD92MQpSRIURR1iNgA/kuFSdxB8xIPt4p/T78kwsg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - '@next/swc-win32-arm64-msvc@15.2.0': resolution: {integrity: sha512-ODZ0r9WMyylTHAN6pLtvUtQlGXBL9voljv6ujSlcsjOxhtXPI1Ag6AhZK0SE8hEpR1374WZZ5w33ChpJd5fsjw==} engines: {node: '>= 10'} @@ -3954,12 +3829,6 @@ packages: cpu: [arm64] os: [win32] - '@next/swc-win32-arm64-msvc@15.2.3': - resolution: {integrity: sha512-+G2FrDcfm2YDbhDiObDU/qPriWeiz/9cRR0yMWJeTLGGX6/x8oryO3tt7HhodA1vZ8r2ddJPCjtLcpaVl7TE2Q==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - '@next/swc-win32-x64-msvc@15.2.0': resolution: {integrity: sha512-8+4Z3Z7xa13NdUuUAcpVNA6o76lNPniBd9Xbo02bwXQXnZgFvEopwY2at5+z7yHl47X9qbZpvwatZ2BRo3EdZw==} engines: {node: '>= 10'} @@ -3972,12 +3841,6 @@ packages: cpu: [x64] os: [win32] - '@next/swc-win32-x64-msvc@15.2.3': - resolution: {integrity: sha512-gHYS9tc+G2W0ZC8rBL+H6RdtXIyk40uLiaos0yj5US85FNhbFEndMA2nW3z47nzOWiSvXTZ5kBClc3rD0zJg0w==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -5795,9 +5658,24 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@vitest/expect@2.1.0': + resolution: {integrity: sha512-N3/xR4fSu0+6sVZETEtPT1orUs2+Y477JOXTcU3xKuu3uBlsgbD7/7Mz2LZ1Jr1XjwilEWlrIgSCj4N1+5ZmsQ==} + '@vitest/expect@2.1.5': resolution: {integrity: sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==} + '@vitest/mocker@2.1.0': + resolution: {integrity: sha512-ZxENovUqhzl+QiOFpagiHUNUuZ1qPd5yYTCYHomGIZOFArzn4mgX2oxZmiAItJWAaXHG6bbpb/DpSPhlk5DgtA==} + peerDependencies: + '@vitest/spy': 2.1.0 + msw: ^2.3.5 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/mocker@2.1.5': resolution: {integrity: sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==} peerDependencies: @@ -5809,21 +5687,36 @@ packages: vite: optional: true + '@vitest/pretty-format@2.1.0': + resolution: {integrity: sha512-7sxf2F3DNYatgmzXXcTh6cq+/fxwB47RIQqZJFoSH883wnVAoccSRT6g+dTKemUBo8Q5N4OYYj1EBXLuRKvp3Q==} + '@vitest/pretty-format@2.1.5': resolution: {integrity: sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==} '@vitest/pretty-format@2.1.9': resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + '@vitest/runner@2.1.0': + resolution: {integrity: sha512-D9+ZiB8MbMt7qWDRJc4CRNNUlne/8E1X7dcKhZVAbcOKG58MGGYVDqAq19xlhNfMFZsW0bpVKgztBwks38Ko0w==} + '@vitest/runner@2.1.5': resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} + '@vitest/snapshot@2.1.0': + resolution: {integrity: sha512-x69CygGMzt9VCO283K2/FYQ+nBrOj66OTKpsPykjCR4Ac3lLV+m85hj9reaIGmjBSsKzVvbxWmjWE3kF5ha3uQ==} + '@vitest/snapshot@2.1.5': resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} + '@vitest/spy@2.1.0': + resolution: {integrity: sha512-IXX5NkbdgTYTog3F14i2LgnBc+20YmkXMx0IWai84mcxySUDRgm0ihbOfR4L0EVRBDFG85GjmQQEZNNKVVpkZw==} + '@vitest/spy@2.1.5': resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} + '@vitest/utils@2.1.0': + resolution: {integrity: sha512-rreyfVe0PuNqJfKYUwfPDfi6rrp0VSu0Wgvp5WBqJonP+4NvXHk48X6oBam1Lj47Hy6jbJtnMj3OcRdrkTP0tA==} + '@vitest/utils@2.1.5': resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==} @@ -6113,16 +6006,6 @@ packages: zod: optional: true - ai@4.2.0: - resolution: {integrity: sha512-3xJWzBZpBS3n/UY360IopufV5dpfgYoY08eCAV2A2m7CcyJxVOAQ4lXvBGSsB+mR+BYJ8Y/JOesFfc0+k4jz3A==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ^19 || ^19.0.0-rc - zod: ^3.23.8 - peerDependenciesMeta: - react: - optional: true - ajv-draft-04@1.0.0: resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} peerDependencies: @@ -6308,6 +6191,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + async@2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} @@ -6551,6 +6437,10 @@ packages: resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} engines: {node: '>=4'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + caniuse-lite@1.0.30001699: resolution: {integrity: sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==} @@ -6575,6 +6465,10 @@ packages: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -7275,15 +7169,6 @@ packages: typescript: optional: true - eslint-config-next@15.2.3: - resolution: {integrity: sha512-VDQwbajhNMFmrhLWVyUXCqsGPN+zz5G8Ys/QwFubfsxTIrkqdx3N3x3QPW+pERz8bzGPP0IgEm8cNbZcd8PFRQ==} - peerDependencies: - eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 - typescript: '>=3.3.1' - peerDependenciesMeta: - typescript: - optional: true - eslint-config-prettier@9.1.0: resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true @@ -7628,6 +7513,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + find-chrome-bin@2.0.2: resolution: {integrity: sha512-KlggCilbbvgETk/WEq9NG894U8yu4erIW0SjMm1sMPm2xihCHeNoybpzGoxEzHRthwF3XrKOgHYtfqgJzpCH2w==} engines: {node: '>=18.0.0'} @@ -9502,6 +9391,14 @@ packages: mongodb-connection-string-url@3.0.2: resolution: {integrity: sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==} + mongodb-memory-server-core@10.1.4: + resolution: {integrity: sha512-o8fgY7ZalEd8pGps43fFPr/hkQu1L8i6HFEGbsTfA2zDOW0TopgpswaBCqDr0qD7ptibyPfB5DmC+UlIxbThzA==} + engines: {node: '>=16.20.1'} + + mongodb-memory-server@10.1.4: + resolution: {integrity: sha512-+oKQ/kc3CX+816oPFRtaF0CN4vNcGKNjpOQe4bHo/21A3pMD+lC7Xz1EX5HP7siCX4iCpVchDMmCOFXVQSGkUg==} + engines: {node: '>=16.20.1'} + mongodb@6.13.0: resolution: {integrity: sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==} engines: {node: '>=16.20.1'} @@ -9649,6 +9546,10 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} + new-find-package-json@2.0.0: + resolution: {integrity: sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==} + engines: {node: '>=12.22.0'} + next-themes@0.4.4: resolution: {integrity: sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==} peerDependencies: @@ -9697,27 +9598,6 @@ packages: sass: optional: true - next@15.2.3: - resolution: {integrity: sha512-x6eDkZxk2rPpu46E1ZVUWIBhYCLszmUY6fvHBFcbzJ9dD+qRX6vcHusaqqDlnY+VngKzKbAiG2iRCkPbmi8f7w==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - nice-grpc-client-middleware-retry@3.1.9: resolution: {integrity: sha512-BgbsNjuppxD6hoeCfO5gkBA/G69Tq5d9QX35QLdA46NSjKllelC+FlcgSPMlO9VQKCAPDfp4zzzDJZTNtbvzVw==} @@ -10242,6 +10122,10 @@ packages: piscina@4.8.0: resolution: {integrity: sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==} + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -12035,6 +11919,11 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.1.0: + resolution: {integrity: sha512-+ybYqBVUjYyIscoLzMWodus2enQDZOpGhcU6HdOVD6n8WZdk12w1GFL3mbnxLs7hPtRtqs1Wo5YF6/Tsr6fmhg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-node@2.1.5: resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} engines: {node: ^18.0.0 || >=20.0.0} @@ -12116,6 +12005,31 @@ packages: yaml: optional: true + vitest@2.1.0: + resolution: {integrity: sha512-XuuEeyNkqbfr0FtAvd9vFbInSSNY1ykCQTYQ0sj9wPy4hx+1gR7gqVNdW0AX2wrrM1wWlN5fnJDjF9xG6mYRSQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.0 + '@vitest/ui': 2.1.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vitest@2.1.5: resolution: {integrity: sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==} engines: {node: ^18.0.0 || >=20.0.0} @@ -12499,14 +12413,6 @@ snapshots: optionalDependencies: zod: 3.24.2 - '@ai-sdk/provider-utils@2.2.0(zod@3.24.2)': - dependencies: - '@ai-sdk/provider': 1.1.0 - eventsource-parser: 3.0.0 - nanoid: 3.3.8 - secure-json-parse: 2.7.0 - zod: 3.24.2 - '@ai-sdk/provider@0.0.26': dependencies: json-schema: 0.4.0 @@ -12515,10 +12421,6 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/provider@1.1.0': - dependencies: - json-schema: 0.4.0 - '@ai-sdk/react@0.0.70(react@19.0.0)(zod@3.24.2)': dependencies: '@ai-sdk/provider-utils': 1.0.22(zod@3.24.2) @@ -12539,16 +12441,6 @@ snapshots: react: 19.0.0 zod: 3.24.2 - '@ai-sdk/react@1.2.0(react@19.0.0)(zod@3.24.2)': - dependencies: - '@ai-sdk/provider-utils': 2.2.0(zod@3.24.2) - '@ai-sdk/ui-utils': 1.2.0(zod@3.24.2) - react: 19.0.0 - swr: 2.3.2(react@19.0.0) - throttleit: 2.1.0 - optionalDependencies: - zod: 3.24.2 - '@ai-sdk/solid@0.0.54(zod@3.24.2)': dependencies: '@ai-sdk/provider-utils': 1.0.22(zod@3.24.2) @@ -12584,13 +12476,6 @@ snapshots: optionalDependencies: zod: 3.24.2 - '@ai-sdk/ui-utils@1.2.0(zod@3.24.2)': - dependencies: - '@ai-sdk/provider': 1.1.0 - '@ai-sdk/provider-utils': 2.2.0(zod@3.24.2) - zod: 3.24.2 - zod-to-json-schema: 3.24.1(zod@3.24.2) - '@ai-sdk/vue@0.0.59(vue@3.5.13(typescript@5.7.3))(zod@3.24.2)': dependencies: '@ai-sdk/provider-utils': 1.0.22(zod@3.24.2) @@ -14646,36 +14531,6 @@ snapshots: - react-dom - supports-color - '@llamaindex/chat-ui@0.3.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@llamaindex/pdf-viewer': 1.3.0(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-collapsible': 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-hover-card': 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-icons': 1.3.2(react@19.0.0) - '@radix-ui/react-progress': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-select': 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-tabs': 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - class-variance-authority: 0.7.1 - clsx: 2.1.1 - highlight.js: 11.11.1 - katex: 0.16.21 - lucide-react: 0.453.0(react@19.0.0) - react: 19.0.0 - react-markdown: 8.0.7(@types/react@19.0.10)(react@19.0.0) - rehype-katex: 7.0.1 - remark: 14.0.3 - remark-code-import: 1.2.0 - remark-gfm: 3.0.1 - remark-math: 5.1.1 - tailwind-merge: 2.6.0 - vaul: 0.9.9(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - - react-dom - - supports-color - '@llamaindex/pdf-viewer@1.3.0(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@wojtekmaj/react-hooks': 1.17.2(react@19.0.0) @@ -14860,88 +14715,58 @@ snapshots: '@next/env@15.2.1': {} - '@next/env@15.2.3': {} - '@next/eslint-plugin-next@15.1.0': dependencies: fast-glob: 3.3.1 - '@next/eslint-plugin-next@15.2.3': - dependencies: - fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.2.0': optional: true '@next/swc-darwin-arm64@15.2.1': optional: true - '@next/swc-darwin-arm64@15.2.3': - optional: true - '@next/swc-darwin-x64@15.2.0': optional: true '@next/swc-darwin-x64@15.2.1': optional: true - '@next/swc-darwin-x64@15.2.3': - optional: true - '@next/swc-linux-arm64-gnu@15.2.0': optional: true '@next/swc-linux-arm64-gnu@15.2.1': optional: true - '@next/swc-linux-arm64-gnu@15.2.3': - optional: true - '@next/swc-linux-arm64-musl@15.2.0': optional: true '@next/swc-linux-arm64-musl@15.2.1': optional: true - '@next/swc-linux-arm64-musl@15.2.3': - optional: true - '@next/swc-linux-x64-gnu@15.2.0': optional: true '@next/swc-linux-x64-gnu@15.2.1': optional: true - '@next/swc-linux-x64-gnu@15.2.3': - optional: true - '@next/swc-linux-x64-musl@15.2.0': optional: true '@next/swc-linux-x64-musl@15.2.1': optional: true - '@next/swc-linux-x64-musl@15.2.3': - optional: true - '@next/swc-win32-arm64-msvc@15.2.0': optional: true '@next/swc-win32-arm64-msvc@15.2.1': optional: true - '@next/swc-win32-arm64-msvc@15.2.3': - optional: true - '@next/swc-win32-x64-msvc@15.2.0': optional: true '@next/swc-win32-x64-msvc@15.2.1': optional: true - '@next/swc-win32-x64-msvc@15.2.3': - optional: true - '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -17106,6 +16931,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/expect@2.1.0': + dependencies: + '@vitest/spy': 2.1.0 + '@vitest/utils': 2.1.0 + chai: 5.2.0 + tinyrainbow: 1.2.0 + '@vitest/expect@2.1.5': dependencies: '@vitest/spy': 2.1.5 @@ -17113,6 +16945,15 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 + '@vitest/mocker@2.1.0(@vitest/spy@2.1.0)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(vite@5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2))': + dependencies: + '@vitest/spy': 2.1.0 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.7.0(@types/node@22.13.5)(typescript@5.7.3) + vite: 5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + '@vitest/mocker@2.1.5(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(vite@5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2))': dependencies: '@vitest/spy': 2.1.5 @@ -17131,6 +16972,10 @@ snapshots: msw: 2.7.0(@types/node@22.9.0)(typescript@5.7.3) vite: 5.4.14(@types/node@22.9.0)(lightningcss@1.29.1)(terser@5.38.2) + '@vitest/pretty-format@2.1.0': + dependencies: + tinyrainbow: 1.2.0 + '@vitest/pretty-format@2.1.5': dependencies: tinyrainbow: 1.2.0 @@ -17139,21 +16984,42 @@ snapshots: dependencies: tinyrainbow: 1.2.0 + '@vitest/runner@2.1.0': + dependencies: + '@vitest/utils': 2.1.0 + pathe: 1.1.2 + '@vitest/runner@2.1.5': dependencies: '@vitest/utils': 2.1.5 pathe: 1.1.2 + '@vitest/snapshot@2.1.0': + dependencies: + '@vitest/pretty-format': 2.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + '@vitest/snapshot@2.1.5': dependencies: '@vitest/pretty-format': 2.1.5 magic-string: 0.30.17 pathe: 1.1.2 + '@vitest/spy@2.1.0': + dependencies: + tinyspy: 3.0.2 + '@vitest/spy@2.1.5': dependencies: tinyspy: 3.0.2 + '@vitest/utils@2.1.0': + dependencies: + '@vitest/pretty-format': 2.1.0 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + '@vitest/utils@2.1.5': dependencies: '@vitest/pretty-format': 2.1.5 @@ -17518,19 +17384,6 @@ snapshots: react: 19.0.0 zod: 3.24.2 - ai@4.2.0(react@19.0.0)(zod@3.24.2): - dependencies: - '@ai-sdk/provider': 1.1.0 - '@ai-sdk/provider-utils': 2.2.0(zod@3.24.2) - '@ai-sdk/react': 1.2.0(react@19.0.0)(zod@3.24.2) - '@ai-sdk/ui-utils': 1.2.0(zod@3.24.2) - '@opentelemetry/api': 1.9.0 - eventsource-parser: 3.0.0 - jsondiffpatch: 0.6.0 - zod: 3.24.2 - optionalDependencies: - react: 19.0.0 - ajv-draft-04@1.0.0(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -17723,6 +17576,10 @@ snapshots: async-function@1.0.0: {} + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + async@2.6.4: dependencies: lodash: 4.17.21 @@ -17749,7 +17606,7 @@ snapshots: axios@1.7.9: dependencies: - follow-redirects: 1.15.9 + follow-redirects: 1.15.9(debug@4.4.0) form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -18015,6 +17872,8 @@ snapshots: camelcase@4.1.0: {} + camelcase@6.3.0: {} + caniuse-lite@1.0.30001699: {} caniuse-lite@1.0.30001701: {} @@ -18052,6 +17911,14 @@ snapshots: loupe: 3.1.3 pathval: 2.0.0 + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -18877,8 +18744,8 @@ snapshots: '@typescript-eslint/parser': 8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3) eslint: 9.16.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.16.0(jiti@2.4.2)) eslint-plugin-react: 7.37.2(eslint@9.16.0(jiti@2.4.2)) eslint-plugin-react-hooks: 5.1.0(eslint@9.16.0(jiti@2.4.2)) @@ -18909,26 +18776,6 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-config-next@15.2.3(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3): - dependencies: - '@next/eslint-plugin-next': 15.2.3 - '@rushstack/eslint-patch': 1.10.5 - '@typescript-eslint/eslint-plugin': 8.24.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3) - '@typescript-eslint/parser': 8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3) - eslint: 9.22.0(jiti@2.4.2) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.22.0(jiti@2.4.2)) - eslint-plugin-react: 7.37.2(eslint@9.22.0(jiti@2.4.2)) - eslint-plugin-react-hooks: 5.1.0(eslint@9.22.0(jiti@2.4.2)) - optionalDependencies: - typescript: 5.7.3 - transitivePeerDependencies: - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - eslint-config-prettier@9.1.0(eslint@9.22.0(jiti@2.4.2)): dependencies: eslint: 9.22.0(jiti@2.4.2) @@ -18947,7 +18794,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)): + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -18959,7 +18806,7 @@ snapshots: is-glob: 4.0.3 stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -18979,14 +18826,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3) eslint: 9.16.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -19001,7 +18848,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -19012,7 +18859,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.16.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -19509,6 +19356,12 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + find-chrome-bin@2.0.2: dependencies: '@puppeteer/browsers': 2.7.1 @@ -19547,7 +19400,9 @@ snapshots: dependencies: tabbable: 6.2.0 - follow-redirects@1.15.9: {} + follow-redirects@1.15.9(debug@4.4.0): + optionalDependencies: + debug: 4.4.0 for-each@0.3.5: dependencies: @@ -20433,7 +20288,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9 + follow-redirects: 1.15.9(debug@4.4.0) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -21183,7 +21038,6 @@ snapshots: make-dir@3.1.0: dependencies: semver: 6.3.1 - optional: true make-dir@4.0.0: dependencies: @@ -22150,6 +22004,44 @@ snapshots: '@types/whatwg-url': 11.0.5 whatwg-url: 14.1.1 + mongodb-memory-server-core@10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4): + dependencies: + async-mutex: 0.5.0 + camelcase: 6.3.0 + debug: 4.4.0 + find-cache-dir: 3.3.2 + follow-redirects: 1.15.9(debug@4.4.0) + https-proxy-agent: 7.0.6 + mongodb: 6.13.0(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4) + new-find-package-json: 2.0.0 + semver: 7.7.1 + tar-stream: 3.1.7 + tslib: 2.8.1 + yauzl: 3.2.0 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + + mongodb-memory-server@10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4): + dependencies: + mongodb-memory-server-core: 10.1.4(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4) + tslib: 2.8.1 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + mongodb@6.13.0(@aws-sdk/credential-providers@3.744.0)(socks@2.8.4): dependencies: '@mongodb-js/saslprep': 1.2.0 @@ -22319,6 +22211,12 @@ snapshots: netmask@2.0.2: {} + new-find-package-json@2.0.0: + dependencies: + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + next-themes@0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 @@ -22376,32 +22274,6 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.2.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@next/env': 15.2.3 - '@swc/counter': 0.1.3 - '@swc/helpers': 0.5.15 - busboy: 1.6.0 - caniuse-lite: 1.0.30001701 - postcss: 8.4.31 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - styled-jsx: 5.1.6(react@19.0.0) - optionalDependencies: - '@next/swc-darwin-arm64': 15.2.3 - '@next/swc-darwin-x64': 15.2.3 - '@next/swc-linux-arm64-gnu': 15.2.3 - '@next/swc-linux-arm64-musl': 15.2.3 - '@next/swc-linux-x64-gnu': 15.2.3 - '@next/swc-linux-x64-musl': 15.2.3 - '@next/swc-win32-arm64-msvc': 15.2.3 - '@next/swc-win32-x64-msvc': 15.2.3 - '@opentelemetry/api': 1.9.0 - sharp: 0.33.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - nice-grpc-client-middleware-retry@3.1.9: dependencies: abort-controller-x: 0.4.3 @@ -22973,6 +22845,10 @@ snapshots: optionalDependencies: '@napi-rs/nice': 1.0.1 + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -25157,6 +25033,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + vite-node@2.1.0(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + pathe: 1.1.2 + vite: 5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@2.1.5(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2): dependencies: cac: 6.7.14 @@ -25233,6 +25126,42 @@ snapshots: tsx: 4.19.3 yaml: 2.7.0 + vitest@2.1.0(@edge-runtime/vm@4.0.4)(@types/node@22.13.5)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(terser@5.38.2): + dependencies: + '@vitest/expect': 2.1.0 + '@vitest/mocker': 2.1.0(@vitest/spy@2.1.0)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(vite@5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.0 + '@vitest/snapshot': 2.1.0 + '@vitest/spy': 2.1.0 + '@vitest/utils': 2.1.0 + chai: 5.2.0 + debug: 4.4.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.14(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + vite-node: 2.1.0(@types/node@22.13.5)(lightningcss@1.29.1)(terser@5.38.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@edge-runtime/vm': 4.0.4 + '@types/node': 22.13.5 + happy-dom: 15.11.7 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@2.1.5(@edge-runtime/vm@4.0.4)(@types/node@22.13.5)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.13.5)(typescript@5.7.3))(terser@5.38.2): dependencies: '@vitest/expect': 2.1.5 @@ -25748,4 +25677,4 @@ snapshots: zod@3.24.2: {} - zwitch@2.0.4: {} + zwitch@2.0.4: {} \ No newline at end of file