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