From 3da642c770bbdcdf5ad8dbdd37b6ca5f976c6719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SHAN=20=CE=9E=20=20M=E2=9A=A1=EF=B8=8F?= Date: Thu, 26 Dec 2024 21:46:19 -0500 Subject: [PATCH 1/3] fix: improve client type identification in runtime initialization - Add determineClientType helper function to reliably identify client types - Replace client.name usage with robust type detection - Maintain backward compatibility with existing clients - Add debug logging for client initialization --- agent/src/index.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/agent/src/index.ts b/agent/src/index.ts index 1e49bae84f..2fa938bcc7 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -17,7 +17,6 @@ import { elizaLogger, FsCacheAdapter, IAgentRuntime, - ICacheManager, IDatabaseAdapter, IDatabaseCacheAdapter, ModelProviderName, @@ -25,6 +24,8 @@ import { stringToUuid, validateCharacterConfig, CacheStore, + Client, + ICacheManager, } from "@elizaos/core"; import { RedisClient } from "@elizaos/adapter-redis"; import { zgPlugin } from "@elizaos/plugin-0g"; @@ -418,12 +419,30 @@ export async function initializeClients( if (slackClient) clients.slack = slackClient; // Use object property instead of push } + function determineClientType(client: Client): string { + // Check if client has a direct type identifier + if ('type' in client) { + return (client as any).type; + } + + // Check constructor name + const constructorName = client.constructor?.name; + if (constructorName && !constructorName.includes('Object')) { + return constructorName.toLowerCase().replace('client', ''); + } + + // Fallback: Generate a unique identifier + return `client_${Date.now()}`; + } + if (character.plugins?.length > 0) { for (const plugin of character.plugins) { if (plugin.clients) { for (const client of plugin.clients) { const startedClient = await client.start(runtime); - clients[client.name] = startedClient; // Assuming client has a name property + const clientType = determineClientType(client); + elizaLogger.debug(`Initializing client of type: ${clientType}`); + clients[clientType] = startedClient; } } } From 554f5daf05e0c79e006cf0b74c0ba50493b388d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SHAN=20=CE=9E=20=20M=E2=9A=A1=EF=B8=8F?= Date: Thu, 26 Dec 2024 21:52:30 -0500 Subject: [PATCH 2/3] test: add Jest testing setup for client type identification - Add Jest and ts-jest dependencies - Configure Jest for TypeScript - Add test script to package.json --- agent/jest.config.js | 17 +++++++++++++++++ agent/package.json | 18 +++++++++++------- agent/tsconfig.json | 3 ++- 3 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 agent/jest.config.js diff --git a/agent/jest.config.js b/agent/jest.config.js new file mode 100644 index 0000000000..927b0b43d2 --- /dev/null +++ b/agent/jest.config.js @@ -0,0 +1,17 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +export default { + preset: 'ts-jest', + testEnvironment: 'node', + extensionsToTreatAsEsm: ['.ts'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, +}; \ No newline at end of file diff --git a/agent/package.json b/agent/package.json index 91a900d600..158db8a0fb 100644 --- a/agent/package.json +++ b/agent/package.json @@ -6,7 +6,8 @@ "scripts": { "start": "node --loader ts-node/esm src/index.ts", "dev": "node --loader ts-node/esm src/index.ts", - "check-types": "tsc --noEmit" + "check-types": "tsc --noEmit", + "test": "jest" }, "nodemonConfig": { "watch": [ @@ -25,37 +26,40 @@ "@elizaos/client-discord": "workspace:*", "@elizaos/client-farcaster": "workspace:*", "@elizaos/client-lens": "workspace:*", + "@elizaos/client-slack": "workspace:*", "@elizaos/client-telegram": "workspace:*", "@elizaos/client-twitter": "workspace:*", - "@elizaos/client-slack": "workspace:*", "@elizaos/core": "workspace:*", "@elizaos/plugin-0g": "workspace:*", "@elizaos/plugin-aptos": "workspace:*", "@elizaos/plugin-bootstrap": "workspace:*", - "@elizaos/plugin-intiface": "workspace:*", "@elizaos/plugin-coinbase": "workspace:*", "@elizaos/plugin-conflux": "workspace:*", "@elizaos/plugin-evm": "workspace:*", "@elizaos/plugin-flow": "workspace:*", - "@elizaos/plugin-story": "workspace:*", "@elizaos/plugin-goat": "workspace:*", "@elizaos/plugin-icp": "workspace:*", "@elizaos/plugin-image-generation": "workspace:*", + "@elizaos/plugin-intiface": "workspace:*", + "@elizaos/plugin-multiversx": "workspace:*", + "@elizaos/plugin-near": "workspace:*", "@elizaos/plugin-nft-generation": "workspace:*", "@elizaos/plugin-node": "workspace:*", "@elizaos/plugin-solana": "workspace:*", "@elizaos/plugin-starknet": "workspace:*", - "@elizaos/plugin-ton": "workspace:*", + "@elizaos/plugin-story": "workspace:*", "@elizaos/plugin-sui": "workspace:*", "@elizaos/plugin-tee": "workspace:*", - "@elizaos/plugin-multiversx": "workspace:*", - "@elizaos/plugin-near": "workspace:*", + "@elizaos/plugin-ton": "workspace:*", "@elizaos/plugin-zksync-era": "workspace:*", "readline": "1.3.0", "ws": "8.18.0", "yargs": "17.7.2" }, "devDependencies": { + "@types/jest": "^29.5.14", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", "ts-node": "10.9.2", "tsup": "8.3.5" } diff --git a/agent/tsconfig.json b/agent/tsconfig.json index a959a90103..3d4700eb63 100644 --- a/agent/tsconfig.json +++ b/agent/tsconfig.json @@ -6,7 +6,8 @@ "module": "ESNext", "moduleResolution": "Bundler", "types": [ - "node" + "node", + "jest" ] }, "ts-node": { From 8a5dd4c38e2cf176f21d45f8b27f9ce96ee5828a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SHAN=20=CE=9E=20=20M=E2=9A=A1=EF=B8=8F?= Date: Thu, 26 Dec 2024 21:52:53 -0500 Subject: [PATCH 3/3] test: add tests for client type identification - Test explicit type property handling - Test constructor name fallback - Test unique identifier generation for plain objects --- .../client-type-identification.test.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 agent/src/__tests__/client-type-identification.test.ts diff --git a/agent/src/__tests__/client-type-identification.test.ts b/agent/src/__tests__/client-type-identification.test.ts new file mode 100644 index 0000000000..602743e16f --- /dev/null +++ b/agent/src/__tests__/client-type-identification.test.ts @@ -0,0 +1,53 @@ +import { Client, IAgentRuntime } from "@elizaos/core"; +import { describe, it, expect } from '@jest/globals'; + +// Helper function to identify client types +function determineClientType(client: Client): string { + // Check if client has a direct type identifier + if ('type' in client) { + return (client as any).type; + } + + // Check constructor name + const constructorName = client.constructor?.name; + if (constructorName && !constructorName.includes('Object')) { + return constructorName.toLowerCase().replace('client', ''); + } + + // Fallback: Generate a unique identifier + return `client_${Date.now()}`; +} + +// Mock client implementations for testing +class MockNamedClient implements Client { + type = "named-client"; + async start(_runtime?: IAgentRuntime) { return this; } + async stop(_runtime?: IAgentRuntime) { } +} + +class MockConstructorClient implements Client { + async start(_runtime?: IAgentRuntime) { return this; } + async stop(_runtime?: IAgentRuntime) { } +} + +const mockPlainClient: Client = { + async start(_runtime?: IAgentRuntime) { return {}; }, + async stop(_runtime?: IAgentRuntime) { } +}; + +describe("Client Type Identification", () => { + it("should identify client type from type property", () => { + const client = new MockNamedClient(); + expect(determineClientType(client)).toBe("named-client"); + }); + + it("should identify client type from constructor name", () => { + const client = new MockConstructorClient(); + expect(determineClientType(client)).toBe("mockconstructor"); + }); + + it("should generate fallback identifier for plain objects", () => { + const result = determineClientType(mockPlainClient); + expect(result).toMatch(/^client_\d+$/); + }); +}); \ No newline at end of file