From 380400c5b8a4264e5943f8a1c31718cf34cbe09c Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 00:35:03 +0100 Subject: [PATCH 01/11] Tests setup for starters --- packages/core/src/embedding.ts | 2 +- .../core/src/test_resources/testAction.ts | 2 +- packages/core/src/tests/actions.test.d.ts | 1 - packages/core/src/tests/actions.test.ts | 268 -------- packages/core/src/tests/browser.test.ts | 98 --- packages/core/src/tests/continue.test.d.ts | 1 - packages/core/src/tests/continue.test.ts | 233 ------- packages/core/src/tests/database.test.ts | 239 +++++++ .../core/src/tests/defaultCharacters.test.ts | 48 ++ packages/core/src/tests/evaluation.test.d.ts | 1 - packages/core/src/tests/evaluation.test.ts | 128 ---- packages/core/src/tests/evaluators.test.ts | 80 +++ packages/core/src/tests/fact.test.d.ts | 1 - packages/core/src/tests/fact.test.ts | 150 ----- packages/core/src/tests/generation.test.ts | 166 ----- packages/core/src/tests/goal.test.d.ts | 1 - packages/core/src/tests/goal.test.ts | 202 ------ packages/core/src/tests/goals.test.d.ts | 1 - packages/core/src/tests/goals.test.ts | 294 ++++++--- packages/core/src/tests/ignore.test.d.ts | 1 - packages/core/src/tests/ignore.test.ts | 228 ------- packages/core/src/tests/memory.test.d.ts | 1 - packages/core/src/tests/memory.test.ts | 617 ------------------ packages/core/src/tests/messages.test.d.ts | 1 - packages/core/src/tests/messages.test.ts | 114 ---- packages/core/src/tests/models.test.ts | 33 + packages/core/src/tests/posts.test.ts | 101 +++ packages/core/src/tests/providers.test.d.ts | 1 - packages/core/src/tests/providers.test.ts | 51 -- .../core/src/tests/relationships.test.d.ts | 1 - packages/core/src/tests/relationships.test.ts | 70 -- packages/core/src/tests/runtime.test.d.ts | 1 - packages/core/src/tests/runtime.test.ts | 113 ---- packages/core/src/tests/time.test.d.ts | 1 - packages/core/src/tests/time.test.ts | 84 --- packages/core/src/tests/token.test.d.ts | 1 - packages/core/src/tests/token.test.ts | 77 --- packages/core/src/tests/utils.test.ts | 76 --- packages/core/tsconfig.json | 6 +- 39 files changed, 694 insertions(+), 2800 deletions(-) delete mode 100644 packages/core/src/tests/actions.test.d.ts delete mode 100644 packages/core/src/tests/actions.test.ts delete mode 100644 packages/core/src/tests/browser.test.ts delete mode 100644 packages/core/src/tests/continue.test.d.ts delete mode 100644 packages/core/src/tests/continue.test.ts create mode 100644 packages/core/src/tests/database.test.ts create mode 100644 packages/core/src/tests/defaultCharacters.test.ts delete mode 100644 packages/core/src/tests/evaluation.test.d.ts delete mode 100644 packages/core/src/tests/evaluation.test.ts create mode 100644 packages/core/src/tests/evaluators.test.ts delete mode 100644 packages/core/src/tests/fact.test.d.ts delete mode 100644 packages/core/src/tests/fact.test.ts delete mode 100644 packages/core/src/tests/generation.test.ts delete mode 100644 packages/core/src/tests/goal.test.d.ts delete mode 100644 packages/core/src/tests/goal.test.ts delete mode 100644 packages/core/src/tests/goals.test.d.ts delete mode 100644 packages/core/src/tests/ignore.test.d.ts delete mode 100644 packages/core/src/tests/ignore.test.ts delete mode 100644 packages/core/src/tests/memory.test.d.ts delete mode 100644 packages/core/src/tests/memory.test.ts delete mode 100644 packages/core/src/tests/messages.test.d.ts delete mode 100644 packages/core/src/tests/messages.test.ts create mode 100644 packages/core/src/tests/models.test.ts create mode 100644 packages/core/src/tests/posts.test.ts delete mode 100644 packages/core/src/tests/providers.test.d.ts delete mode 100644 packages/core/src/tests/providers.test.ts delete mode 100644 packages/core/src/tests/relationships.test.d.ts delete mode 100644 packages/core/src/tests/relationships.test.ts delete mode 100644 packages/core/src/tests/runtime.test.d.ts delete mode 100644 packages/core/src/tests/runtime.test.ts delete mode 100644 packages/core/src/tests/time.test.d.ts delete mode 100644 packages/core/src/tests/time.test.ts delete mode 100644 packages/core/src/tests/token.test.d.ts delete mode 100644 packages/core/src/tests/token.test.ts delete mode 100644 packages/core/src/tests/utils.test.ts diff --git a/packages/core/src/embedding.ts b/packages/core/src/embedding.ts index e212558875..d54447875c 100644 --- a/packages/core/src/embedding.ts +++ b/packages/core/src/embedding.ts @@ -1,4 +1,4 @@ -import { EmbeddingModel, FlagEmbedding } from "fastembed"; +import { FlagEmbedding } from "fastembed"; import path from "path"; import { fileURLToPath } from "url"; import models from "./models.ts"; diff --git a/packages/core/src/test_resources/testAction.ts b/packages/core/src/test_resources/testAction.ts index 78ea87a3a6..7dfc9d8226 100644 --- a/packages/core/src/test_resources/testAction.ts +++ b/packages/core/src/test_resources/testAction.ts @@ -2,7 +2,7 @@ import { IAgentRuntime, type Action, type Memory, -} from "@ai16z/eliza/src/types.ts"; +} from "../../src/types.ts"; export const TEST_ACTION = { name: "TEST_ACTION", diff --git a/packages/core/src/tests/actions.test.d.ts b/packages/core/src/tests/actions.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/actions.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/actions.test.ts b/packages/core/src/tests/actions.test.ts deleted file mode 100644 index 6f702bf5d9..0000000000 --- a/packages/core/src/tests/actions.test.ts +++ /dev/null @@ -1,268 +0,0 @@ -import dotenv from "dotenv"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { messageHandlerTemplate } from "../src/test_resources/templates.ts"; -import { - TEST_ACTION, - TEST_ACTION_FAIL, -} from "../src/test_resources/testAction.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { composeContext } from "../src/context.ts"; -import { embeddingZeroVector } from "../src/memory.ts"; -import { - Content, - IAgentRuntime, - ModelClass, - State, - type Memory, - type UUID, -} from "../src/types.ts"; -import { stringToUuid } from "../src/uuid.ts"; -import { generateMessageResponse } from "../src/generation.ts"; -import { MemoryManager } from "@ai16z/eliza/src/index.ts"; - -async function handleMessage( - runtime: IAgentRuntime, - message: Memory, - state?: State -) { - const _saveRequestMessage = async (message: Memory, state: State) => { - const { content: senderContent, userId, roomId } = message; - - const _senderContent = (senderContent as Content).text?.trim(); - if (_senderContent) { - await runtime.messageManager.createMemory({ - id: stringToUuid( - message.id ?? userId + runtime.agentId + Date.now() - ), - userId: userId!, - agentId: runtime.agentId, - content: { - text: _senderContent, - action: (message.content as Content)?.action ?? "null", - }, - roomId, - embedding: embeddingZeroVector, - }); - await runtime.evaluate(message, state); - } - }; - - await _saveRequestMessage(message, state as State); - if (!state) { - state = (await runtime.composeState(message)) as State; - } - - const context = composeContext({ - state, - template: messageHandlerTemplate, - }); - - let responseContent: Content | null = null; - const { userId, roomId } = message; - - for (let triesLeft = 3; triesLeft > 0; triesLeft--) { - const response = await generateMessageResponse({ - context, - runtime, - modelClass: ModelClass.SMALL, - }); - - runtime.databaseAdapter.log({ - body: { message, context, response }, - userId: userId, - roomId, - type: "actions_test_completion", - }); - return response; - } - - if (!responseContent) { - responseContent = { - text: "", - action: "IGNORE", - }; - } - - if (responseContent.text) { - const response = { - userId: runtime.agentId, - agentId: runtime.agentId, - content: responseContent, - roomId, - embedding: embeddingZeroVector, - }; - await runtime.messageManager.createMemory(response); - - state = await this.runtime.updateRecentMessageState(state); - await runtime.processActions(message, [response], state); - await runtime.evaluate(message, state); - } else { - console.warn("Empty response, skipping"); - } - - return responseContent; -} - -// use .dev.vars for local testing -dotenv.config({ path: ".dev.vars" }); - -describe("Actions", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId: UUID; - - beforeAll(async () => { - const { session, runtime: _runtime } = await createRuntime({ - env: process.env as Record, - actions: [TEST_ACTION, TEST_ACTION_FAIL], - }); - - user = session.user!; - runtime = _runtime as IAgentRuntime; - - // check if the user id exists in the 'accounts' table - // if it doesn't, create it with the name 'Test User' - let account = await runtime.databaseAdapter.getAccountById( - user.id as UUID - ); - - if (!account) { - account = await runtime.databaseAdapter.getAccountById( - user.id as UUID - ); - if (!account) { - await runtime.databaseAdapter.createAccount({ - id: user.id as UUID, - username: "Test User", - name: "Test User", - email: user.email, - avatarUrl: "", - }); - } - } - - // get all relationships for user - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: "00000000-0000-0000-0000-000000000000" as UUID, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data!.roomId; - - await cleanup(); - }); - - afterAll(async () => { - await cleanup(); - }); - - async function cleanup() { - const factsManager = new MemoryManager({ - runtime, - tableName: "facts", - }); - - await factsManager.removeAllMemories(roomId); - await runtime.messageManager.removeAllMemories(roomId); - } - - // Test that actions are being loaded into context properly - test("Actions are loaded into context", async () => { - const actions = runtime.actions; - expect(actions).toBeDefined(); - expect(actions.length).toBeGreaterThan(0); - // Ensure the TEST_ACTION action is part of the loaded actions - const testAction = actions.find( - (action) => action.name === "TEST_ACTION" - ); - expect(testAction).toBeDefined(); - }); - - // Test that actions are validated properly - test("Test action is always valid", async () => { - const testAction = runtime.actions.find( - (action) => action.name === "TEST_ACTION" - ); - expect(testAction).toBeDefined(); - if (testAction && testAction.validate) { - const isValid = await testAction.validate(runtime, { - userId: user.id as UUID, - agentId: runtime.agentId, - content: { text: "Test message" }, - roomId: roomId, - }); - expect(isValid).toBeTruthy(); - } else { - throw new Error( - "Continue action or its validation function is undefined" - ); - } - }); - - test("Test that actions are properly validated in state", async () => { - const message: Memory = { - agentId: runtime.agentId, - userId: user.id as UUID, - content: { - text: "Please respond with the message 'ok' and the action TEST_ACTION", - }, - roomId, - }; - - const state = await runtime.composeState(message); - expect(state.actionNames).not.toContain("TEST_ACTION_FAIL"); - - expect(state.actionNames).toContain("TEST_ACTION"); - }); - - // Validate that TEST_ACTION is in the state - test("Validate that TEST_ACTION is in the state", async () => { - await runAiTest("Validate TEST_ACTION is in the state", async () => { - const message: Memory = { - agentId: runtime.agentId, - userId: user.id as UUID, - content: { - text: "Please respond with the message 'ok' and the action TEST_ACTION", - }, - roomId, - }; - - const response = await handleMessage(runtime, message); - return response.action === "TEST_ACTION"; // Return true if the expected action matches - }); - }, 60000); - - // Test that TEST_ACTION action handler is called properly - test("Test action handler is called", async () => { - await runAiTest("Test action handler is called", async () => { - const testAction = runtime.actions.find( - (action) => action.name === "TEST_ACTION" - ); - if (!testAction || !testAction.handler) { - console.error( - "Continue action or its handler function is undefined" - ); - return false; // Return false to indicate the test setup failed - } - - const mockMessage: Memory = { - userId: user.id as UUID, - agentId: runtime.agentId, - content: { - text: "Test message for TEST action", - }, - roomId, - }; - - const response = await testAction.handler(runtime, mockMessage); - return response !== undefined; // Return true if the handler returns a defined response - }); - }, 60000); // You can adjust the timeout if needed -}); diff --git a/packages/core/src/tests/browser.test.ts b/packages/core/src/tests/browser.test.ts deleted file mode 100644 index b8c5d1fc94..0000000000 --- a/packages/core/src/tests/browser.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import dotenv from "dotenv"; -import { createRuntime } from "../test_resources/createRuntime.ts"; -import { BrowserService } from "./browser.ts"; - -dotenv.config(); - -describe("BrowserService", () => { - let browserService: BrowserService; - - beforeAll(async () => { - const { runtime } = await createRuntime({ - env: process.env as Record, - actions: [], - }); - browserService = BrowserService.getInstance(runtime); - await browserService.initialize(); - }); - - afterAll(async () => { - await browserService.closeBrowser(); - }); - - test("should initialize and close browser", async () => { - const { runtime } = await createRuntime({ - env: process.env as Record, - actions: [], - }); - const newBrowserService = BrowserService.getInstance(runtime); - await expect(newBrowserService.initialize()).resolves.not.toThrow(); - await expect(newBrowserService.closeBrowser()).resolves.not.toThrow(); - }); - - test("should fetch content from a simple website", async () => { - const content = await browserService.getPageContent( - "https://example.com" - ); - expect(content).toContain("Example Domain"); - }, 30000); - - test("should fetch content from a news website", async () => { - const content = await browserService.getPageContent( - "https://news.ycombinator.com" - ); - expect(content).toContain("Hacker News"); - }, 30000); - - test("should handle a website with potential CAPTCHA (GitHub)", async () => { - const content = - await browserService.getPageContent("https://github.com"); - expect(content).toContain("GitHub"); - }, 60000); - - test("should fetch content from a website that might be blocked (Wikipedia)", async () => { - const content = await browserService.getPageContent( - "https://en.wikipedia.org/wiki/Main_Page" - ); - expect(content).toContain("Wikipedia"); - }, 30000); - - test("should handle a 404 error and try alternative sources", async () => { - const content = await browserService.getPageContent( - "https://example.com/nonexistent-page" - ); - expect(content).not.toBe(""); - expect(content).toContain("search"); // Expecting to fall back to a search result - }, 60000); - - test("should handle network errors gracefully", async () => { - await expect( - browserService.getPageContent( - "https://thisisaninvalidurlthatdoesnotexist.com" - ) - ).rejects.toThrow("Failed to fetch content from alternative sources"); - }, 60000); - - test("should block ads on ad-heavy website", async () => { - const content = await browserService.getPageContent( - "https://www.cnn.com" - ); - expect(content).not.toContain("Advertisement"); - }, 60000); - - test("should handle a website with reCAPTCHA", async () => { - const content = await browserService.getPageContent( - "https://www.google.com/recaptcha/api2/demo" - ); - expect(content).toContain("reCAPTCHA"); - // Note: Full CAPTCHA solving can't be reliably tested without manual intervention - }, 60000); - - test("should handle a website with hCAPTCHA", async () => { - const content = await browserService.getPageContent( - "https://accounts.hcaptcha.com/demo" - ); - expect(content).toContain("hCaptcha"); - // Note: Full CAPTCHA solving can't be reliably tested without manual intervention - }, 60000); -}); diff --git a/packages/core/src/tests/continue.test.d.ts b/packages/core/src/tests/continue.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/continue.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/continue.test.ts b/packages/core/src/tests/continue.test.ts deleted file mode 100644 index 07663f9388..0000000000 --- a/packages/core/src/tests/continue.test.ts +++ /dev/null @@ -1,233 +0,0 @@ -import dotenv from "dotenv"; -import { Content, IAgentRuntime, Memory, type UUID } from "../src/types.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { Goodbye1 } from "../src/test_resources/data.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { type User } from "../src/test_resources/types.ts"; -import action from "../src/actions/continue.ts"; -import ignore from "../src/actions/ignore.ts"; -import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; - -dotenv.config({ path: ".dev.vars" }); - -const GetContinueExample1 = (_userId: UUID) => [ - { - userId: zeroUuid, - content: { - text: "Hmm, let think for a second, I was going to tell you about something...", - action: "CONTINUE", - }, - }, - { - userId: zeroUuid, - content: { - text: "I remember now, I was going to tell you about my favorite food, which is pizza.", - action: "CONTINUE", - }, - }, - { - userId: zeroUuid, - content: { - text: "I love pizza, it's so delicious.", - action: "CONTINUE", - }, - }, -]; - -describe("User Profile", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId: UUID = zeroUuid; - - afterAll(async () => { - await cleanup(); - }); - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - actions: [action, ignore], - }); - user = setup.session.user; - runtime = setup.runtime; - - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: zeroUuid, - }); - - roomId = data.roomId; - - await cleanup(); - }); - - beforeEach(async () => { - await cleanup(); - }); - - async function cleanup() { - const factsManager = new MemoryManager({ - runtime, - tableName: "facts", - }); - - await factsManager.removeAllMemories(roomId); - await runtime.messageManager.removeAllMemories(roomId); - } - - // test validate function response - - test("Test validate function response", async () => { - await runAiTest("Test validate function response", async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "Hello" }, - roomId: roomId as UUID, - }; - - const validate = action.validate!; - - const result = await validate(runtime, message); - - // try again with GetContinueExample1, expect to be false - await populateMemories(runtime, user, roomId, [ - GetContinueExample1, - ]); - - const message2: Memory = { - userId: zeroUuid as UUID, - content: { - text: "Hello", - action: "CONTINUE", - }, - roomId: roomId as UUID, - }; - - const result2 = await validate(runtime, message2); - - return result === true && result2 === false; - }); - }, 60000); - - test("Test repetition check on continue", async () => { - await runAiTest("Test repetition check on continue", async () => { - const message: Memory = { - userId: zeroUuid as UUID, - content: { - text: "Hmm, let think for a second, I was going to tell you about something...", - action: "CONTINUE", - }, - roomId, - }; - - const handler = action.handler!; - - await populateMemories(runtime, user, roomId, [ - GetContinueExample1, - ]); - - const result = (await handler(runtime, message)) as Content; - - return result.action !== "CONTINUE"; - }); - }, 60000); - - test("Test multiple continue messages in a conversation", async () => { - await runAiTest( - "Test multiple continue messages in a conversation", - async () => { - const message: Memory = { - userId: user?.id as UUID, - content: { - text: "Write a short story in three parts, using the CONTINUE action for each part.", - }, - roomId: roomId, - }; - - const initialMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - await action.handler!(runtime, message); - - const finalMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - const agentMessages = await runtime.messageManager.getMemories({ - roomId, - agentId: runtime.agentId, - count: finalMessageCount - initialMessageCount, - unique: false, - }); - - const continueMessages = agentMessages.filter( - (m) => - m.userId === zeroUuid && - (m.content as Content).action === "CONTINUE" - ); - - // Check if the agent sent more than one message - const sentMultipleMessages = - finalMessageCount - initialMessageCount > 2; - - // Check if the agent used the CONTINUE action for each part - const usedContinueAction = continueMessages.length === 3; - // Check if the agent's responses are not empty - const responsesNotEmpty = agentMessages.every( - (m) => (m.content as Content).text !== "" - ); - - return ( - sentMultipleMessages && - usedContinueAction && - responsesNotEmpty - ); - } - ); - }, 60000); - - test("Test if message is added to database", async () => { - await runAiTest("Test if message is added to database", async () => { - const message: Memory = { - userId: user?.id as UUID, - content: { - text: "Tell me more about your favorite food.", - }, - roomId: roomId as UUID, - }; - - const initialMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - await action.handler!(runtime, message); - - const finalMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - return finalMessageCount - initialMessageCount === 2; - }); - }, 60000); - test("Test if not continue", async () => { - await runAiTest("Test if not continue", async () => { - // this is basically the same test as the one in ignore.test - const message: Memory = { - userId: user?.id as UUID, - content: { text: "Bye" }, - roomId: roomId as UUID, - }; - - const handler = action.handler!; - - await populateMemories(runtime, user, roomId, [Goodbye1]); - - const result = (await handler(runtime, message)) as Content; - - return result.action === "IGNORE"; - }); - }, 60000); - - // test conditions where we would expect a wait or an ignore -}); diff --git a/packages/core/src/tests/database.test.ts b/packages/core/src/tests/database.test.ts new file mode 100644 index 0000000000..9922d16930 --- /dev/null +++ b/packages/core/src/tests/database.test.ts @@ -0,0 +1,239 @@ +/* eslint-disable no-dupe-class-members */ +import { DatabaseAdapter } from '../database.ts'; // Adjust the import based on your project structure +import { Memory, Actor, Account, Goal, GoalStatus, Participant, Relationship, UUID } from '../types'; // Adjust based on your types location + +class MockDatabaseAdapter extends DatabaseAdapter { + getMemoryById(_id: UUID): Promise { + throw new Error('Method not implemented.'); + } + log(_params: { body: { [key: string]: unknown; }; userId: UUID; roomId: UUID; type: string; }): Promise { + throw new Error('Method not implemented.'); + } + getActorDetails(_params: { roomId: UUID; }): Promise { + throw new Error('Method not implemented.'); + } + searchMemoriesByEmbedding(_embedding: number[], _params: { match_threshold?: number; count?: number; roomId?: UUID; agentId?: UUID; unique?: boolean; tableName: string; }): Promise { + throw new Error('Method not implemented.'); + } + createMemory(_memory: Memory, _tableName: string, _unique?: boolean): Promise { + throw new Error('Method not implemented.'); + } + removeMemory(_memoryId: UUID, _tableName: string): Promise { + throw new Error('Method not implemented.'); + } + removeAllMemories(_roomId: UUID, _tableName: string): Promise { + throw new Error('Method not implemented.'); + } + countMemories(_roomId: UUID, _unique?: boolean, _tableName?: string): Promise { + throw new Error('Method not implemented.'); + } + getGoals(_params: { roomId: UUID; userId?: UUID | null; onlyInProgress?: boolean; count?: number; }): Promise { + throw new Error('Method not implemented.'); + } + updateGoal(_goal: Goal): Promise { + throw new Error('Method not implemented.'); + } + createGoal(_goal: Goal): Promise { + throw new Error('Method not implemented.'); + } + removeGoal(_goalId: UUID): Promise { + throw new Error('Method not implemented.'); + } + removeAllGoals(_roomId: UUID): Promise { + throw new Error('Method not implemented.'); + } + getRoom(_roomId: UUID): Promise { + throw new Error('Method not implemented.'); + } + createRoom(_roomId?: UUID): Promise { + throw new Error('Method not implemented.'); + } + removeRoom(_roomId: UUID): Promise { + throw new Error('Method not implemented.'); + } + getRoomsForParticipant(_userId: UUID): Promise { + throw new Error('Method not implemented.'); + } + getRoomsForParticipants(_userIds: UUID[]): Promise { + throw new Error('Method not implemented.'); + } + addParticipant(_userId: UUID, _roomId: UUID): Promise { + throw new Error('Method not implemented.'); + } + removeParticipant(_userId: UUID, _roomId: UUID): Promise { + throw new Error('Method not implemented.'); + } + getParticipantsForAccount(userId: UUID): Promise; + getParticipantsForAccount(userId: UUID): Promise; + getParticipantsForAccount(_userId: unknown): Promise { + throw new Error('Method not implemented.'); + } + getParticipantsForRoom(_roomId: UUID): Promise { + throw new Error('Method not implemented.'); + } + getParticipantUserState(_roomId: UUID, _userId: UUID): Promise<'FOLLOWED' | 'MUTED' | null> { + throw new Error('Method not implemented.'); + } + setParticipantUserState(_roomId: UUID, _userId: UUID, _state: 'FOLLOWED' | 'MUTED' | null): Promise { + throw new Error('Method not implemented.'); + } + createRelationship(_params: { userA: UUID; userB: UUID; }): Promise { + throw new Error('Method not implemented.'); + } + getRelationship(_params: { userA: UUID; userB: UUID; }): Promise { + throw new Error('Method not implemented.'); + } + getRelationships(_params: { userId: UUID; }): Promise { + throw new Error('Method not implemented.'); + } + db: any = {}; + + // Mock method for getting memories by room IDs + async getMemoriesByRoomIds(params: { roomIds: `${string}-${string}-${string}-${string}-${string}`[]; agentId?: `${string}-${string}-${string}-${string}-${string}`; tableName: string }): Promise { + return [{ + id: 'memory-id' as UUID, + content: 'Test Memory', + roomId: params.roomIds[0], + userId: 'user-id' as UUID, + agentId: params.agentId ?? 'agent-id' as UUID + }] as unknown as Memory[]; + } + + // Mock method for getting cached embeddings + async getCachedEmbeddings(_params: { query_table_name: string; query_threshold: number; query_input: string; query_field_name: string; query_field_sub_name: string; query_match_count: number }): Promise { + return [{ + embedding: [0.1, 0.2, 0.3], + levenshtein_distance: 0.4 + }]; + } + + // Mock method for searching memories + async searchMemories(params: { tableName: string; roomId: `${string}-${string}-${string}-${string}-${string}`; embedding: number[]; match_threshold: number; match_count: number; unique: boolean }): Promise { + return [{ + id: 'memory-id' as UUID, + content: 'Test Memory', + roomId: params.roomId, + userId: 'user-id' as UUID, + agentId: 'agent-id' as UUID + }] as unknown as Memory[]; + } + + // Mock method for getting account by ID + async getAccountById(userId: UUID): Promise { + return { id: userId, username: 'testuser', name: 'Test Account' } as Account; + } + + // Other methods stay the same... + async createAccount(_account: Account): Promise { + return true; + } + + async getMemories(params: { roomId: UUID; count?: number; unique?: boolean; tableName: string }): Promise { + return [{ + id: 'memory-id' as UUID, + content: 'Test Memory', + roomId: params.roomId, + userId: 'user-id' as UUID, + agentId: 'agent-id' as UUID + }] as unknown as Memory[]; + } + + async getActors(_params: { roomId: UUID }): Promise { + return [{ + id: 'actor-id' as UUID, + name: 'Test Actor', + username: 'testactor', + roomId: 'room-id' as UUID // Ensure roomId is provided + }] as unknown as Actor[]; + } + + async updateGoalStatus(_params: { goalId: UUID, status: GoalStatus }): Promise { + return Promise.resolve(); + } + + async getGoalById(goalId: UUID): Promise { + return { + id: goalId, + status: GoalStatus.IN_PROGRESS, + roomId: 'room-id' as UUID, + userId: 'user-id' as UUID, + name: 'Test Goal', + objectives: [] + } as Goal; + } +} + +// Now, let’s fix the test suite. + +describe('DatabaseAdapter Tests', () => { + let adapter: MockDatabaseAdapter; + const roomId = 'room-id' as UUID; + + beforeEach(() => { + adapter = new MockDatabaseAdapter(); + }); + + it('should return memories by room ID', async () => { + const memories = await adapter.getMemoriesByRoomIds({ + roomIds: ['room-id' as `${string}-${string}-${string}-${string}-${string}`], + tableName: 'test_table' + }); + expect(memories).toHaveLength(1); + expect(memories[0].roomId).toBe('room-id'); + }); + + it('should return cached embeddings', async () => { + const embeddings = await adapter.getCachedEmbeddings({ + query_table_name: 'test_table', + query_threshold: 0.5, + query_input: 'test query', + query_field_name: 'field', + query_field_sub_name: 'subfield', + query_match_count: 5 + }); + expect(embeddings).toHaveLength(1); + expect(embeddings[0].embedding).toEqual([0.1, 0.2, 0.3]); + }); + + it('should search memories based on embedding', async () => { + const memories = await adapter.searchMemories({ + tableName: 'test_table', + roomId: 'room-id' as `${string}-${string}-${string}-${string}-${string}`, + embedding: [0.1, 0.2, 0.3], + match_threshold: 0.5, + match_count: 3, + unique: true + }); + expect(memories).toHaveLength(1); + expect(memories[0].roomId).toBe('room-id'); + }); + + it('should get an account by user ID', async () => { + const account = await adapter.getAccountById('test-user-id' as UUID); + expect(account).not.toBeNull(); + expect(account.username).toBe('testuser'); + }); + + it('should create a new account', async () => { + const newAccount: Account = { id: 'new-user-id' as UUID, username: 'newuser', name: 'New Account' }; + const result = await adapter.createAccount(newAccount); + expect(result).toBe(true); + }); + + it('should update the goal status', async () => { + const goalId = 'goal-id' as UUID; + await expect(adapter.updateGoalStatus({ goalId, status: GoalStatus.IN_PROGRESS })).resolves.toBeUndefined(); + }); + + it('should return actors by room ID', async () => { + const actors = await adapter.getActors({ roomId }); + expect(actors).toHaveLength(1); + }); + + it('should get a goal by ID', async () => { + const goalId = 'goal-id' as UUID; + const goal = await adapter.getGoalById(goalId); + expect(goal).not.toBeNull(); + expect(goal?.status).toBe(GoalStatus.IN_PROGRESS); + }); +}); diff --git a/packages/core/src/tests/defaultCharacters.test.ts b/packages/core/src/tests/defaultCharacters.test.ts new file mode 100644 index 0000000000..32b916b741 --- /dev/null +++ b/packages/core/src/tests/defaultCharacters.test.ts @@ -0,0 +1,48 @@ +import { defaultCharacter } from '../defaultCharacter'; +import { ModelProviderName } from '../types'; + +describe('defaultCharacter', () => { + it('should have the correct name', () => { + expect(defaultCharacter.name).toBe('Eliza'); + }); + + it('should have an empty plugins array', () => { + expect(defaultCharacter.plugins).toEqual([]); + }); + + it('should have an empty clients array', () => { + expect(defaultCharacter.clients).toEqual([]); + }); + + it('should have the correct modelProvider', () => { + expect(defaultCharacter.modelProvider).toBe(ModelProviderName.OPENAI); + }); + + it('should have the correct voice model', () => { + expect(defaultCharacter.settings.voice.model).toBe('en_US-hfc_female-medium'); + }); + + it('should have a system description', () => { + expect(defaultCharacter.system).toBe('Roleplay and generate interesting on behalf of Eliza.'); + }); + + it('should have a bio array with at least one entry', () => { + expect(defaultCharacter.bio.length).toBeGreaterThan(0); + }); + + it('should have a lore array with at least one entry', () => { + expect(defaultCharacter.lore.length).toBeGreaterThan(0); + }); + + it('should have messageExamples array with at least one example', () => { + expect(defaultCharacter.messageExamples.length).toBeGreaterThan(0); + }); + + it('should have a topics array with at least one broad topic', () => { + expect(defaultCharacter.topics).toContain('metaphysics'); + }); + + it('should have style settings with "all" array', () => { + expect(defaultCharacter.style.all.length).toBeGreaterThan(0); + }); +}); diff --git a/packages/core/src/tests/evaluation.test.d.ts b/packages/core/src/tests/evaluation.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/evaluation.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/evaluation.test.ts b/packages/core/src/tests/evaluation.test.ts deleted file mode 100644 index 04ff8bee4c..0000000000 --- a/packages/core/src/tests/evaluation.test.ts +++ /dev/null @@ -1,128 +0,0 @@ -import dotenv from "dotenv"; -import fact from "../src/evaluators/fact.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { - TEST_EVALUATOR, - TEST_EVALUATOR_FAIL, -} from "../src/test_resources/testEvaluator.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { composeContext } from "../src/context.ts"; -import { evaluationTemplate } from "../src/evaluators.ts"; -import { IAgentRuntime, Memory, UUID } from "../src/types.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Evaluation Process", () => { - let runtime: IAgentRuntime; - let user: User; - let roomId: UUID; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - evaluators: [TEST_EVALUATOR, TEST_EVALUATOR_FAIL], - }); - runtime = setup.runtime; - user = setup.session.user; - - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data!.roomId; - }); - - test("Validate the format of the examples from the evaluator", () => { - expect(TEST_EVALUATOR.examples).toBeInstanceOf(Array); - TEST_EVALUATOR.examples.forEach((example) => { - expect(example).toHaveProperty("context"); - expect(example).toHaveProperty("messages"); - expect(example.messages).toBeInstanceOf(Array); - example.messages.forEach((message) => { - expect(message).toHaveProperty("user"); - expect(message).toHaveProperty("content"); - expect(message.content).toHaveProperty("action"); - }); - expect(example).toHaveProperty("outcome"); - }); - }); - - test("Check if test and examples appear in state", async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "Test message for evaluation" }, - roomId, - }; - - const state = await runtime.composeState(message); - const prompt = composeContext({ state, template: evaluationTemplate }); - - // expect that the prompt contacts the testEvaluator name - expect(prompt).toContain(TEST_EVALUATOR.name); - - // check if state.EvaluatorNames contains the testEvaluator name - - expect(state.evaluatorNames).toContain(TEST_EVALUATOR.name); - }); - - test("Run the TEST_EVALUATOR handler and validate output", async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "Run TEST_EVALUATOR handler" }, - roomId, - }; - - const result = await TEST_EVALUATOR.handler(runtime, message); - expect(result).toBeTruthy(); - }); - - test("Run the evaluation process", async () => { - await runAiTest("Run the evaluation process", async () => { - const message: Memory = { - userId: user.id as UUID, - content: { - text: "We are in testing mode. We want to make sure that the test passes by replying with the evaluator TEST_EVALUATOR in the array of evaluators that are returned. Please run the TEST_EVALUATOR", - }, - roomId, - }; - - const state = await runtime.composeState(message); - const result = await runtime.evaluate(message, state); - - return result?.includes("TEST_EVALUATOR"); - }); // Adjust the timeout if needed - }, 600000); - - test("Test that fact appears in evaluation handler", async () => { - const { runtime } = await createRuntime({ - env: process.env as Record, - conversationLength: 1, - evaluators: [fact], - }); - - const message: Memory = { - userId: user.id as UUID, - content: { text: "Test message for evaluation" }, - roomId, - }; - - const state = await runtime.composeState(message); - const prompt = composeContext({ state, template: evaluationTemplate }); - - // expect that the prompt contacts the testEvaluator name - expect(prompt.includes(fact.name)).toBeTruthy(); - - // check if state.EvaluatorNames contains the testEvaluator name - - expect(state.evaluatorNames).toContain(fact.name); - }); -}); diff --git a/packages/core/src/tests/evaluators.test.ts b/packages/core/src/tests/evaluators.test.ts new file mode 100644 index 0000000000..ef9c2995c1 --- /dev/null +++ b/packages/core/src/tests/evaluators.test.ts @@ -0,0 +1,80 @@ +import { formatEvaluatorNames, formatEvaluators, formatEvaluatorExamples, formatEvaluatorExampleDescriptions } from '../evaluators'; +import { Evaluator, HandlerCallback, IAgentRuntime, Memory, State } from '../types'; + +// Mock data for evaluators +const mockEvaluators: Evaluator[] = [ + { + name: "Evaluator1", + description: "This is the first evaluator.", + examples: [ + { + context: "Context 1 with {{user1}}.", + outcome: "Outcome 1 with {{user1}}.", + messages: [ + { user: "user1", content: { text: "Message 1", action: "action1" } }, + { user: "user2", content: { text: "Message 2" } }, + ], + }, + ], + similes: [], + handler: function (_runtime: IAgentRuntime, _message: Memory, _state?: State, _options?: { [key: string]: unknown; }, _callback?: HandlerCallback): Promise { + throw new Error('Function not implemented.'); + }, + validate: function (_runtime: IAgentRuntime, _message: Memory, _state?: State): Promise { + throw new Error('Function not implemented.'); + } + }, + { + name: "Evaluator2", + description: "This is the second evaluator.", + examples: [ + { + context: "Context 2 with {{user1}} and {{user2}}.", + outcome: "Outcome 2 with {{user1}} and {{user2}}.", + messages: [ + { user: "user1", content: { text: "Message 1", action: "action1" } }, + { user: "user2", content: { text: "Message 2" } }, + ], + }, + ], + similes: [], + handler: function (_runtime: IAgentRuntime, _message: Memory, _state?: State, _options?: { [key: string]: unknown; }, _callback?: HandlerCallback): Promise { + throw new Error('Function not implemented.'); + }, + validate: function (_runtime: IAgentRuntime, _message: Memory, _state?: State): Promise { + throw new Error('Function not implemented.'); + } + }, +]; + +// Unit test for formatEvaluatorNames +test('formats evaluator names correctly', () => { + const result = formatEvaluatorNames(mockEvaluators); + expect(result).toBe("'Evaluator1',\n'Evaluator2'"); +}); + +// Unit test for formatEvaluators +test('formats evaluators correctly', () => { + const result = formatEvaluators(mockEvaluators); + expect(result).toBe( + "'Evaluator1: This is the first evaluator.',\n'Evaluator2: This is the second evaluator.'" + ); +}); + +// Unit test for formatEvaluatorExamples +test('formats evaluator examples correctly', () => { + const result = formatEvaluatorExamples(mockEvaluators); + expect(result).toContain('Context:\nContext 1 with'); + expect(result).toContain('Outcome:\nOutcome 1 with'); + expect(result).toContain('Messages:\nuser1: Message 1 (action1)'); +}); + +// Unit test for formatEvaluatorExampleDescriptions +test('formats evaluator example descriptions correctly', () => { + const result = formatEvaluatorExampleDescriptions(mockEvaluators); + expect(result).toBe( + "Evaluator1 Example 1: This is the first evaluator.\n\nEvaluator2 Example 1: This is the second evaluator." + ); +}); + +// Additional tests can be added to ensure edge cases and larger inputs are handled diff --git a/packages/core/src/tests/fact.test.d.ts b/packages/core/src/tests/fact.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/fact.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/fact.test.ts b/packages/core/src/tests/fact.test.ts deleted file mode 100644 index 01cbdbc2e9..0000000000 --- a/packages/core/src/tests/fact.test.ts +++ /dev/null @@ -1,150 +0,0 @@ -import dotenv from "dotenv"; -import { defaultActions } from "../src/actions.ts"; -import { IAgentRuntime, type Memory, type UUID } from "../src/types.ts"; -import { - getCachedEmbeddings, - writeCachedEmbedding, -} from "../src/test_resources/cache.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { - GetTellMeAboutYourselfConversation1, - GetTellMeAboutYourselfConversation2, - GetTellMeAboutYourselfConversation3, - jimFacts, -} from "../src/test_resources/data.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { type User } from "../src/test_resources/types.ts"; -import evaluator from "../src/evaluators/fact.ts"; -import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Facts Evaluator", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId = zeroUuid; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - evaluators: [evaluator], - actions: defaultActions, - }); - user = setup.session.user; - runtime = setup.runtime; - - if (!user.id) { - throw new Error("User ID is undefined"); - } - - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data.roomId; - }); - - afterAll(async () => { - await cleanup(runtime, user.id as UUID); - }); - - test("Extract facts from conversations", async () => { - await runAiTest("Extract programmer and startup facts", async () => { - await populateMemories(runtime, user, roomId, [ - GetTellMeAboutYourselfConversation1, - ]); - - const message: Memory = { - userId: user.id as UUID, - content: { text: "" }, - roomId, - }; - - const result = await evaluator.handler(runtime, message); - const resultConcatenated = result.join("\n"); - - return ( - resultConcatenated.toLowerCase().includes("programmer") && - resultConcatenated.toLowerCase().includes("startup") - ); - }); - - await runAiTest( - "Extract married fact, ignoring known facts", - async () => { - await populateMemories(runtime, user, roomId, [ - GetTellMeAboutYourselfConversation2, - GetTellMeAboutYourselfConversation3, - ]); - - await addFacts(runtime, user.id as UUID, roomId, jimFacts); - - const message: Memory = { - userId: user.id as UUID, - content: { text: "" }, - roomId, - }; - - const result = await evaluator.handler(runtime, message); - const resultConcatenated = result.join("\n"); - - return ( - !resultConcatenated.toLowerCase().includes("francisco") && - !resultConcatenated.toLowerCase().includes("38") && - resultConcatenated.toLowerCase().includes("married") - ); - } - ); - }, 120000); // Adjust the timeout as needed for your tests -}); - -async function cleanup(runtime: IAgentRuntime, roomId: UUID) { - const factsManager = new MemoryManager({ - runtime, - tableName: "facts", - }); - - await factsManager.removeAllMemories(roomId); - await runtime.messageManager.removeAllMemories(roomId); -} - -async function addFacts( - runtime: IAgentRuntime, - userId: UUID, - roomId: UUID, - facts: string[] -) { - for (const fact of facts) { - const existingEmbedding = await getCachedEmbeddings(fact); - - const factsManager = new MemoryManager({ - runtime, - tableName: "facts", - }); - - const bakedMemory = await factsManager.addEmbeddingToMemory({ - userId: userId, - content: { text: fact }, - agentId: runtime.agentId, - roomId: roomId, - embedding: existingEmbedding, - }); - - await factsManager.createMemory(bakedMemory); - - if (!existingEmbedding) { - writeCachedEmbedding(fact, bakedMemory.embedding as number[]); - // Ensure there's a slight delay for asynchronous operations to complete - await new Promise((resolve) => setTimeout(resolve, 200)); - } - } -} diff --git a/packages/core/src/tests/generation.test.ts b/packages/core/src/tests/generation.test.ts deleted file mode 100644 index b523025925..0000000000 --- a/packages/core/src/tests/generation.test.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { - generateObject, - GenerationOptions, - trimTokens, - handleProvider, -} from "../generation"; -import { createRuntime } from "../test_resources/createRuntime"; -import { ModelProviderName, ModelClass } from "../types"; -import { ZodSchema } from "zod"; -import dotenv from "dotenv"; - -dotenv.config({ path: ".dev.vars" }); - -describe("generateObject", () => { - let runtime; - - beforeAll(async () => { - // Create runtime with a mock environment - const setup = await createRuntime({ - env: process.env as Record, - }); - runtime = setup.runtime; - }); - - test("should throw an error when context is empty", async () => { - const options: GenerationOptions = { - runtime, - context: "", - modelClass: ModelClass.SMALL, - }; - - await expect(generateObject(options)).rejects.toThrow( - "generateObject context is empty" - ); - }); - - test("should handle supported provider calls", async () => { - // Mock provider and trimTokens response - const context = "Test prompt for generation"; - const provider = ModelProviderName.OPENAI; - const schema: ZodSchema = ZodSchema.any(); // Replace with a valid schema if needed - - runtime.modelProvider = provider; - - (trimTokens as jest.Mock).mockResolvedValue(context); - (handleProvider as jest.Mock).mockResolvedValue([ - { response: "Generated text" }, - ]); - - const options: GenerationOptions = { - runtime, - context, - modelClass: ModelClass.SMALL, - schema, - schemaName: "TestSchema", - schemaDescription: "A schema for testing purposes", - mode: "json", - }; - - const result = await generateObject(options); - - expect(trimTokens).toHaveBeenCalledWith( - context, - expect.any(Number), - ModelClass.SMALL - ); - expect(handleProvider).toHaveBeenCalledWith( - expect.objectContaining({ - provider, - model: expect.anything(), - schema, - schemaName: "TestSchema", - schemaDescription: "A schema for testing purposes", - }) - ); - expect(result).toEqual([{ response: "Generated text" }]); - }); - - test("should throw an error for unsupported provider", async () => { - runtime.modelProvider = "unsupportedProvider" as ModelProviderName; - - const options: GenerationOptions = { - runtime, - context: "This should fail", - modelClass: ModelClass.SMALL, - }; - - await expect(generateObject(options)).rejects.toThrow( - "Unsupported provider" - ); - }); -}); - -describe("handleProvider", () => { - let runtime; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - }); - runtime = setup.runtime; - }); - - test("should handle OpenAI provider call", async () => { - const options = { - runtime, - provider: ModelProviderName.OPENAI, - model: "text-davinci-003", - apiKey: "testApiKey", - schema: ZodSchema.any(), - schemaName: "TestSchema", - schemaDescription: "A test schema", - mode: "json", - modelOptions: { - prompt: "Test prompt", - temperature: 0.7, - maxTokens: 100, - frequencyPenalty: 0, - presencePenalty: 0, - }, - modelClass: ModelClass.SMALL, - context: "This is a test context", - }; - - (handleOpenAI as jest.Mock).mockResolvedValue([ - { response: "Generated by OpenAI" }, - ]); - - const result = await handleProvider(options); - - expect(handleOpenAI).toHaveBeenCalledWith( - expect.objectContaining({ - model: "text-davinci-003", - apiKey: "testApiKey", - schemaName: "TestSchema", - }) - ); - expect(result).toEqual([{ response: "Generated by OpenAI" }]); - }); - - test("should throw error on unsupported provider in handleProvider", async () => { - const options = { - runtime, - provider: "unsupportedProvider" as ModelProviderName, - model: "unsupportedModel", - apiKey: "testApiKey", - schema: ZodSchema.any(), - schemaName: "UnsupportedSchema", - schemaDescription: "This should fail", - mode: "json", - modelOptions: { - prompt: "Test unsupported provider", - temperature: 0.7, - maxTokens: 100, - frequencyPenalty: 0, - presencePenalty: 0, - }, - modelClass: ModelClass.SMALL, - context: "This is an unsupported provider context", - }; - - await expect(handleProvider(options)).rejects.toThrow( - "Unsupported provider" - ); - }); -}); diff --git a/packages/core/src/tests/goal.test.d.ts b/packages/core/src/tests/goal.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/goal.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/goal.test.ts b/packages/core/src/tests/goal.test.ts deleted file mode 100644 index 8120fb0e12..0000000000 --- a/packages/core/src/tests/goal.test.ts +++ /dev/null @@ -1,202 +0,0 @@ -import dotenv from "dotenv"; -import { defaultActions } from "../src/actions.ts"; -import { createGoal, getGoals } from "../src/goals.ts"; -import { - Goal, - GoalStatus, - IAgentRuntime, - Objective, - State, - type Memory, - type UUID, -} from "../src/types.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { type User } from "../src/test_resources/types.ts"; -import evaluator from "../src/evaluators/goal.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Goals Evaluator", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId: UUID; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - evaluators: [evaluator], - actions: defaultActions, - }); - user = setup.session.user; - runtime = setup.runtime; - - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data.roomId; - - await cleanup(); - }); - - afterEach(async () => { - await cleanup(); - }); - - async function cleanup() { - // delete all goals for the user - await runtime.databaseAdapter.removeAllMemories(roomId, "goals"); - } - - async function createTestGoal(name: string, objectives: Objective[]) { - const result = await createGoal({ - runtime, - goal: { - name, - status: GoalStatus.IN_PROGRESS, - roomId, - userId: user.id as UUID, - objectives, - }, - }); - return result; - } - - test("Update goal objectives based on conversation", async () => { - await runAiTest( - "Update goal objectives based on conversation", - async () => { - await cleanup(); - - await createTestGoal("Test Goal", [ - { description: "Complete task 1", completed: false }, - { description: "Complete task 2", completed: false }, - ]); - - // Simulate a conversation indicating failure to achieve "Goal Y" - const conversation = (userId: UUID) => [ - { - userId, - content: { - text: "I see that you've finished the task?", - }, - }, - { - userId: zeroUuid, - content: { - text: "Yes, the task and all objectives are finished.", - }, - }, - ]; - - await populateMemories(runtime, user, roomId, [conversation]); - - // Simulate a conversation indicating the generateText of both objectives - const message: Memory = { - userId: user.id as UUID, - content: { - text: "I've completed task 1 and task 2 for the Test Goal. Both are finished. Everything is done and I'm ready for the next goal.", - }, - roomId, - }; - - // Process the message with the goal evaluator - await evaluator.handler( - runtime, - message, - {} as unknown as State, - { - onlyInProgress: false, - } - ); - - // Fetch the updated goal to verify the objectives and status were updated - const updatedGoals = await getGoals({ - runtime, - roomId, - onlyInProgress: false, - }); - - const updatedTestGoal = updatedGoals.find( - (goal: Goal) => goal.name === "Test Goal" - ); - - return ( - updatedTestGoal !== undefined && - updatedTestGoal.status === GoalStatus.DONE && - updatedTestGoal.objectives.every( - (obj: Objective) => obj.completed - ) - ); - } - ); - }, 60000); - - test("Goal status updated to FAILED based on conversation", async () => { - await runAiTest( - "Goal status updated to FAILED based on conversation", - async () => { - await cleanup(); - // Preparing the test goal "Goal Y" - await createTestGoal("Goal Y", [ - { - description: "Complete all tasks for Goal Y", - completed: false, - }, - ]); - - // Simulate a conversation indicating failure to achieve "Goal Y" - const conversation = (userId: UUID) => [ - { - userId, - content: { - text: "I couldn't complete the tasks for Goal Y.", - }, - }, - { - userId: zeroUuid, - content: { - text: "That's unfortunate. Let's cancel it..", - }, - }, - ]; - - await populateMemories(runtime, user, roomId, [conversation]); - - const message: Memory = { - userId: user.id as UUID, - content: { text: "I've decided to mark Goal Y as failed." }, - roomId, - }; - - await evaluator.handler(runtime, message, {} as State, { - onlyInProgress: false, - }); - - const goals = await getGoals({ - runtime, - roomId, - onlyInProgress: false, - }); - - const goalY = goals.find( - (goal: Goal) => goal.name === "Goal Y" - ); - - return ( - goalY !== undefined && goalY.status === GoalStatus.FAILED - ); - } - ); - }, 60000); -}); diff --git a/packages/core/src/tests/goals.test.d.ts b/packages/core/src/tests/goals.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/goals.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/goals.test.ts b/packages/core/src/tests/goals.test.ts index 872073a39a..65f0adde2d 100644 --- a/packages/core/src/tests/goals.test.ts +++ b/packages/core/src/tests/goals.test.ts @@ -1,123 +1,209 @@ -import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { createGoal, getGoals, updateGoal } from "../src/goals.ts"; -import { - GoalStatus, - IAgentRuntime, - type Goal, - type UUID, -} from "../src/types.ts"; - -dotenv.config({ path: ".dev.vars" }); -describe("Goals", () => { - let runtime: IAgentRuntime; - let user: User; - beforeAll(async () => { - const result = await createRuntime({ - env: process.env as Record, - }); - runtime = result.runtime; - user = result.session.user; - await runtime.databaseAdapter.removeAllGoals(zeroUuid); - }); +import { getGoals, formatGoalsAsString, updateGoal, createGoal } from "../goals"; +import { type Goal, type IAgentRuntime, type UUID, Action, GoalStatus, HandlerCallback, IMemoryManager, Memory, ModelProviderName, Service, State } from "../types"; - beforeEach(async () => { - await runtime.databaseAdapter.removeAllGoals(zeroUuid); - }); +// Mock the database adapter +const mockDatabaseAdapter = { + getGoals: jest.fn(), + updateGoal: jest.fn(), + createGoal: jest.fn(), +}; - afterAll(async () => { - await runtime.databaseAdapter.removeAllGoals(zeroUuid); - }); +// Mock the runtime +const mockRuntime: IAgentRuntime = { + databaseAdapter: mockDatabaseAdapter as any, + agentId: "qweqew-qweqwe-qweqwe-qweqwe-qweeqw", + serverUrl: "", + token: "", + modelProvider: ModelProviderName.OPENAI, + character: { + id: "qweqew-qweqwe-qweqwe-qweqwe-qweeqw", + name: "", + system: "", + modelProvider: ModelProviderName.OPENAI, + modelEndpointOverride: "", + templates: {}, + bio: "", + lore: [], + messageExamples: [], + postExamples: [], + people: [], + topics: [], + adjectives: [], + knowledge: [], + clients: [], + plugins: [], + settings: { + secrets: {}, + voice: { + model: "", + url: "" + }, + model: "", + embeddingModel: "" + }, + clientConfig: { + discord: { + shouldIgnoreBotMessages: false, + shouldIgnoreDirectMessages: false + }, + telegram: { + shouldIgnoreBotMessages: false, + shouldIgnoreDirectMessages: false + } + }, + style: { + all: [], + chat: [], + post: [] + } + }, + providers: [], + actions: [], + evaluators: [], + messageManager: undefined, + descriptionManager: undefined, + loreManager: undefined, + services: undefined, + registerMemoryManager: function (_manager: IMemoryManager): void { + throw new Error("Function not implemented."); + }, + getMemoryManager: function (_name: string): IMemoryManager | null { + throw new Error("Function not implemented."); + }, + registerService: function (_service: Service): void { + throw new Error("Function not implemented."); + }, + getSetting: function (_key: string): string | null { + throw new Error("Function not implemented."); + }, + getConversationLength: function (): number { + throw new Error("Function not implemented."); + }, + processActions: function (_message: Memory, _responses: Memory[], _state?: State, _callback?: HandlerCallback): Promise { + throw new Error("Function not implemented."); + }, + evaluate: function (_message: Memory, _state?: State, _didRespond?: boolean): Promise { + throw new Error("Function not implemented."); + }, + ensureParticipantExists: function (_userId: UUID, _roomId: UUID): Promise { + throw new Error("Function not implemented."); + }, + ensureUserExists: function (_userId: UUID, _userName: string | null, _name: string | null, _source: string | null): Promise { + throw new Error("Function not implemented."); + }, + registerAction: function (_action: Action): void { + throw new Error("Function not implemented."); + }, + ensureConnection: function (_userId: UUID, _roomId: UUID, _userName?: string, _userScreenName?: string, _source?: string): Promise { + throw new Error("Function not implemented."); + }, + ensureParticipantInRoom: function (_userId: UUID, _roomId: UUID): Promise { + throw new Error("Function not implemented."); + }, + ensureRoomExists: function (_roomId: UUID): Promise { + throw new Error("Function not implemented."); + }, + composeState: function (_message: Memory, _additionalKeys?: { [key: string]: unknown; }): Promise { + throw new Error("Function not implemented."); + }, + updateRecentMessageState: function (_state: State): Promise { + throw new Error("Function not implemented."); + }, + getService: function (_service: string): typeof Service | null { + throw new Error("Function not implemented."); + } +}; + +// Sample data +const sampleGoal: Goal = { + id: "goal-id" as UUID, + name: "Test Goal", + roomId: "room-id" as UUID, + userId: "user-id" as UUID, + objectives: [ + { description: "Objective 1", completed: false }, + { description: "Objective 2", completed: true }, + ], + status: GoalStatus.IN_PROGRESS, +}; + +describe("getGoals", () => { + it("retrieves goals successfully", async () => { + (mockDatabaseAdapter.getGoals as jest.Mock).mockResolvedValue([sampleGoal]); - test("createGoal - successfully creates a new goal", async () => { - const newGoal: Goal = { - name: "Test Create Goal", - status: GoalStatus.IN_PROGRESS, - roomId: zeroUuid, - userId: user?.id as UUID, - objectives: [ - { - description: "Test Objective", - completed: false, - }, - ], - }; - - await createGoal({ - runtime, - goal: newGoal, + const result = await getGoals({ + runtime: mockRuntime, + roomId: "room-id" as UUID, }); - // Verify the goal is created in the database - const goals = await getGoals({ - runtime, - userId: user?.id as UUID, - roomId: zeroUuid, - onlyInProgress: false, + expect(result).toEqual([sampleGoal]); + expect(mockDatabaseAdapter.getGoals).toHaveBeenCalledWith({ + roomId: "room-id", + userId: undefined, + onlyInProgress: true, + count: 5, }); + }); - const createdGoal = goals.find( - (goal: Goal) => goal.name === newGoal.name + it("handles failure to retrieve goals", async () => { + (mockDatabaseAdapter.getGoals as jest.Mock).mockRejectedValue( + new Error("Failed to retrieve goals") ); - expect(createdGoal).toBeDefined(); - expect(createdGoal?.status).toEqual("IN_PROGRESS"); - expect(createdGoal?.objectives.length).toBeGreaterThan(0); + await expect( + getGoals({ runtime: mockRuntime, roomId: "room-id" as UUID }) + ).rejects.toThrow("Failed to retrieve goals"); }); +}); - // Updating an existing goal - test("updateGoals - successfully updates an existing goal", async () => { - const newGoal: Goal = { - name: "Test Create Goal", - status: GoalStatus.IN_PROGRESS, - roomId: zeroUuid, - userId: user?.id as UUID, - objectives: [ - { - description: "Test Objective", - completed: false, - }, - ], - }; - - await createGoal({ - runtime, - goal: newGoal, - }); +describe("formatGoalsAsString", () => { + it("formats goals correctly", () => { + const formatted = formatGoalsAsString({ goals: [sampleGoal] }); + expect(formatted).toContain("Goal: Test Goal"); + expect(formatted).toContain("- [ ] Objective 1 (IN PROGRESS)"); + expect(formatted).toContain("- [x] Objective 2 (DONE)"); + }); - // retrieve the goal from the database - let goals = await getGoals({ - runtime, - roomId: zeroUuid, - onlyInProgress: false, - }); - const existingGoal = goals.find( - (goal: Goal) => goal.name === newGoal.name - ) as Goal; - const updatedGoal = { ...existingGoal, status: GoalStatus.DONE }; - await updateGoal({ - runtime, - goal: updatedGoal, - }); + it("handles empty goal list", () => { + const formatted = formatGoalsAsString({ goals: [] }); + expect(formatted).toBe(""); + }); +}); - // Verify the goal's status is updated in the database - goals = await getGoals({ - runtime, - roomId: zeroUuid, - onlyInProgress: false, - }); +describe("updateGoal", () => { + it("updates a goal successfully", async () => { + (mockDatabaseAdapter.updateGoal as jest.Mock).mockResolvedValue(undefined); + + await expect(updateGoal({ runtime: mockRuntime, goal: sampleGoal })).resolves.toBeUndefined(); + expect(mockDatabaseAdapter.updateGoal).toHaveBeenCalledWith(sampleGoal); + }); - const updatedGoalInDb = goals.find( - (goal: Goal) => goal.id === existingGoal.id + it("handles failure to update a goal", async () => { + (mockDatabaseAdapter.updateGoal as jest.Mock).mockRejectedValue( + new Error("Failed to update goal") ); - expect(updatedGoalInDb?.status).toEqual(GoalStatus.DONE); + await expect(updateGoal({ runtime: mockRuntime, goal: sampleGoal })).rejects.toThrow( + "Failed to update goal" + ); + }); +}); + +describe("createGoal", () => { + it("creates a goal successfully", async () => { + (mockDatabaseAdapter.createGoal as jest.Mock).mockResolvedValue(undefined); - // Clean up the created goal - if (existingGoal?.id) { - await runtime.databaseAdapter.removeGoal(existingGoal.id); - } + await expect(createGoal({ runtime: mockRuntime, goal: sampleGoal })).resolves.toBeUndefined(); + expect(mockDatabaseAdapter.createGoal).toHaveBeenCalledWith(sampleGoal); + }); + + it("handles failure to create a goal", async () => { + (mockDatabaseAdapter.createGoal as jest.Mock).mockRejectedValue( + new Error("Failed to create goal") + ); + + await expect(createGoal({ runtime: mockRuntime, goal: sampleGoal })).rejects.toThrow( + "Failed to create goal" + ); }); }); diff --git a/packages/core/src/tests/ignore.test.d.ts b/packages/core/src/tests/ignore.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/ignore.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/ignore.test.ts b/packages/core/src/tests/ignore.test.ts deleted file mode 100644 index 28746f6068..0000000000 --- a/packages/core/src/tests/ignore.test.ts +++ /dev/null @@ -1,228 +0,0 @@ -import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { composeContext } from "../src/context.ts"; -import { embeddingZeroVector } from "../src/memory.ts"; -import { - Content, - IAgentRuntime, - Memory, - ModelClass, - State, - type UUID, -} from "../src/types.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { - GetTellMeAboutYourselfConversationTroll1, - GetTellMeAboutYourselfConversationTroll2, - Goodbye1, -} from "../src/test_resources/data.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { messageHandlerTemplate } from "../src/test_resources/templates.ts"; -import { type User } from "../src/test_resources/types.ts"; -import action from "../src/actions/ignore.ts"; -import { generateMessageResponse } from "../src/generation.ts"; -import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; - -async function handleMessage( - runtime: IAgentRuntime, - message: Memory, - state?: State -) { - const _saveRequestMessage = async (message: Memory, state: State) => { - const { content: senderContent, userId, roomId } = message; - - const _senderContent = (senderContent as Content).text?.trim(); - if (_senderContent) { - await runtime.messageManager.createMemory({ - userId: userId!, - content: { - text: _senderContent, - action: (message.content as Content)?.action ?? "null", - }, - roomId, - embedding: embeddingZeroVector, - }); - } - }; - - await _saveRequestMessage(message, state as State); - if (!state) { - state = (await runtime.composeState(message)) as State; - } - - const context = composeContext({ - state, - template: messageHandlerTemplate, - }); - - const { userId, roomId } = message; - - const response = await generateMessageResponse({ - context, - runtime, - modelClass: ModelClass.SMALL, - }); - - await runtime.databaseAdapter.log({ - body: { message, context, response }, - userId: userId, - roomId, - type: "ignore_test_completion", - }); - - const responseMessage: Memory = { - userId: runtime.agentId, - content: response, - roomId, - embedding: embeddingZeroVector, - }; - - if (responseMessage.content.text?.trim()) { - await runtime.messageManager.createMemory(responseMessage); - await runtime.evaluate(message, state); - await runtime.processActions(message, [responseMessage]); - } else { - console.warn("Empty response, skipping"); - } - - return responseMessage; -} - -// use .dev.vars for local testing -dotenv.config({ path: ".dev.vars" }); - -describe("Ignore action tests", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId: UUID; - - afterAll(async () => { - await cleanup(); - }); - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - actions: [action], - }); - user = setup.session.user; - runtime = setup.runtime; - - const data = await getOrCreateRelationship({ - runtime, - userA: user?.id as UUID, - userB: zeroUuid, - }); - - console.log("data is", data); - - roomId = data?.roomId; - console.log("*** data", data); - console.log("Room ID", roomId); - - await cleanup(); - }); - - beforeEach(async () => { - await cleanup(); - }); - - async function cleanup() { - const factsManager = new MemoryManager({ - runtime, - tableName: "facts", - }); - await factsManager.removeAllMemories(roomId); - await runtime.messageManager.removeAllMemories(roomId); - } - - test("Test ignore action", async () => { - await runAiTest("Test ignore action", async () => { - const message: Memory = { - userId: user?.id as UUID, - content: { text: "Never talk to me again" }, - roomId: roomId as UUID, - }; - - await populateMemories(runtime, user, roomId, [ - GetTellMeAboutYourselfConversationTroll1, - ]); - - const result = await handleMessage(runtime, message); - - return result.content.action === "IGNORE"; - }); - }, 120000); - - test("Action handler test 1: response should be ignore", async () => { - await runAiTest( - "Action handler test 1: response should be ignore", - async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "", action: "IGNORE" }, - roomId: roomId as UUID, - }; - - await populateMemories(runtime, user, roomId, [ - GetTellMeAboutYourselfConversationTroll1, - ]); - - await handleMessage(runtime, message); - - const state = await runtime.composeState(message); - - const lastMessage = state.recentMessagesData[0]; - - return (lastMessage.content as Content).action === "IGNORE"; - } - ); - }, 120000); - - test("Action handler test 2: response should be ignore", async () => { - await runAiTest( - "Action handler test 2: response should be ignore", - async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "", action: "IGNORE" }, - roomId: roomId as UUID, - }; - - await populateMemories(runtime, user, roomId, [ - GetTellMeAboutYourselfConversationTroll2, - ]); - - await handleMessage(runtime, message); - - const state = await runtime.composeState(message); - - const lastMessage = state.recentMessagesData[0]; - - return (lastMessage.content as Content).action === "IGNORE"; - } - ); - }, 120000); - - test("Expect ignore", async () => { - await runAiTest("Expect ignore", async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "Bye" }, - roomId: roomId as UUID, - }; - - await populateMemories(runtime, user, roomId, [Goodbye1]); - - await handleMessage(runtime, message); - - const state = await runtime.composeState(message); - - const lastMessage = state.recentMessagesData[0]; - - return (lastMessage.content as Content).action === "IGNORE"; - }); - }, 120000); -}); diff --git a/packages/core/src/tests/memory.test.d.ts b/packages/core/src/tests/memory.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/memory.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/memory.test.ts b/packages/core/src/tests/memory.test.ts deleted file mode 100644 index d77f515256..0000000000 --- a/packages/core/src/tests/memory.test.ts +++ /dev/null @@ -1,617 +0,0 @@ -import dotenv from "dotenv"; -import { - getCachedEmbeddings, - writeCachedEmbedding, -} from "../src/test_resources/cache.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { MemoryManager } from "../src/memory.ts"; -import { type Content, type Memory, type UUID } from "../src/types.ts"; -import { embed } from "../src/embedding.ts"; - -dotenv.config({ path: ".dev.vars" }); -describe("Memory", () => { - let memoryManager: MemoryManager; - let runtime = null; - let user: User; - let roomId: UUID = zeroUuid; - - beforeAll(async () => { - const result = await createRuntime({ - env: process.env as Record, - }); - runtime = result.runtime; - user = result.session.user; - - const data = await getOrCreateRelationship({ - runtime, - userA: user?.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data.roomId; - - memoryManager = new MemoryManager({ - tableName: "messages", - runtime, - }); - }); - - beforeEach(async () => { - await memoryManager.removeAllMemories(roomId); - }); - - afterAll(async () => { - await memoryManager.removeAllMemories(roomId); - }); - - test("Search memories by embedding similarity", async () => { - // Define a base memory and two additional memories, one similar and one dissimilar - const baseMemoryContent = "Base memory content for testing similarity"; - const similarMemoryContent = - "Base memory content for testing similarity - Similar memory content to the base memory"; - const dissimilarMemoryContent = - "Dissimilar memory content, not related"; - - // Create and add embedding to the base memory - const baseMemory = await embed( - memoryManager.runtime, - baseMemoryContent - ); - - let embedding = await getCachedEmbeddings(similarMemoryContent); - - // Create and add embedding to the similar and dissimilar memories - const similarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: similarMemoryContent }, - roomId: roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - similarMemoryContent, - similarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(similarMemory); - - embedding = await getCachedEmbeddings(dissimilarMemoryContent); - - const dissimilarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: dissimilarMemoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - dissimilarMemoryContent, - dissimilarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(dissimilarMemory); - - // Search for memories similar to the base memory - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - baseMemory!, - { - roomId, - count: 1, - } - ); - - // Check that the similar memory is included in the search results and the dissimilar one is not or ranks lower - expect( - searchedMemories.some( - (memory) => - (memory.content as Content).text === similarMemoryContent - ) - ).toBe(true); - expect( - searchedMemories.some( - (memory) => - (memory.content as Content).text === dissimilarMemoryContent - ) - ).toBe(false); - }, 60000); - - test("Verify memory similarity and ranking", async () => { - // Define a set of memories with varying degrees of similarity - const queryMemoryContent = - "High similarity content to the query memory"; - const highSimilarityContent = - "High similarity content to the query memory"; - const lowSimilarityContent = - "Low similarity content compared to the query"; - - let embedding = await getCachedEmbeddings(queryMemoryContent); - - // Create and add embedding to the query memory - const queryMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: queryMemoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - queryMemoryContent, - queryMemory.embedding as number[] - ); - } - await memoryManager.createMemory(queryMemory); - - embedding = await getCachedEmbeddings(highSimilarityContent); - // Create and add embedding to the high and low similarity memories - const highSimilarityMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: highSimilarityContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - highSimilarityContent, - highSimilarityMemory.embedding as number[] - ); - } - await memoryManager.createMemory(highSimilarityMemory); - - embedding = await getCachedEmbeddings(lowSimilarityContent); - const lowSimilarityMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: lowSimilarityContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - lowSimilarityContent, - lowSimilarityMemory.embedding as number[] - ); - } - await memoryManager.createMemory(lowSimilarityMemory); - - // Search for memories similar to the query memory - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - queryMemory.embedding!, - { - roomId, - count: 10, - } - ); - - // Check that the high similarity memory ranks higher than the low similarity memory - const highSimilarityIndex = searchedMemories.findIndex( - (memory) => - (memory.content as Content).text === highSimilarityContent - ); - const lowSimilarityIndex = searchedMemories.findIndex( - (memory) => - (memory.content as Content).text === lowSimilarityContent - ); - - expect(highSimilarityIndex).toBeLessThan(lowSimilarityIndex); - }, 60000); -}); -describe("Memory - Basic tests", () => { - let memoryManager: MemoryManager; - let runtime = null; - let user: User; - let roomId: UUID; - - // Setup before all tests - beforeAll(async () => { - const result = await createRuntime({ - env: process.env as Record, - }); - runtime = result.runtime; - user = result.session.user; - - const data = await getOrCreateRelationship({ - runtime, - userA: user?.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data.roomId; - - memoryManager = new MemoryManager({ - tableName: "messages", // Adjust based on your actual table name - runtime, - }); - }); - - // Cleanup after all tests - afterAll(async () => { - await memoryManager.removeAllMemories(roomId); - }); - - test("Memory lifecycle: create, search, count, and remove", async () => { - const embedding = await getCachedEmbeddings( - "Test content for memory lifecycle" - ); - // Create a test memory - const testMemory: Memory = await memoryManager.addEmbeddingToMemory({ - userId: user.id as UUID, - content: { text: "Test content for memory lifecycle" }, - roomId: roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - (testMemory.content as Content).text as string, - testMemory.embedding as number[] - ); - } - await memoryManager.createMemory(testMemory); - - const createdMemories = await memoryManager.getMemories({ - roomId, - agentId: runtime.agentId, - count: 100, - }); - - // Verify creation by counting memories - const initialCount = await memoryManager.countMemories(roomId, false); - expect(initialCount).toBeGreaterThan(0); - - // Search memories by embedding - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - testMemory.embedding!, - { - roomId, - count: 5, - } - ); - expect(searchedMemories.length).toBeGreaterThan(0); - - // Remove a specific memory - await memoryManager.removeMemory(createdMemories[0].id!); - const afterRemovalCount = await memoryManager.countMemories(roomId); - expect(afterRemovalCount).toBeLessThan(initialCount); - - // Remove all memories for the test user - await memoryManager.removeAllMemories(roomId); - const finalCount = await memoryManager.countMemories(roomId); - expect(finalCount).toEqual(0); - }); -}); -describe("Memory - Extended Tests", () => { - let memoryManager: MemoryManager; - let runtime = null; - let user: User; - let roomId: UUID; - - beforeAll(async () => { - const result = await createRuntime({ - env: process.env as Record, - }); - runtime = result.runtime; - user = result.session.user; - - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - roomId = data.roomId; - - if (!roomId) throw new Error("Room not found"); - - memoryManager = new MemoryManager({ - tableName: "messages", - runtime, - }); - }); - - beforeEach(async () => { - await memoryManager.removeAllMemories(roomId); - }); - - afterAll(async () => { - await memoryManager.removeAllMemories(roomId); - }); - - test("Test cosine similarity value equality", async () => { - // Define a base memory and two additional memories, one similar and one dissimilar - const baseMemoryContent = "Base memory content for testing similarity"; - const similarMemoryContent = - "Base memory content for testing similarity"; - - // Create and add embedding to the base memory - const baseMemory = await embed( - memoryManager.runtime, - baseMemoryContent - ); - - const embedding = await getCachedEmbeddings(similarMemoryContent); - - // Create and add embedding to the similar and dissimilar memories - const similarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: similarMemoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - similarMemoryContent, - similarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(similarMemory); - - // Search for memories similar to the base memory - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - baseMemory!, - { - roomId, - count: 1, - } - ); - - const memory = searchedMemories[0]; - - const similarity = (memory as unknown as { similarity: number }) - .similarity; - expect(similarity).toBeGreaterThan(0.9); - }); - - test("Test cosine similarity value inequality", async () => { - // Define a base memory and two additional memories, one similar and one dissimilar - const baseMemoryContent = "i love u"; - const similarMemoryContent = - "Cognitive security in the information age"; - - // Create and add embedding to the base memory - const baseMemory = await embed( - memoryManager.runtime, - baseMemoryContent - ); - - const embedding = await getCachedEmbeddings(similarMemoryContent); - - // Create and add embedding to the similar and dissimilar memories - const similarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: similarMemoryContent }, - roomId: roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - similarMemoryContent, - similarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(similarMemory); - - // Search for memories similar to the base memory - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - baseMemory!, - { - match_threshold: 0.01, - roomId, - count: 1, - } - ); - - const memory = searchedMemories[0]; - - const similarity = (memory as unknown as { similarity: number }) - .similarity; - - expect(similarity).toBeLessThan(0.2); - }); - - test("Test unique insert", async () => { - // Define a base memory and two additional memories, one similar and one dissimilar - const memoryContent = "Cognitive security in the information age"; - const similarMemoryContent = - "Cognitive security in the information age"; - - let embedding = await getCachedEmbeddings(memoryContent); - - // Create and add embedding to the similar and dissimilar memories - const newMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: memoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - memoryContent, - newMemory.embedding as number[] - ); - } - await memoryManager.createMemory(newMemory, true); - - embedding = await getCachedEmbeddings(similarMemoryContent); - - // Create and add embedding to the similar and dissimilar memories - const similarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: similarMemoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - similarMemoryContent, - similarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(similarMemory, true); - - const allCount = await memoryManager.countMemories(roomId, false); - const uniqueCount = await memoryManager.countMemories(roomId, true); - - expect(allCount > uniqueCount).toBe(true); - }); - - test("Search memories by embedding similarity", async () => { - // Define a base memory and two additional memories, one similar and one dissimilar - const baseMemoryContent = "Base memory content for testing similarity"; - const similarMemoryContent = - "Base memory content for testing similarity 2"; - const dissimilarMemoryContent = "Dissimilar, not related"; - - // Create and add embedding to the base memory - const baseMemory = await embed( - memoryManager.runtime, - baseMemoryContent - ); - - let embedding = await getCachedEmbeddings(similarMemoryContent); - - // Create and add embedding to the similar and dissimilar memories - const similarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: similarMemoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - similarMemoryContent, - similarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(similarMemory); - - embedding = await getCachedEmbeddings(dissimilarMemoryContent); - - const dissimilarMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: dissimilarMemoryContent }, - roomId, - embedding: await getCachedEmbeddings(dissimilarMemoryContent), - }); - if (!embedding) { - writeCachedEmbedding( - dissimilarMemoryContent, - dissimilarMemory.embedding as number[] - ); - } - await memoryManager.createMemory(dissimilarMemory); - - // Search for memories similar to the base memory - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - baseMemory!, - { - roomId, - count: 1, - } - ); - - // Check that the similar memory is included in the search results and the dissimilar one is not or ranks lower - expect( - searchedMemories.some( - (memory) => - (memory.content as Content).text === similarMemoryContent - ) - ).toBe(true); - expect( - searchedMemories.some( - (memory) => - (memory.content as Content).text === dissimilarMemoryContent - ) - ).toBe(false); - }, 60000); - - test("Verify memory similarity and ranking", async () => { - // Define a set of memories with varying degrees of similarity - const queryMemoryContent = - "High similarity content to the query memory"; - const highSimilarityContent = - "High similarity content to the query memory"; - const lowSimilarityContent = "Low similarity, not related"; - - let embedding = await getCachedEmbeddings(queryMemoryContent); - - // Create and add embedding to the query memory - const queryMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: queryMemoryContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - queryMemoryContent, - queryMemory.embedding as number[] - ); - } - await memoryManager.createMemory(queryMemory); - - embedding = await getCachedEmbeddings(highSimilarityContent); - // Create and add embedding to the high and low similarity memories - const highSimilarityMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: highSimilarityContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - highSimilarityContent, - highSimilarityMemory.embedding as number[] - ); - } - await memoryManager.createMemory(highSimilarityMemory); - - embedding = await getCachedEmbeddings(lowSimilarityContent); - const lowSimilarityMemory = await memoryManager.addEmbeddingToMemory({ - userId: user?.id as UUID, - content: { text: lowSimilarityContent }, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - lowSimilarityContent, - lowSimilarityMemory.embedding as number[] - ); - } - await memoryManager.createMemory(lowSimilarityMemory); - - // Search for memories similar to the query memory - const searchedMemories = await memoryManager.searchMemoriesByEmbedding( - queryMemory.embedding!, - { - roomId, - count: 10, - } - ); - - // Check that the high similarity memory ranks higher than the low similarity memory - const highSimilarityIndex = searchedMemories.findIndex( - (memory) => - (memory.content as Content).text === highSimilarityContent - ); - const lowSimilarityIndex = searchedMemories.findIndex( - (memory) => - (memory.content as Content).text === lowSimilarityContent - ); - - expect(highSimilarityIndex).toBeLessThan(lowSimilarityIndex); - }, 60000); -}); diff --git a/packages/core/src/tests/messages.test.d.ts b/packages/core/src/tests/messages.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/messages.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/messages.test.ts b/packages/core/src/tests/messages.test.ts deleted file mode 100644 index 02e2c1107a..0000000000 --- a/packages/core/src/tests/messages.test.ts +++ /dev/null @@ -1,114 +0,0 @@ -import dotenv from "dotenv"; -import { formatFacts } from "../src/evaluators/fact.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { - formatActors, - formatMessages, - getActorDetails, -} from "../src/messages.ts"; -import { createRelationship } from "../src/relationships.ts"; -import { - IAgentRuntime, - type Actor, - type Content, - type Memory, - type UUID, -} from "../src/types.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Messages Library", () => { - let runtime: IAgentRuntime, user: User, actors: Actor[]; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - }); - runtime = setup.runtime; - user = setup.session.user; - actors = await getActorDetails({ - runtime, - roomId: "00000000-0000-0000-0000-000000000000", - }); - }); - - test("getActorDetails should return actors based on given roomId", async () => { - // create a room and add a user to it - const userA = user?.id as UUID; - const userB = zeroUuid; - - await createRelationship({ - runtime, - userA, - userB, - }); - - const { roomId } = await getOrCreateRelationship({ - runtime, - userA, - userB, - }); - - const result = await getActorDetails({ - runtime, - roomId, - }); - - expect(result.length).toBeGreaterThan(0); - result.forEach((actor: Actor) => { - expect(actor).toHaveProperty("name"); - expect(actor).toHaveProperty("details"); - expect(actor).toHaveProperty("id"); - }); - }); - - test("formatActors should format actors into a readable string", () => { - const formattedActors = formatActors({ actors }); - actors.forEach((actor) => { - expect(formattedActors).toContain(actor.name); - }); - }); - - test("formatMessages should format messages into a readable string", async () => { - const messages: Memory[] = [ - { - content: { text: "Hello" }, - userId: user.id as UUID, - roomId: "00000000-0000-0000-0000-000000000000", - }, - { - content: { text: "How are you?" }, - userId: "00000000-0000-0000-0000-000000000000", - roomId: "00000000-0000-0000-0000-000000000000", - }, - ]; - const formattedMessages = formatMessages({ messages, actors }); - messages.forEach((message: Memory) => { - expect(formattedMessages).toContain( - (message.content as Content).text - ); - }); - }); - - test("formatFacts should format facts into a readable string", async () => { - const facts: Memory[] = [ - { - content: { text: "Reflecting on the day" }, - userId: user.id as UUID, - roomId: "00000000-0000-0000-0000-000000000000", - }, - { - content: { text: "Thoughts and musings" }, - userId: "00000000-0000-0000-0000-000000000000", - roomId: "00000000-0000-0000-0000-000000000000room", - }, - ]; - const formattedFacts = formatFacts(facts); - facts.forEach((fact) => { - expect(formattedFacts).toContain(fact.content.text); - }); - }); -}); diff --git a/packages/core/src/tests/models.test.ts b/packages/core/src/tests/models.test.ts new file mode 100644 index 0000000000..02320de7eb --- /dev/null +++ b/packages/core/src/tests/models.test.ts @@ -0,0 +1,33 @@ +import { getModel, getEndpoint } from '../models.ts'; +import { ModelProviderName, ModelClass } from '../types.ts'; + +describe('Model Provider Tests', () => { + test('should retrieve the correct model for OpenAI SMALL', () => { + const model = getModel(ModelProviderName.OPENAI, ModelClass.SMALL); + expect(model).toBe('gpt-4o-mini'); + }); + + test('should retrieve the correct model for Google MEDIUM', () => { + const model = getModel(ModelProviderName.GOOGLE, ModelClass.MEDIUM); + expect(model).toBe('gemini-1.5-flash-latest'); + }); + + test('should retrieve the correct model for Groq LARGE', () => { + const model = getModel(ModelProviderName.GROQ, ModelClass.LARGE); + expect(model).toBe('llama-3.2-90b-text-preview'); + }); + + test('should retrieve the correct endpoint for OpenAI', () => { + const endpoint = getEndpoint(ModelProviderName.OPENAI); + expect(endpoint).toBe('https://api.openai.com/v1'); + }); + + test('should retrieve the correct endpoint for Anthropic', () => { + const endpoint = getEndpoint(ModelProviderName.ANTHROPIC); + expect(endpoint).toBe('https://api.anthropic.com/v1'); + }); + + test('should handle invalid model provider', () => { + expect(() => getModel('INVALID_PROVIDER' as any, ModelClass.SMALL)).toThrow(); + }); +}); diff --git a/packages/core/src/tests/posts.test.ts b/packages/core/src/tests/posts.test.ts new file mode 100644 index 0000000000..9110ad07b5 --- /dev/null +++ b/packages/core/src/tests/posts.test.ts @@ -0,0 +1,101 @@ +import { formatPosts } from '../posts.ts'; +import { Actor, Memory } from '../types.ts'; + +// Mocked data with consistent conversation IDs +const mockActors: Actor[] = [ + { + id: 'f9c8b107-953b-473d-8c87-2894c6e3fe25', name: 'Alice', username: 'alice123', + details: { + tagline: 'The quick brown fox', + summary: 'Lorem ipsum dolor sit amet.', + quote: 'To be or not to be.' + } + }, + { + id: 'e4928cd1-8007-40b1-93ff-7c5da3c39e36', name: 'Bob', username: 'bob456', + details: { + tagline: 'A journey of a thousand miles', + summary: 'Sed ut perspiciatis unde omnis iste.', + quote: 'Knowledge is power.' + } + }, + { + id: 'b62e64da-5699-4c8e-b58c-8d447b2f2014', name: 'Charlie', username: 'charlie789', + details: { + tagline: 'Hello, world!', + summary: 'Lorem ipsum dolor sit.', + quote: 'Live and let live.' + } + }, +]; + +const mockMessages: Memory[] = [ + { + id: '0db429f4-9ad9-44db-b2c6-0cf6d6cb2dfe', + userId: 'f9c8b107-953b-473d-8c87-2894c6e3fe25', + roomId: 'aae8df56-e890-4876-a3ba-2cbfc94cbd97', + createdAt: 2000, + content: { text: 'Hi Bob, how are you?', inReplyTo: 'f9c8b107-953b-473d-8c87-2894c6e3fe25' }, + agentId: 'f9c8b107-953b-473d-8c87-2894c6e3fe25' + }, + { + id: 'cdb70b0f-bcfe-44ea-b940-1d7e7e981768', + userId: 'e4928cd1-8007-40b1-93ff-7c5da3c39e36', + roomId: 'aae8df56-e890-4876-a3ba-2cbfc94cbd97', + createdAt: 2500, + content: { text: 'Hi Alice, how are you?', inReplyTo: 'f9c8b107-953b-473d-8c87-2894c6e3fe25' }, + agentId: 'e4928cd1-8007-40b1-93ff-7c5da3c39e36' + }, + { + id: '88297c98-3d95-4ab5-9c88-b7f01e10f7a7', + userId: 'b62e64da-5699-4c8e-b58c-8d447b2f2014', + roomId: 'c57bc580-dabf-4e56-9526-1ca1982f1d0c', + createdAt: 1500, + content: { text: 'Hello, how’s it going?', inReplyTo: null }, + agentId: 'b62e64da-5699-4c8e-b58c-8d447b2f2014' + }, + { + id: 'f9c8f0f5-2aef-4a07-96d8-43b980cb7325', + userId: 'f9c8b107-953b-473d-8c87-2894c6e3fe25', + roomId: 'aae8df56-e890-4876-a3ba-2cbfc94cbd97', + createdAt: 3000, + content: { text: 'Let’s catch up later.', inReplyTo: 'e4928cd1-8007-40b1-93ff-7c5da3c39e36' }, + agentId: 'f9c8b107-953b-473d-8c87-2894c6e3fe25' + }, +]; + +// Unit tests for formatPosts +test('formats posts correctly with conversation header', () => { + const result = formatPosts({ + messages: mockMessages, + actors: mockActors, + conversationHeader: true, + }); + + expect(result).toContain('Name: Alice (@alice123)'); + expect(result).toContain('ID: 0db429f4-9ad9-44db-b2c6-0cf6d6cb2dfe'); + expect(result).toContain('In reply to: f9c8b107-953b-473d-8c87-2894c6e3fe25'); + expect(result).toContain('Date: 20042 days ago'); + expect(result).toContain('Text:\nHi Bob, how are you?'); +}); + +test('formats posts correctly with multiple rooms', () => { + const result = formatPosts({ + messages: mockMessages, + actors: mockActors, + conversationHeader: true, + }); + + expect(result).toContain('Name: Alice (@alice123)'); + expect(result).toContain('Text:\nHello, how’s it going?'); +}); + +test('handles empty messages array', () => { + const result = formatPosts({ + messages: [], + actors: mockActors, + conversationHeader: true, + }); + + expect(result).toBe(''); +}); diff --git a/packages/core/src/tests/providers.test.d.ts b/packages/core/src/tests/providers.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/providers.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/providers.test.ts b/packages/core/src/tests/providers.test.ts deleted file mode 100644 index 902de0379c..0000000000 --- a/packages/core/src/tests/providers.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { - IAgentRuntime, - type Memory, - type Provider, - type State, - type UUID, -} from "../src/types.ts"; - -dotenv.config({ path: ".dev.vars" }); - -const TestProvider: Provider = { - get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { - return "Hello Test"; - }, -}; - -describe("TestProvider", () => { - let runtime: IAgentRuntime; - let roomId: UUID; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - providers: [TestProvider], - }); - runtime = setup.runtime; - roomId = zeroUuid; - }); - - test("TestProvider should return 'Hello Test'", async () => { - const message: Memory = { - userId: zeroUuid, - content: { text: "" }, - roomId: roomId, - }; - - const testProviderResponse = await TestProvider.get( - runtime, - message, - {} as State - ); - expect(testProviderResponse).toBe("Hello Test"); - }); - - test("TestProvider should be integrated in the runtime providers", async () => { - expect(runtime.providers).toContain(TestProvider); - }); -}); diff --git a/packages/core/src/tests/relationships.test.d.ts b/packages/core/src/tests/relationships.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/relationships.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/relationships.test.ts b/packages/core/src/tests/relationships.test.ts deleted file mode 100644 index d9bb406e41..0000000000 --- a/packages/core/src/tests/relationships.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; // Adjust the import path as needed -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { createRelationship, getRelationships } from "../src/relationships.ts"; // Adjust the import path as needed -import { IAgentRuntime, type UUID } from "../src/types.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Relationships Module", () => { - let runtime: IAgentRuntime; - let user: User; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - }); - runtime = setup.runtime; - user = setup.session.user; - if (!user.id) { - throw new Error("User ID is undefined"); - } - }); - - test("createRelationship creates a new relationship", async () => { - const userA = user.id as UUID; - const userB = zeroUuid; - if (userA === undefined) throw new Error("userA is undefined"); - const relationship = await createRelationship({ - runtime, - userA, - userB, - }); - expect(relationship).toBe(true); - }); - - test("getRelationship retrieves an existing relationship", async () => { - const userA = user?.id as UUID; - const userB = zeroUuid; - - await createRelationship({ runtime, userA, userB }); - - const relationship = await getOrCreateRelationship({ - runtime, - userA, - userB, - }); - expect(relationship).toBeDefined(); - expect(relationship?.userA).toBe(userA); - expect(relationship?.userB).toBe(userB); - }); - - test("getRelationships retrieves all relationships for a user", async () => { - const userA = user?.id as UUID; - const userB = zeroUuid; - - await createRelationship({ runtime, userA, userB }); - - const relationships = await getRelationships({ - runtime, - userId: userA, - }); - expect(relationships).toBeDefined(); - expect(relationships.length).toBeGreaterThan(0); - expect( - relationships.some((r) => r.userA === userA || r.userB === userA) - ).toBeTruthy(); - }); -}); diff --git a/packages/core/src/tests/runtime.test.d.ts b/packages/core/src/tests/runtime.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/runtime.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/runtime.test.ts b/packages/core/src/tests/runtime.test.ts deleted file mode 100644 index efd3f2efb0..0000000000 --- a/packages/core/src/tests/runtime.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -import dotenv from "dotenv"; -import { - getCachedEmbeddings, - writeCachedEmbedding, -} from "../src/test_resources/cache.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { IAgentRuntime, type Memory, type UUID } from "../src/types.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Agent Runtime", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId: UUID = zeroUuid; - - // Helper function to clear memories - async function clearMemories() { - await runtime.messageManager.removeAllMemories(roomId); - } - - // Helper function to create memories - async function createMemories() { - const memories = [ - { - userId: user?.id as UUID, - content: { text: "test memory from user" }, - }, - { userId: zeroUuid, content: { text: "test memory from agent" } }, - ]; - - for (const { userId, content } of memories) { - try { - const embedding = await getCachedEmbeddings(content.text); - const memory = - await runtime.messageManager.addEmbeddingToMemory({ - userId: userId, - content, - roomId, - embedding, - }); - if (!embedding) { - writeCachedEmbedding( - content.text, - memory.embedding as number[] - ); - } - await runtime.messageManager.createMemory(memory); - } catch (error) { - console.error("Error creating memory", error); - } - } - } - - // Set up before each test - beforeEach(async () => { - const result = await createRuntime({ - env: process.env as Record, - }); - - runtime = result.runtime; - user = result.session.user; - - const data = await getOrCreateRelationship({ - runtime, - userA: user?.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - roomId = data.roomId; - await clearMemories(); // Clear memories before each test - }); - - // Clean up after each test - afterEach(async () => { - await clearMemories(); // Clear memories after each test to ensure a clean state - }); - - test("Create an agent runtime instance and use the basic functionality", () => { - expect(user).toBeDefined(); - expect(runtime).toBeDefined(); - }); - - test("Demonstrate idempotency by creating an agent runtime instance again", () => { - expect(user).toBeDefined(); - expect(runtime).toBeDefined(); - }); - - test("Memory lifecycle: create, retrieve, and destroy", async () => { - try { - await createMemories(); // Create new memories - } catch (error) { - console.error("Error creating memories", error); - } - - const message: Memory = { - userId: user.id as UUID, - content: { text: "test message" }, - roomId: roomId as UUID, - }; - - const state = await runtime.composeState(message); - - expect(state.recentMessagesData.length).toBeGreaterThan(1); - - await clearMemories(); - }, 60000); -}); diff --git a/packages/core/src/tests/time.test.d.ts b/packages/core/src/tests/time.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/time.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/time.test.ts b/packages/core/src/tests/time.test.ts deleted file mode 100644 index 0453c2d79f..0000000000 --- a/packages/core/src/tests/time.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import dotenv from "dotenv"; -import { composeContext } from "../src/context.ts"; -import { - IAgentRuntime, - type Memory, - type State, - type UUID, -} from "../src/types.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import timeProvider from "../src/providers/time.ts"; - -dotenv.config({ path: ".dev.vars" }); - -describe("Time Provider", () => { - let runtime: IAgentRuntime; - let user: { id: UUID }; - let roomId: UUID; - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - providers: [timeProvider], - }); - runtime = setup.runtime; - user = { id: setup.session.user?.id as UUID }; - roomId = zeroUuid; - }); - - test("Time provider should return the current time in the correct format", async () => { - const message: Memory = { - userId: user.id, - content: { text: "" }, - roomId: roomId, - }; - - const currentTimeResponse = await timeProvider.get( - runtime, - message, - {} as State - ); - expect(currentTimeResponse).toMatch( - /^The current time is: \d{1,2}:\d{2}:\d{2}\s?(AM|PM)$/ - ); - }); - - test("Time provider should be integrated in the state and context correctly", async () => { - const message: Memory = { - userId: user.id, - content: { text: "" }, - roomId: roomId, - }; - - // Manually integrate the time provider's response into the state - const state = await runtime.composeState(message); - - const contextTemplate = `Current Time: {{providers}}`; - const context = composeContext({ - state: state, - template: contextTemplate, - }); - - const match = context.match( - new RegExp( - `^Current Time: The current time is: \\d{1,2}:\\d{2}:\\d{2}\\s?(AM|PM)$` - ) - ); - - expect(match).toBeTruthy(); - }); - - test("Time provider should work independently", async () => { - const message: Memory = { - userId: user.id, - content: { text: "" }, - roomId: roomId, - }; - const currentTimeResponse = await timeProvider.get(runtime, message); - - expect(currentTimeResponse).toMatch( - /^The current time is: \d{1,2}:\d{2}:\d{2}\s?(AM|PM)$/ - ); - }); -}); diff --git a/packages/core/src/tests/token.test.d.ts b/packages/core/src/tests/token.test.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/core/src/tests/token.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/token.test.ts b/packages/core/src/tests/token.test.ts deleted file mode 100644 index 46abfe6f8a..0000000000 --- a/packages/core/src/tests/token.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { createRuntime } from "../src/test_resources/createRuntime"; -import { TokenProvider } from "../src/providers/token"; -import NodeCache from "node-cache"; - -// Mock the dependencies -jest.mock("cross-fetch"); -jest.mock("fs"); -jest.mock("node-cache"); - -describe("TokenProvider Tests", () => { - // let connection: Connection; - let tokenProvider: TokenProvider; - - beforeEach(() => { - // Initialize the connection and token provider before each test - // connection = new Connection("https://api.mainnet-beta.solana.com"); - tokenProvider = new TokenProvider( - "2weMjPLLybRMMva1fM3U31goWWrCpF59CHWNhnCJ9Vyh" - ); - }); - - test("should fetch token security data", async () => { - const { runtime } = await createRuntime({ - conversationLength: 10, - }); - - // Mock the response for the fetchTokenSecurity call - const mockFetchResponse = { - success: true, - data: { - ownerBalance: "100", - creatorBalance: "50", - ownerPercentage: 10, - creatorPercentage: 5, - top10HolderBalance: "200", - top10HolderPercent: 20, - }, - }; - - // Mock fetchWithRetry function - const fetchSpy = jest - .spyOn(tokenProvider as any, "fetchWithRetry") - .mockResolvedValue(mockFetchResponse); - - // Run the fetchTokenSecurity method - // const securityData = await tokenProvider.fetchTokenSecurity(); - - // Check if the data returned is correct - // expect(securityData).toEqual({ - // ownerBalance: "100", - // creatorBalance: "50", - // ownerPercentage: 10, - // creatorPercentage: 5, - // top10HolderBalance: "200", - // top10HolderPercent: 20, - // }); - //console.log the securityData - // console.log({ securityData }); - - // const holderList = await tokenProvider.fetchHolderList(); - - // console.log({ holderList }); - - // const tradeData = await tokenProvider.fetchTokenTradeData(); - // console.log({ tradeData }); - - // const dexScreenerData = await tokenProvider.fetchDexScreenerData(); - // console.log({ dexScreenerData }); - - const tokenReport = - await tokenProvider.getFormattedTokenReport(runtime); - console.log({ tokenReport }); - - // Ensure the mock was called - expect(fetchSpy).toHaveBeenCalled(); - }); -}); diff --git a/packages/core/src/tests/utils.test.ts b/packages/core/src/tests/utils.test.ts deleted file mode 100644 index a7d4888899..0000000000 --- a/packages/core/src/tests/utils.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import Database from "better-sqlite3"; -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; -import { TwitterInteractionClient } from "../src/clients/twitter/interactions.ts"; -import { SqliteDatabaseAdapter } from "../src/adapters/sqlite.ts"; -import { defaultCharacter } from "../src/defaultCharacter.ts"; -import { buildConversationThread } from "../src/clients/twitter/utils.ts"; -import { AgentRuntime } from "../src/runtime.ts"; -import settings from "../src/settings.ts"; -import { ModelProviderName } from "../src/types.ts"; - -// const __dirname = path.dirname(new URL(".", import.meta.url).pathname); - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -describe("buildConversationThread", () => { - let runtime: AgentRuntime; - let client: TwitterInteractionClient; - - beforeAll(async () => { - // Create an instance of the AgentRuntime - runtime = new AgentRuntime({ - databaseAdapter: new SqliteDatabaseAdapter( - new Database(":memory:") - ), - token: settings.OPENAI_API_KEY as string, - evaluators: [], - modelProvider: ModelProviderName.OPENAI, - character: defaultCharacter, - providers: [], - actions: [], - }); - - // Create an instance of the TwitterPostClient - client = new TwitterInteractionClient(runtime); - - // Load cached Twitter credentials - const cookiesFilePath = path.join( - __dirname, - "../../../tweetcache/" + - runtime.getSetting("TWITTER_USERNAME") + - "_cookies.json" - ); - console.log("Cookies file path:", cookiesFilePath); - if (fs.existsSync(cookiesFilePath)) { - const cookiesArray = JSON.parse( - fs.readFileSync(cookiesFilePath, "utf-8") - ); - client.setCookiesFromArray(cookiesArray); - } else { - throw new Error( - "Twitter credentials not found. Please provide valid cookies.json." - ); - } - }); - - it("should build a conversation thread from a tweet ID", async () => { - const tweetId = "1830058678197895517"; - - // Fetch the tweet from the API - const tweet = await client.getTweet(tweetId); - console.log("Original tweet:", JSON.stringify(tweet, null, 2)); - - // Build the conversation thread - const thread = await buildConversationThread(tweet, client); - - console.log("Generated conversation thread:"); - console.log(thread); - - // Add assertions based on the expected structure and content of the thread - // expect(thread.includes("By: Aya Bochman (@ayaboch)")).toBe(true); - // expect(thread.includes("@ayaboch @DanBochman You should do nothing. Its opensource code, you have too much to lose by fighting this fight, this post will get u blacklisted be aware")).toBe(true); - // expect(thread.includes("@BLUECOW009 @ayaboch @DanBochman That's not how it works")).toBe(true); - }, 30000); -}); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 84cf46532c..636eff9b6f 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -21,11 +21,7 @@ "noEmitOnError": false, "moduleDetection": "force", "allowArbitraryExtensions": true, - "typeRoots": [ - "./node_modules/@types", - "./types", - "./node_modules/jest/types" - ] + "types": ["jest"] }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "src/**/*.d.ts", "types/**/*.test.ts"] From c76136897dc5b8041ac5e149abbee2892b3a26e1 Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 00:55:36 +0100 Subject: [PATCH 02/11] Adding readme tests file for test documentation --- packages/core/README-TESTS.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 packages/core/README-TESTS.md diff --git a/packages/core/README-TESTS.md b/packages/core/README-TESTS.md new file mode 100644 index 0000000000..1f2ddfa5a9 --- /dev/null +++ b/packages/core/README-TESTS.md @@ -0,0 +1,35 @@ +# Core Package Tests + +This package contains a test suite for evaluating evaluators and their functionality using **Jest**. + +## Prerequisites + +1. **pnpm**: Ensure you have `pnpm` installed. If not, you can install it globally using: + ```bash + npm install -g pnpm + ``` + +2. **Environment Variables**: Set up a `.env` file in the project root (eliza) with the necessary environment variables. Copy .env.example file and add required variables. + +## Setup + +1. Navigate to the `packages/core` directory: + ```bash + cd packages/core + ``` + +2. Install dependencies: + ```bash + pnpm install + ``` + +## Running Tests + +Run all tests using: +```bash +pnpm test +``` + +The test results will be displayed in the terminal. + +--- \ No newline at end of file From f98392c509bbdef33dcde06c74143f135295f9f3 Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 00:57:03 +0100 Subject: [PATCH 03/11] Adding readme tests file for test documentation - Fixing README-TESTS --- packages/core/README-TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/README-TESTS.md b/packages/core/README-TESTS.md index 1f2ddfa5a9..9abe6d9780 100644 --- a/packages/core/README-TESTS.md +++ b/packages/core/README-TESTS.md @@ -1,6 +1,6 @@ # Core Package Tests -This package contains a test suite for evaluating evaluators and their functionality using **Jest**. +This package contains a test suite for evaluating functionalities using **Jest**. ## Prerequisites From 5a70cf911491520ebe86afd79930d3402eaa678a Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 01:06:01 +0100 Subject: [PATCH 04/11] Removing date check, should think of a better way for generating date --- packages/core/src/tests/posts.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/tests/posts.test.ts b/packages/core/src/tests/posts.test.ts index 9110ad07b5..f45dd73c6c 100644 --- a/packages/core/src/tests/posts.test.ts +++ b/packages/core/src/tests/posts.test.ts @@ -75,7 +75,6 @@ test('formats posts correctly with conversation header', () => { expect(result).toContain('Name: Alice (@alice123)'); expect(result).toContain('ID: 0db429f4-9ad9-44db-b2c6-0cf6d6cb2dfe'); expect(result).toContain('In reply to: f9c8b107-953b-473d-8c87-2894c6e3fe25'); - expect(result).toContain('Date: 20042 days ago'); expect(result).toContain('Text:\nHi Bob, how are you?'); }); From 95700110031c92cc539d4a42da5756b34f87c44e Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 22:13:35 +0100 Subject: [PATCH 05/11] Adding tests for relationships, with mocker Users and relationships --- packages/core/src/tests/relationships.test.ts | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 packages/core/src/tests/relationships.test.ts diff --git a/packages/core/src/tests/relationships.test.ts b/packages/core/src/tests/relationships.test.ts new file mode 100644 index 0000000000..d8b94c8ba8 --- /dev/null +++ b/packages/core/src/tests/relationships.test.ts @@ -0,0 +1,167 @@ +import { + createRelationship, + getRelationship, + getRelationships, + formatRelationships, +} from "../relationships"; +import { IAgentRuntime, type Relationship, type UUID } from "../types"; + +// Mock runtime and databaseAdapter +const mockDatabaseAdapter = { + createRelationship: jest.fn(), + getRelationship: jest.fn(), + getRelationships: jest.fn(), +}; +const mockRuntime: IAgentRuntime = { + databaseAdapter: mockDatabaseAdapter, +} as unknown as IAgentRuntime; + +describe("Relationships Module", () => { + // Helper function to generate random UUIDs + const generateRandomUUID = (): UUID => crypto.randomUUID() as UUID; + + // Randomized UUIDs for each test run + const mockUserA: UUID = generateRandomUUID(); + const mockUserB: UUID = generateRandomUUID(); + const mockUserId: UUID = generateRandomUUID(); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("createRelationship", () => { + it("should call createRelationship on the databaseAdapter with correct parameters", async () => { + mockDatabaseAdapter.createRelationship.mockResolvedValue(true); + + const result = await createRelationship({ + runtime: mockRuntime, + userA: mockUserA, + userB: mockUserB, + }); + + expect(mockDatabaseAdapter.createRelationship).toHaveBeenCalledWith({ + userA: mockUserA, + userB: mockUserB, + }); + expect(result).toBe(true); + }); + + it("should handle errors from databaseAdapter", async () => { + mockDatabaseAdapter.createRelationship.mockRejectedValue( + new Error("Database error") + ); + + await expect( + createRelationship({ + runtime: mockRuntime, + userA: mockUserA, + userB: mockUserB, + }) + ).rejects.toThrow("Database error"); + }); + }); + + describe("getRelationship", () => { + it("should call getRelationship on the databaseAdapter with correct parameters", async () => { + const mockRelationship: Relationship = { + userA: mockUserA, + userB: mockUserB, + id: generateRandomUUID(), + userId: generateRandomUUID(), + roomId: generateRandomUUID(), + status: "STATUS" + }; + mockDatabaseAdapter.getRelationship.mockResolvedValue(mockRelationship); + + const result = await getRelationship({ + runtime: mockRuntime, + userA: mockUserA, + userB: mockUserB, + }); + + expect(mockDatabaseAdapter.getRelationship).toHaveBeenCalledWith({ + userA: mockUserA, + userB: mockUserB, + }); + expect(result).toEqual(mockRelationship); + }); + }); + + describe("getRelationships", () => { + it("should call getRelationships on the databaseAdapter with correct parameters", async () => { + const mockRelationships: Relationship[] = [ + { + userA: mockUserA, userB: mockUserB, + id: generateRandomUUID(), + userId: generateRandomUUID(), + roomId: generateRandomUUID(), + status: generateRandomUUID() + }, + { + userA: mockUserB, userB: mockUserId, + id: generateRandomUUID(), + userId: generateRandomUUID(), + roomId: generateRandomUUID(), + status: "" + }, + ]; + mockDatabaseAdapter.getRelationships.mockResolvedValue(mockRelationships); + + const result = await getRelationships({ + runtime: mockRuntime, + userId: mockUserA, + }); + + expect(mockDatabaseAdapter.getRelationships).toHaveBeenCalledWith({ + userId: mockUserA, + }); + expect(result).toEqual(mockRelationships); + }); + }); + + describe("formatRelationships", () => { + it("should format relationships correctly", async () => { + const mockRelationships: Relationship[] = [ + { + userA: mockUserA, userB: mockUserB, + id: generateRandomUUID(), + userId: generateRandomUUID(), + roomId: generateRandomUUID(), + status: "STATUS" + }, + { + userA: mockUserB, userB: mockUserId, + id: generateRandomUUID(), + userId: generateRandomUUID(), + roomId: generateRandomUUID(), + status: "STATUS" + }, + ]; + mockDatabaseAdapter.getRelationships.mockResolvedValue(mockRelationships); + + const result = await formatRelationships({ + runtime: mockRuntime, + userId: mockUserA, + }); + + expect(mockDatabaseAdapter.getRelationships).toHaveBeenCalledWith({ + userId: mockUserA, + }); + expect(result[0]).toEqual(mockUserB); + }); + + it("should return an empty array if no relationships exist", async () => { + mockDatabaseAdapter.getRelationships.mockResolvedValue([]); + + const result = await formatRelationships({ + runtime: mockRuntime, + userId: mockUserId, + }); + + expect(mockDatabaseAdapter.getRelationships).toHaveBeenCalledWith({ + userId: mockUserId, + }); + expect(result).toEqual([]); + }); + }); +}); From dd15e20a46f796ce018c696ccf794e7a2c99042f Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 22:20:01 +0100 Subject: [PATCH 06/11] Adding tests for providers.test.ts, with mocking providers and checking negative scenarios --- packages/core/src/tests/providers.test.ts | 139 ++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 packages/core/src/tests/providers.test.ts diff --git a/packages/core/src/tests/providers.test.ts b/packages/core/src/tests/providers.test.ts new file mode 100644 index 0000000000..c031a89ab2 --- /dev/null +++ b/packages/core/src/tests/providers.test.ts @@ -0,0 +1,139 @@ +import { getProviders } from "../providers"; +import { IAgentRuntime, type Memory, type State, type Provider, UUID } from "../types.ts"; + +describe("getProviders", () => { + let runtime: IAgentRuntime; + let roomId: UUID; + + // Mock providers for testing + const MockProvider1: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + return "Response from Provider 1"; + }, + }; + + const MockProvider2: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + return "Response from Provider 2"; + }, + }; + + const MockProvider3: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + return "Response from Provider 3"; + }, + }; + + beforeAll(() => { + // Initialize the runtime with mock providers + runtime = { + providers: [MockProvider1, MockProvider2, MockProvider3], + } as IAgentRuntime; + roomId = "00000000-0000-0000-0000-000000000000" as UUID; // Example UUID + }); + + test("getProviders should call all provider get methods and return concatenated responses", async () => { + const message: Memory = { + userId: "00000000-0000-0000-0000-000000000001", + content: { text: "" }, + roomId: roomId, + agentId: "00000000-0000-0000-0000-000000000002" + }; + + const result = await getProviders(runtime, message, {} as State); + + // Check if the responses are concatenated correctly with newline separators + expect(result).toBe( + "Response from Provider 1\nResponse from Provider 2\nResponse from Provider 3" + ); + }); + + test("getProviders should handle an empty provider list", async () => { + runtime.providers = []; + + const message: Memory = { + userId: "00000000-0000-0000-0000-000000000001", + content: { text: "" }, + roomId: roomId, + agentId: "00000000-0000-0000-0000-000000000002" + }; + + const result = await getProviders(runtime, message, {} as State); + + // No providers, should return an empty string + expect(result).toBe(""); + }); + + test("getProviders should handle providers returning undefined", async () => { + const MockProviderWithUndefinedResponse: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + return undefined; // Simulate undefined return + }, + }; + + runtime.providers = [MockProviderWithUndefinedResponse]; + + const message: Memory = { + userId: "00000000-0000-0000-0000-000000000001", + content: { text: "" }, + roomId: roomId, + agentId: "00000000-0000-0000-0000-000000000002" + }; + + const result = await getProviders(runtime, message, {} as State); + + // Should handle undefined return and result in empty string for that provider + expect(result).toBe(""); + }); + + test("getProviders should concatenate valid responses and ignore undefined", async () => { + const MockProviderWithValidAndUndefinedResponse: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + return "Valid response"; + }, + }; + + const MockProviderWithUndefinedResponse: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + return undefined; + }, + }; + + runtime.providers = [ + MockProviderWithValidAndUndefinedResponse, + MockProviderWithUndefinedResponse, + ]; + + const message: Memory = { + userId: "00000000-0000-0000-0000-000000000001", + content: { text: "" }, + roomId: roomId, + agentId: "00000000-0000-0000-0000-000000000002" + }; + + const result = await getProviders(runtime, message, {} as State); + + // Only the valid response should be concatenated, ignoring undefined + expect(result).toContain("Valid response"); + }); + + test("getProviders should handle error if one provider fails", async () => { + const MockProviderThatThrows: Provider = { + get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => { + throw new Error("Provider error"); + }, + }; + + const message: Memory = { + userId: "00000000-0000-0000-0000-000000000001", + content: { text: "" }, + roomId: roomId, + agentId: "00000000-0000-0000-0000-000000000002" + }; + + runtime.providers = [MockProviderThatThrows, MockProvider1]; + + // Expect an error from the first provider but still get the response from the second provider + await expect(getProviders(runtime, message, {} as State)).rejects.toThrow("Provider error"); + }); +}); From 5542f7614bdb9a638f221992905a7b22a2b4b7d7 Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 22:56:14 +0100 Subject: [PATCH 07/11] Adding messages tests --- .../core/src/test_resources/basic.test.ts | 12 -- packages/core/src/test_resources/constants.ts | 2 +- .../core/src/test_resources/createRuntime.ts | 11 +- .../test_resources/getOrCreateRelationship.ts | 4 +- packages/core/src/test_resources/testSetup.ts | 2 - packages/core/src/tests/messages.test.ts | 137 ++++++++++++++++++ 6 files changed, 146 insertions(+), 22 deletions(-) delete mode 100644 packages/core/src/test_resources/basic.test.ts create mode 100644 packages/core/src/tests/messages.test.ts diff --git a/packages/core/src/test_resources/basic.test.ts b/packages/core/src/test_resources/basic.test.ts deleted file mode 100644 index fb31cc366b..0000000000 --- a/packages/core/src/test_resources/basic.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, expect, it } from "@jest/globals"; - -describe("Basic Test Suite", () => { - it("should run a basic test", () => { - expect(true).toBe(true); - }); - - it("should have access to environment variables", () => { - expect(process.env.NODE_ENV).toBe("test"); - expect(process.env.TEST_DATABASE_CLIENT).toBe("sqlite"); - }); -}); diff --git a/packages/core/src/test_resources/constants.ts b/packages/core/src/test_resources/constants.ts index f60b632a03..e68e9569cd 100644 --- a/packages/core/src/test_resources/constants.ts +++ b/packages/core/src/test_resources/constants.ts @@ -1,4 +1,4 @@ -import { type UUID } from "@ai16z/eliza/src/types.ts"; +import { type UUID } from "../types.ts"; export const SERVER_URL = "http://localhost:7998"; export const SUPABASE_URL = "https://pronvzrzfwsptkojvudd.supabase.co"; diff --git a/packages/core/src/test_resources/createRuntime.ts b/packages/core/src/test_resources/createRuntime.ts index a9c98ddcf7..71dad40f25 100644 --- a/packages/core/src/test_resources/createRuntime.ts +++ b/packages/core/src/test_resources/createRuntime.ts @@ -1,15 +1,15 @@ -import { SqliteDatabaseAdapter } from "../adapters/sqlite.ts"; +import { SqliteDatabaseAdapter } from "../../../adapter-sqlite/src/index.ts"; import { load } from "../../../adapter-sqlite/src/sqlite_vec.ts"; import { SqlJsDatabaseAdapter } from "../../../adapter-sqljs/src/index.ts"; import { SupabaseDatabaseAdapter } from "../../../adapter-supabase/src/index.ts"; -import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; -import { AgentRuntime } from "@ai16z/eliza/src/runtime.ts"; +import { DatabaseAdapter } from "../database.ts"; +import { AgentRuntime } from "../runtime.ts"; import { Action, Evaluator, ModelProviderName, Provider, -} from "@ai16z/eliza/src/types.ts"; +} from "../types.ts"; import { SUPABASE_ANON_KEY, SUPABASE_URL, @@ -107,7 +107,8 @@ export async function createRuntime({ env?.SUPABASE_URL ?? SUPABASE_URL, env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY ); - } + } break; + case "sqlite": default: { diff --git a/packages/core/src/test_resources/getOrCreateRelationship.ts b/packages/core/src/test_resources/getOrCreateRelationship.ts index 9ecab65ee9..9883d52816 100644 --- a/packages/core/src/test_resources/getOrCreateRelationship.ts +++ b/packages/core/src/test_resources/getOrCreateRelationship.ts @@ -1,5 +1,5 @@ -import { getRelationship } from "@ai16z/eliza/src/relationships.ts"; -import { IAgentRuntime, Relationship, UUID } from "@ai16z/eliza/src/types.ts"; +import { getRelationship } from "../relationships.ts"; +import { IAgentRuntime, Relationship, UUID } from "..//types.ts"; export async function getOrCreateRelationship({ runtime, diff --git a/packages/core/src/test_resources/testSetup.ts b/packages/core/src/test_resources/testSetup.ts index 1f782c22fe..81e865cdf2 100644 --- a/packages/core/src/test_resources/testSetup.ts +++ b/packages/core/src/test_resources/testSetup.ts @@ -1,6 +1,4 @@ import dotenv from "dotenv"; -import path from "path"; - import { jest } from "@jest/globals"; // Load test environment variables diff --git a/packages/core/src/tests/messages.test.ts b/packages/core/src/tests/messages.test.ts new file mode 100644 index 0000000000..10f6db22e6 --- /dev/null +++ b/packages/core/src/tests/messages.test.ts @@ -0,0 +1,137 @@ +import { formatActors, formatMessages, getActorDetails, formatTimestamp } from "../messages.ts"; +import { IAgentRuntime, Actor, Content, Memory, UUID } from "../types.ts"; + +describe("Messages Library", () => { + let runtime: IAgentRuntime; + let actors: Actor[]; + let userId: UUID; + + beforeAll(() => { + // Mock runtime with necessary methods + runtime = { + databaseAdapter: { + // Casting to a Jest mock function + getParticipantsForRoom: jest.fn(), + getAccountById: jest.fn(), + }, + } as unknown as IAgentRuntime; + + // Mock user data with proper UUID format + userId = "12345678-1234-1234-1234-123456789abc" as UUID; + actors = [ + { + id: userId, + name: "Test User", + username: "testuser", + details: { + tagline: "A test user", + summary: "This is a test user for the system.", + quote: "" + }, + }, + ]; + }); + + test("getActorDetails should return actors based on roomId", async () => { + // Mocking the database adapter methods + const roomId: UUID = "room1234-1234-1234-1234-123456789abc" as UUID; + + // Properly mocking the resolved values of the mocked methods + (runtime.databaseAdapter.getParticipantsForRoom as jest.Mock).mockResolvedValue([userId]); + (runtime.databaseAdapter.getAccountById as jest.Mock).mockResolvedValue({ + id: userId, + name: "Test User", + username: "testuser", + details: { + tagline: "A test user", + summary: "This is a test user for the system.", + }, + }); + + // Calling the function under test + const result = await getActorDetails({ runtime, roomId }); + + // Assertions + expect(result.length).toBeGreaterThan(0); + expect(result[0].name).toBe("Test User"); + expect(result[0].details?.tagline).toBe("A test user"); + }); + + test("formatActors should format actors into a readable string", () => { + const formattedActors = formatActors({ actors }); + + // Assertions + expect(formattedActors).toContain("Test User"); + expect(formattedActors).toContain("A test user"); + expect(formattedActors).toContain("This is a test user for the system."); + }); + + test("formatMessages should format messages into a readable string", () => { + const messages: Memory[] = [ + { + content: { text: "Hello, world!" } as Content, + userId: userId, + roomId: "room1234-1234-1234-1234-123456789abc" as UUID, + createdAt: new Date().getTime(), + agentId: "" as UUID // assuming agentId is an empty string here + }, + ]; + + const formattedMessages = formatMessages({ messages, actors }); + + // Assertions + expect(formattedMessages).toContain("Hello, world!"); + expect(formattedMessages).toContain("Test User"); + }); + + test("formatTimestamp should return correct time string", () => { + const timestamp = new Date().getTime() - 60000; // 1 minute ago + const result = formatTimestamp(timestamp); + + // Assertions + expect(result).toBe("1 minute ago"); + }); + + test("formatMessages should include attachments if present", () => { + const messages: Memory[] = [ + { + content: { + text: "Check this attachment", + attachments: [ + { id: "1", title: "Image", url: "http://example.com/image.jpg" }, + ], + } as Content, + userId: userId, + roomId: "room1234-1234-1234-1234-123456789abc" as UUID, + createdAt: new Date().getTime(), + agentId: "" as UUID // assuming agentId is an empty string here + }, + ]; + + const formattedMessages = formatMessages({ messages, actors }); + + // Assertions + expect(formattedMessages).toContain("Check this attachment"); + expect(formattedMessages).toContain("Attachments: [1 - Image (http://example.com/image.jpg)]"); + }); + + test("formatMessages should handle empty attachments gracefully", () => { + const messages: Memory[] = [ + { + content: { + text: "No attachments here", + } as Content, + userId: userId, + roomId: "room1234-1234-1234-1234-123456789abc" as UUID, + createdAt: new Date().getTime(), + agentId: "" as UUID // assuming agentId is an empty string here + }, + ]; + + const formattedMessages = formatMessages({ messages, actors }); + + // Assertions + expect(formattedMessages).toContain("No attachments here"); + expect(formattedMessages).not.toContain("Attachments"); + }); +}); From 004c7ae787f8721505959d17243ae140404b34c5 Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 23:46:25 +0100 Subject: [PATCH 08/11] Runtime file --- packages/core/src/test_resources/createRuntime.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/test_resources/createRuntime.ts b/packages/core/src/test_resources/createRuntime.ts index 71dad40f25..1137875d16 100644 --- a/packages/core/src/test_resources/createRuntime.ts +++ b/packages/core/src/test_resources/createRuntime.ts @@ -17,7 +17,7 @@ import { TEST_PASSWORD, zeroUuid, } from "./constants.ts"; -import { User } from "./types.ts"; +import { User } from "../types.ts"; export async function createRuntime({ env, From 9eb5715e45abf419a9177e18297dac072d3a4d73 Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 23:49:21 +0100 Subject: [PATCH 09/11] removing files to sync with main branch --- packages/core/jest.config.js | 1 - packages/core/src/test_resources/constants.ts | 12 -- .../core/src/test_resources/createRuntime.ts | 148 ------------------ .../test_resources/getOrCreateRelationship.ts | 66 -------- .../core/src/test_resources/testAction.ts | 59 ------- packages/core/src/test_resources/testSetup.ts | 8 - 6 files changed, 294 deletions(-) delete mode 100644 packages/core/src/test_resources/constants.ts delete mode 100644 packages/core/src/test_resources/createRuntime.ts delete mode 100644 packages/core/src/test_resources/getOrCreateRelationship.ts delete mode 100644 packages/core/src/test_resources/testAction.ts delete mode 100644 packages/core/src/test_resources/testSetup.ts diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js index 62c0deeb70..35d5f9f0b3 100644 --- a/packages/core/jest.config.js +++ b/packages/core/jest.config.js @@ -4,7 +4,6 @@ export default { testEnvironment: "node", rootDir: "./src", testMatch: ["**/*.test.ts"], - setupFilesAfterEnv: ["/test_resources/testSetup.ts"], testTimeout: 120000, globals: { __DEV__: true, diff --git a/packages/core/src/test_resources/constants.ts b/packages/core/src/test_resources/constants.ts deleted file mode 100644 index e68e9569cd..0000000000 --- a/packages/core/src/test_resources/constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { type UUID } from "../types.ts"; - -export const SERVER_URL = "http://localhost:7998"; -export const SUPABASE_URL = "https://pronvzrzfwsptkojvudd.supabase.co"; -export const SUPABASE_ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InByb252enJ6ZndzcHRrb2p2dWRkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDY4NTYwNDcsImV4cCI6MjAyMjQzMjA0N30.I6_-XrqssUb2SWYg5DjsUqSodNS3_RPoET3-aPdqywM"; -export const TEST_EMAIL = "testuser123@gmail.com"; -export const TEST_PASSWORD = "testuser123@gmail.com"; -export const TEST_EMAIL_2 = "testuser234@gmail.com"; -export const TEST_PASSWORD_2 = "testuser234@gmail.com"; - -export const zeroUuid = "00000000-0000-0000-0000-000000000000" as UUID; diff --git a/packages/core/src/test_resources/createRuntime.ts b/packages/core/src/test_resources/createRuntime.ts deleted file mode 100644 index 1137875d16..0000000000 --- a/packages/core/src/test_resources/createRuntime.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { SqliteDatabaseAdapter } from "../../../adapter-sqlite/src/index.ts"; -import { load } from "../../../adapter-sqlite/src/sqlite_vec.ts"; -import { SqlJsDatabaseAdapter } from "../../../adapter-sqljs/src/index.ts"; -import { SupabaseDatabaseAdapter } from "../../../adapter-supabase/src/index.ts"; -import { DatabaseAdapter } from "../database.ts"; -import { AgentRuntime } from "../runtime.ts"; -import { - Action, - Evaluator, - ModelProviderName, - Provider, -} from "../types.ts"; -import { - SUPABASE_ANON_KEY, - SUPABASE_URL, - TEST_EMAIL, - TEST_PASSWORD, - zeroUuid, -} from "./constants.ts"; -import { User } from "../types.ts"; - -export async function createRuntime({ - env, - conversationLength, - evaluators = [], - actions = [], - providers = [], -}: { - env?: Record | NodeJS.ProcessEnv; - conversationLength?: number; - evaluators?: Evaluator[]; - actions?: Action[]; - providers?: Provider[]; -}) { - let adapter: DatabaseAdapter; - let user: User; - let session: { - user: User; - }; - - switch (env?.TEST_DATABASE_CLIENT as string) { - case "sqljs": - { - const module = await import("sql.js"); - - const initSqlJs = module.default; - - // SQLite adapter - const SQL = await initSqlJs({}); - const db = new SQL.Database(); - - adapter = new SqlJsDatabaseAdapter(db); - - // Load sqlite-vss - load((adapter as SqlJsDatabaseAdapter).db); - // Create a test user and session - user = { - id: zeroUuid, - email: "test@example.com", - } as User; - session = { - user: user, - }; - } - break; - case "supabase": { - const module = await import("@supabase/supabase-js"); - - const { createClient } = module; - - const supabase = createClient( - env?.SUPABASE_URL ?? SUPABASE_URL, - env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY - ); - - const { data } = await supabase.auth.signInWithPassword({ - email: TEST_EMAIL!, - password: TEST_PASSWORD!, - }); - - user = data.user as User; - session = data.session as unknown as { user: User }; - - if (!session) { - const response = await supabase.auth.signUp({ - email: TEST_EMAIL!, - password: TEST_PASSWORD!, - }); - - // Change the name of the user - const { error } = await supabase - .from("accounts") - .update({ name: "Test User" }) - .eq("id", response.data.user?.id); - - if (error) { - throw new Error( - "Create runtime error: " + JSON.stringify(error) - ); - } - - user = response.data.user as User; - session = response.data.session as unknown as { user: User }; - } - - adapter = new SupabaseDatabaseAdapter( - env?.SUPABASE_URL ?? SUPABASE_URL, - env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY - ); - } break; - - case "sqlite": - default: - { - const module = await import("better-sqlite3"); - - const Database = module.default; - - // SQLite adapter - adapter = new SqliteDatabaseAdapter(new Database(":memory:")); - - // Load sqlite-vss - await load((adapter as SqliteDatabaseAdapter).db); - // Create a test user and session - user = { - id: zeroUuid, - email: "test@example.com", - } as User; - session = { - user: user, - }; - } - break; - } - - const runtime = new AgentRuntime({ - serverUrl: "https://api.openai.com/v1", - conversationLength, - token: env!.OPENAI_API_KEY!, - modelProvider: ModelProviderName.OPENAI, - actions: actions ?? [], - evaluators: evaluators ?? [], - providers: providers ?? [], - databaseAdapter: adapter, - }); - - return { user, session, runtime }; -} diff --git a/packages/core/src/test_resources/getOrCreateRelationship.ts b/packages/core/src/test_resources/getOrCreateRelationship.ts deleted file mode 100644 index f42f924597..0000000000 --- a/packages/core/src/test_resources/getOrCreateRelationship.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { getRelationship } from "../relationships.ts"; -import { IAgentRuntime, Relationship, UUID } from "../types.ts"; - -export async function getOrCreateRelationship({ - runtime, - userA, - userB, -}: { - runtime: IAgentRuntime; - userA: UUID; - userB: UUID; -}): Promise { - // Check if a relationship already exists between userA and userB - let relationship: Relationship | null = null; - try { - relationship = await getRelationship({ runtime, userA, userB }); - } catch (error) { - console.log("Error fetching relationship", error); - } - - if (!relationship) { - await runtime.databaseAdapter.createRelationship({ - userA, - userB, - }); - - relationship = await getRelationship({ runtime, userA, userB }); - } - - // Check if a room already exists for the participants - const rooms = await runtime.databaseAdapter.getRoomsForParticipants([ - userA, - userB, - ]); - - let roomId: UUID; - if (!rooms || rooms.length === 0) { - console.log("No room found for participants"); - // If no room exists, create a new room for the relationship - roomId = await runtime.databaseAdapter.createRoom(); - console.log("Created room", roomId); - - // Add participants to the newly created room - await runtime.databaseAdapter.addParticipant(userA, roomId); - await runtime.databaseAdapter.addParticipant(userB, roomId); - } else { - console.log("Room found for participants", rooms[0]); - // If a room already exists, use the existing room - roomId = rooms[0]; - } - - if (!relationship) { - // Create the relationship - await runtime.databaseAdapter.createRelationship({ - userA, - userB, - }); - - relationship = await getRelationship({ runtime, userA, userB }); - - if (!relationship) { - throw new Error("Failed to fetch the created relationship"); - } - } - return { ...relationship, roomId }; -} diff --git a/packages/core/src/test_resources/testAction.ts b/packages/core/src/test_resources/testAction.ts deleted file mode 100644 index 7dfc9d8226..0000000000 --- a/packages/core/src/test_resources/testAction.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - IAgentRuntime, - type Action, - type Memory, -} from "../../src/types.ts"; - -export const TEST_ACTION = { - name: "TEST_ACTION", - validate: async (_runtime: IAgentRuntime, _message: Memory) => { - return true; - }, - description: "This is a test action, for use in testing.", - handler: async ( - runtime: IAgentRuntime, - message: Memory - ): Promise => { - return true; - }, - examples: [ - [ - { - user: "{{user1}}", - content: { - text: "Please respond with the message 'testing 123' and the action TEST_ACTION", - action: "TEST_ACTION", - }, - }, - { - user: "{{user2}}", - content: { text: "testing 123", action: "TEST_ACTION" }, - }, - ], - ], -} as Action; - -export const TEST_ACTION_FAIL = { - name: "TEST_ACTION_FAIL", - validate: async (_runtime: IAgentRuntime, _message: Memory) => { - return false; - }, - description: "This is a test action, for use in testing.", - handler: async ( - runtime: IAgentRuntime, - message: Memory - ): Promise => { - return false; - }, - examples: [ - [ - { - user: "{{user1}}", - content: { - text: "Testing failure", - action: "TEST_ACTIONFALSE", - }, - }, - ], - ], -} as Action; diff --git a/packages/core/src/test_resources/testSetup.ts b/packages/core/src/test_resources/testSetup.ts deleted file mode 100644 index 81e865cdf2..0000000000 --- a/packages/core/src/test_resources/testSetup.ts +++ /dev/null @@ -1,8 +0,0 @@ -import dotenv from "dotenv"; -import { jest } from "@jest/globals"; - -// Load test environment variables -dotenv.config({ path: ".env.test" }); - -// Set longer timeout for tests -jest.setTimeout(120000); From 5014a2ca55e2284626cb3f5203ab72ec06ad3a79 Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sat, 16 Nov 2024 23:54:41 +0100 Subject: [PATCH 10/11] Mocking env file --- packages/core/src/tests/models.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/tests/models.test.ts b/packages/core/src/tests/models.test.ts index 02320de7eb..66cbb101d7 100644 --- a/packages/core/src/tests/models.test.ts +++ b/packages/core/src/tests/models.test.ts @@ -1,6 +1,10 @@ import { getModel, getEndpoint } from '../models.ts'; import { ModelProviderName, ModelClass } from '../types.ts'; +jest.mock('../settings', () => ({ + loadEnv: jest.fn(), // Mock the loadEnv function +})); + describe('Model Provider Tests', () => { test('should retrieve the correct model for OpenAI SMALL', () => { const model = getModel(ModelProviderName.OPENAI, ModelClass.SMALL); From 9dfbc9ebb130916e3fb11d57281338e808191a7a Mon Sep 17 00:00:00 2001 From: Mladen Radivojevic Date: Sun, 17 Nov 2024 00:22:36 +0100 Subject: [PATCH 11/11] Adding not required label to env variables in test documentation --- packages/core/README-TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/README-TESTS.md b/packages/core/README-TESTS.md index 9abe6d9780..85a14eb8f6 100644 --- a/packages/core/README-TESTS.md +++ b/packages/core/README-TESTS.md @@ -9,7 +9,7 @@ This package contains a test suite for evaluating functionalities using **Jest** npm install -g pnpm ``` -2. **Environment Variables**: Set up a `.env` file in the project root (eliza) with the necessary environment variables. Copy .env.example file and add required variables. +2. **Environment Variables - NOT REQUIRED** : Set up a `.env` file in the project root (eliza) with the necessary environment variables. Copy .env.example file and add required variables. ## Setup