From 91f1a3e10e03fe7b7e14b68c7c6742a6bf057387 Mon Sep 17 00:00:00 2001 From: Ting Chien Meng Date: Mon, 17 Feb 2025 13:33:32 +0800 Subject: [PATCH 1/4] fix base and environment test error --- .../plugin-twitter/__tests__/base.test.ts | 18 +++++--- .../__tests__/environment.test.ts | 46 ++++++++++--------- packages/plugin-twitter/src/environment.ts | 16 +++---- 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/packages/plugin-twitter/__tests__/base.test.ts b/packages/plugin-twitter/__tests__/base.test.ts index ec4e9a49f1d..1da00e05d6b 100644 --- a/packages/plugin-twitter/__tests__/base.test.ts +++ b/packages/plugin-twitter/__tests__/base.test.ts @@ -44,22 +44,26 @@ describe('Twitter Client Base', () => { TWITTER_RETRY_LIMIT: 5, TWITTER_POLL_INTERVAL: 120, TWITTER_ENABLE_POST_GENERATION: true, - POST_INTERVAL_MIN: 90, - POST_INTERVAL_MAX: 180, + TWITTER_POST_INTERVAL_MIN: 90, + TWITTER_POST_INTERVAL_MAX: 180, TWITTER_POST_IMMEDIATELY: false }; }); it('should create instance with correct configuration', () => { - const client = new ClientBase(mockRuntime); + const client = new ClientBase(mockRuntime, mockConfig); expect(client).toBeDefined(); expect(mockRuntime.getSetting("TWITTER_USERNAME")).toBe('testuser'); - expect(mockRuntime.getSetting("TWITTER_DRY_RUN")).toBe(true); + expect(client.state["TWITTER_USERNAME"]).toBe('testuser'); + expect(mockRuntime.getSetting("TWITTER_DRY_RUN")).toBe('true'); + expect(client.state["TWITTER_DRY_RUN"]).toBe(true); }); it('should initialize with correct post intervals', () => { - const client = new ClientBase(mockRuntime); - expect(mockRuntime.getSetting("TWITTER_POST_INTERVAL_MIN")).toBe(90); - expect(mockRuntime.getSetting("TWITTER_POST_INTERVAL_MAX")).toBe(180); + const client = new ClientBase(mockRuntime, mockConfig); + expect(mockRuntime.getSetting("TWITTER_POST_INTERVAL_MIN")).toBe('90'); + expect(client.state["TWITTER_POST_INTERVAL_MIN"]).toBe(90); + expect(mockRuntime.getSetting("TWITTER_POST_INTERVAL_MAX")).toBe('180'); + expect(client.state["TWITTER_POST_INTERVAL_MAX"]).toBe(180); }); }); diff --git a/packages/plugin-twitter/__tests__/environment.test.ts b/packages/plugin-twitter/__tests__/environment.test.ts index 83167d78683..343d3b4be94 100644 --- a/packages/plugin-twitter/__tests__/environment.test.ts +++ b/packages/plugin-twitter/__tests__/environment.test.ts @@ -2,23 +2,25 @@ import { describe, it, expect, vi } from 'vitest'; import { validateTwitterConfig } from '../src/environment'; import type { IAgentRuntime } from '@elizaos/core'; +const env = { + TWITTER_USERNAME: 'testuser123', + TWITTER_DRY_RUN: 'true', + TWITTER_SPACES_ENABLE: 'false', + TWITTER_TARGET_USERS: 'user1,user2,user3', + TWITTER_POST_INTERVAL_MIN: '90', + TWITTER_POST_INTERVAL_MAX: '180', + TWITTER_ENABLE_ACTION_PROCESSING: 'false', + TWITTER_POST_IMMEDIATELY: 'false', + TWITTER_EMAIL: 'test@example.com', + TWITTER_PASSWORD: 'hashedpassword', + TWITTER_2FA_SECRET: '', + TWITTER_POLL_INTERVAL: '120', + TWITTER_RETRY_LIMIT: '5' +} + describe('Twitter Environment Configuration', () => { const mockRuntime: IAgentRuntime = { - env: { - TWITTER_USERNAME: 'testuser123', - TWITTER_DRY_RUN: 'true', - TWITTER_SPACES_ENABLE: 'false', - TWITTER_TARGET_USERS: 'user1,user2,user3', - TWITTER_POST_INTERVAL_MIN: '90', - TWITTER_POST_INTERVAL_MAX: '180', - TWITTER_ENABLE_ACTION_PROCESSING: 'false', - TWITTER_POST_IMMEDIATELY: 'false', - TWITTER_EMAIL: 'test@example.com', - TWITTER_PASSWORD: 'hashedpassword', - TWITTER_2FA_SECRET: '', - TWITTER_POLL_INTERVAL: '120', - TWITTER_RETRY_LIMIT: '5' - }, + env, getEnv: function (key: string) { return this.env[key] || null; }, @@ -34,8 +36,8 @@ describe('Twitter Environment Configuration', () => { expect(config.TWITTER_DRY_RUN).toBe(true); expect(config.TWITTER_SPACES_ENABLE).toBe(false); expect(config.TWITTER_TARGET_USERS).toEqual(['user1', 'user2', 'user3']); - expect(config.POST_INTERVAL_MIN).toBe(90); - expect(config.POST_INTERVAL_MAX).toBe(180); + expect(config.TWITTER_POST_INTERVAL_MIN).toBe(90); + expect(config.TWITTER_POST_INTERVAL_MAX).toBe(180); expect(config.TWITTER_POST_IMMEDIATELY).toBe(false); }); @@ -43,7 +45,7 @@ describe('Twitter Environment Configuration', () => { const wildcardRuntime = { ...mockRuntime, env: { - ...mockRuntime.env, + ...env, TWITTER_USERNAME: '*' }, getEnv: function(key: string) { @@ -62,7 +64,7 @@ describe('Twitter Environment Configuration', () => { const validRuntime = { ...mockRuntime, env: { - ...mockRuntime.env, + ...env, TWITTER_USERNAME: 'test_user_123' }, getEnv: function(key: string) { @@ -81,7 +83,7 @@ describe('Twitter Environment Configuration', () => { const runtimeWithoutTargets = { ...mockRuntime, env: { - ...mockRuntime.env, + ...env, TWITTER_TARGET_USERS: '' }, getEnv: function(key: string) { @@ -115,7 +117,7 @@ describe('Twitter Environment Configuration', () => { const config = await validateTwitterConfig(minimalRuntime); expect(config).toBeDefined(); - expect(config.POST_INTERVAL_MIN).toBe(90); - expect(config.POST_INTERVAL_MAX).toBe(180); + expect(config.TWITTER_POST_INTERVAL_MIN).toBe(90); + expect(config.TWITTER_POST_INTERVAL_MAX).toBe(180); }); }); diff --git a/packages/plugin-twitter/src/environment.ts b/packages/plugin-twitter/src/environment.ts index 6d6d73e9c93..845530b0faa 100644 --- a/packages/plugin-twitter/src/environment.ts +++ b/packages/plugin-twitter/src/environment.ts @@ -61,8 +61,8 @@ export const twitterEnvSchema = z.object({ .default(''), */ TWITTER_ENABLE_POST_GENERATION: z.boolean(), - POST_INTERVAL_MIN: z.number().int(), - POST_INTERVAL_MAX: z.number().int(), + TWITTER_POST_INTERVAL_MIN: z.number().int(), + TWITTER_POST_INTERVAL_MAX: z.number().int(), TWITTER_POST_IMMEDIATELY: z.boolean(), TWITTER_SPACES_ENABLE: z.boolean().default(false), }); @@ -159,16 +159,16 @@ export async function validateTwitterConfig( // int in minutes - POST_INTERVAL_MIN: safeParseInt( - runtime.getSetting("POST_INTERVAL_MIN") || - process.env.POST_INTERVAL_MIN, + TWITTER_POST_INTERVAL_MIN: safeParseInt( + runtime.getSetting("TWITTER_POST_INTERVAL_MIN") || + process.env.TWITTER_POST_INTERVAL_MIN, 90 // 1.5 hours ), // int in minutes - POST_INTERVAL_MAX: safeParseInt( - runtime.getSetting("POST_INTERVAL_MAX") || - process.env.POST_INTERVAL_MAX, + TWITTER_POST_INTERVAL_MAX: safeParseInt( + runtime.getSetting("TWITTER_POST_INTERVAL_MAX") || + process.env.TWITTER_POST_INTERVAL_MAX, 180 // 3 hours ), From 14f1a0b6ccc5eb39b1cdd380d0c6174d91ff378d Mon Sep 17 00:00:00 2001 From: Ting Chien Meng Date: Mon, 17 Feb 2025 15:46:36 +0800 Subject: [PATCH 2/4] fix post test error and add more test --- .../plugin-twitter/__tests__/post.test.ts | 341 +++++++++++++----- packages/plugin-twitter/src/post.ts | 17 +- 2 files changed, 260 insertions(+), 98 deletions(-) diff --git a/packages/plugin-twitter/__tests__/post.test.ts b/packages/plugin-twitter/__tests__/post.test.ts index 3f2a1010916..19d62f96864 100644 --- a/packages/plugin-twitter/__tests__/post.test.ts +++ b/packages/plugin-twitter/__tests__/post.test.ts @@ -1,92 +1,251 @@ -import { describe, it, expect, vi } from 'vitest'; -import { TwitterPostClient } from '../src/post'; -import { ClientBase } from '../src/base'; -import type { IAgentRuntime } from '@elizaos/core'; -import type { TwitterConfig } from '../src/environment'; - -describe('Twitter Post Client', () => { - let mockRuntime: IAgentRuntime; - let mockConfig: TwitterConfig; - let baseClient: ClientBase; - - beforeEach(() => { - mockRuntime = { - env: { - TWITTER_USERNAME: 'testuser', - TWITTER_DRY_RUN: 'true', - TWITTER_POST_INTERVAL_MIN: '5', - TWITTER_POST_INTERVAL_MAX: '10', - TWITTER_ENABLE_ACTION_PROCESSING: 'true', - TWITTER_POST_IMMEDIATELY: 'false', - TWITTER_EMAIL: 'test@example.com', - TWITTER_PASSWORD: 'hashedpassword', - TWITTER_2FA_SECRET: '', - TWITTER_POLL_INTERVAL: '120', - TWITTER_RETRY_LIMIT: '5', - }, - getEnv: function (key: string) { - return this.env[key] || null; - }, - getSetting: function (key: string) { - return this.env[key] || null; - }, - character: { - style: { - all: ['Test style 1', 'Test style 2'], - post: ['Post style 1', 'Post style 2'] - } - } - } as unknown as IAgentRuntime; - - mockConfig = { - TWITTER_USERNAME: 'testuser', - TWITTER_DRY_RUN: true, - TWITTER_SPACES_ENABLE: false, - TWITTER_TARGET_USERS: [], - TWITTER_PASSWORD: 'hashedpassword', - TWITTER_EMAIL: 'test@example.com', - TWITTER_2FA_SECRET: '', - TWITTER_RETRY_LIMIT: 5, - TWITTER_POLL_INTERVAL: 120, - POST_INTERVAL_MIN: 5, - POST_INTERVAL_MAX: 10, - TWITTER_ENABLE_POST_GENERATION: true, - TWITTER_POST_IMMEDIATELY: false, - }; - - baseClient = new ClientBase(mockRuntime, mockConfig); - }); - - it('should create post client instance', () => { - const postClient = new TwitterPostClient(baseClient, mockRuntime); - expect(postClient).toBeDefined(); - expect(postClient.twitterUsername).toBe('testuser'); - expect(postClient['isDryRun']).toBe(true); - }); - - it('should keep tweets under max length when already valid', () => { - const postClient = new TwitterPostClient(baseClient, mockRuntime); - const validTweet = 'This is a valid tweet'; - const result = postClient['trimTweetLength'](validTweet); - expect(result).toBe(validTweet); - expect(result.length).toBeLessThanOrEqual(280); - }); - - it('should cut at last sentence when possible', () => { - const postClient = new TwitterPostClient(baseClient, mockRuntime); - const longTweet = 'First sentence. Second sentence that is quite long. Third sentence that would make it too long.'; - const result = postClient['trimTweetLength'](longTweet); - const lastPeriod = result.lastIndexOf('.'); - expect(lastPeriod).toBeGreaterThan(0); - expect(result.length).toBeLessThanOrEqual(280); - }); - - it('should add ellipsis when cutting within a sentence', () => { - const postClient = new TwitterPostClient(baseClient, mockRuntime); - const longSentence = 'This is an extremely long sentence without any periods that needs to be truncated because it exceeds the maximum allowed length for a tweet on the Twitter platform and therefore must be shortened'; - const result = postClient['trimTweetLength'](longSentence); - const lastSpace = result.lastIndexOf(' '); - expect(lastSpace).toBeGreaterThan(0); - expect(result.length).toBeLessThanOrEqual(280); - }); +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { TwitterPostClient } from "../src/post"; +import { ClientBase } from "../src/base"; +import type { IAgentRuntime } from "@elizaos/core"; +import type { TwitterConfig } from "../src/environment"; +import { truncateToCompleteSentence, logger } from "@elizaos/core"; + +const MAX_TWITTER_POST_LENGTH = 280; + +vi.mock("@elizaos/core", async () => { + const actual = await vi.importActual( + "@elizaos/core" + ); + + return { + ...actual, + logger: { + log: vi.fn(), + info: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + }, + stringToUuid: (str: string) => str, + messageCompletionFooter: + "# INSTRUCTIONS: Choose the best response for the agent.", + shouldRespondFooter: "# INSTRUCTIONS: Choose if the agent should respond.", + generateMessageResponse: vi.fn(), + generateText: vi + .fn() + .mockResolvedValue("{text: mock text, action: mock-action}"), + generateShouldRespond: vi.fn().mockResolvedValue("IGNORE"), // Prevent API calls by always returning "IGNORE" + composeContext: vi.fn(), + ModelClass: { + TEXT_SMALL: "TEXT_SMALL", + }, + ServiceType: { + VIDEO: "VIDEO", + BROWSER: "BROWSER", + }, + }; +}); + +vi.mock("./utils.ts", () => ({ + fetchMediaData: vi.fn(), +})); + +describe("Twitter Post Client", () => { + let mockRuntime: IAgentRuntime; + let mockConfig: TwitterConfig; + let baseClient: ClientBase; + let postClient: TwitterPostClient; + + beforeEach(() => { + mockRuntime = { + env: { + TWITTER_USERNAME: "testuser", + TWITTER_DRY_RUN: "true", + TWITTER_POST_INTERVAL_MIN: "5", + TWITTER_POST_INTERVAL_MAX: "10", + TWITTER_ENABLE_ACTION_PROCESSING: "true", + TWITTER_POST_IMMEDIATELY: "false", + TWITTER_EMAIL: "test@example.com", + TWITTER_PASSWORD: "hashedpassword", + TWITTER_2FA_SECRET: "", + TWITTER_POLL_INTERVAL: "120", + TWITTER_RETRY_LIMIT: "5", + }, + getEnv: function (key: string) { + return this.env[key] || null; + }, + getSetting: function (key: string) { + return this.env[key] || null; + }, + cacheManager: { + get: vi.fn().mockResolvedValue(null), + set: vi.fn().mockResolvedValue(true), + }, + messageManager: { + createMemory: vi.fn().mockResolvedValue(true), + }, + composeState: vi.fn(), + composeContext: vi.fn(), + ensureUserExists: vi.fn().mockResolvedValue(true), + ensureRoomExists: vi.fn().mockResolvedValue(true), + ensureParticipantInRoom: vi.fn().mockResolvedValue(true), + character: { + templates: { + twitterPostTemplate: "Mock template", + }, + }, + topics: [], + } as unknown as IAgentRuntime; + + mockConfig = { + TWITTER_USERNAME: "testuser", + TWITTER_DRY_RUN: true, + TWITTER_SPACES_ENABLE: false, + TWITTER_TARGET_USERS: [], + TWITTER_PASSWORD: "hashedpassword", + TWITTER_EMAIL: "test@example.com", + TWITTER_2FA_SECRET: "", + TWITTER_RETRY_LIMIT: 5, + TWITTER_POLL_INTERVAL: 120, + TWITTER_POST_INTERVAL_MIN: 5, + TWITTER_POST_INTERVAL_MAX: 10, + TWITTER_ENABLE_POST_GENERATION: true, + TWITTER_POST_IMMEDIATELY: false, + }; + + baseClient = new ClientBase(mockRuntime, mockConfig); + baseClient.profile = { + screenName: "Mock Screen Name", + username: "mockuser", + id: "mock-id", + bio: "Mock bio for testing.", + nicknames: ["MockNickname"], + }; + + postClient = new TwitterPostClient(baseClient, mockRuntime, mockConfig); + }); + + it("should create post client instance", () => { + expect(postClient).toBeDefined(); + expect(postClient.twitterUsername).toBe("testuser"); + expect(postClient["isDryRun"]).toBe(true); + }); + + it("should keep tweets under max length when already valid", () => { + const validTweet = "This is a valid tweet"; + const result = truncateToCompleteSentence( + validTweet, + MAX_TWITTER_POST_LENGTH + ); + expect(result).toBe(validTweet); + expect(result.length).toBeLessThanOrEqual(280); + }); + + it("should cut at last sentence when possible", () => { + const longTweet = + "First sentence. Second sentence that is quite long. Third sentence that would make it too long."; + const result = truncateToCompleteSentence( + longTweet, + MAX_TWITTER_POST_LENGTH + ); + const lastPeriod = result.lastIndexOf("."); + expect(lastPeriod).toBeGreaterThan(0); + expect(result.length).toBeLessThanOrEqual(280); + }); + + it("should add ellipsis when cutting within a sentence", () => { + const longSentence = + "This is an extremely long sentence without any periods that needs to be truncated because it exceeds the maximum allowed length for a tweet on the Twitter platform and therefore must be shortened"; + const result = truncateToCompleteSentence( + longSentence, + MAX_TWITTER_POST_LENGTH + ); + const lastSpace = result.lastIndexOf(" "); + expect(lastSpace).toBeGreaterThan(0); + expect(result.length).toBeLessThanOrEqual(280); + }); + + it("should call postTweet when dry run mode is disabled", async () => { + postClient["isDryRun"] = false; + const postTweetSpy = vi + .spyOn(postClient, "postTweet") + .mockResolvedValue(undefined); + + await postClient.generateNewTweet(); + + expect(postTweetSpy).toHaveBeenCalled(); + }); + + it("should NOT call postTweet in dry run mode", async () => { + const postTweetSpy = vi + .spyOn(postClient, "postTweet") + .mockResolvedValue(undefined); + + await postClient.generateNewTweet(); + + expect(postTweetSpy).not.toHaveBeenCalled(); + }); + it("should handle Twitter API errors gracefully", async () => { + const mockError = new Error("Twitter API error"); + vi.spyOn(logger, "error"); + vi.spyOn(postClient, "sendStandardTweet").mockRejectedValue(mockError); + + await expect( + postClient.postTweet( + mockRuntime, + baseClient, + "Test tweet", + "room-id" as any, + "raw tweet", + "testuser" + ) + ).rejects.toThrow(mockError); + + expect(logger.error).toHaveBeenCalledWith( + expect.stringContaining("Error sending tweet:") + ); + }); + + it("should process a tweet and cache it", async () => { + const tweetData = { + rest_id: "mock-tweet-id", + legacy: { + full_text: "Mock tweet", + }, + }; + + const tweet = postClient.createTweetObject( + tweetData, + baseClient, + baseClient.profile?.username as any + ); + + await postClient.processAndCacheTweet( + mockRuntime, + baseClient, + tweet, + "room-id" as any, + "raw tweet" + ); + + expect(mockRuntime.cacheManager.set).toHaveBeenCalledWith( + `twitter/${baseClient.profile?.username}/lastPost`, + expect.objectContaining({ id: "mock-tweet-id" }) + ); + }); + + it("should properly construct tweet objects", () => { + const tweetData = { + rest_id: "mock-tweet-id", + legacy: { + full_text: "Mock tweet", + }, + }; + + const tweet = postClient.createTweetObject( + tweetData, + baseClient, + "testuser" + ); + + expect(tweet.id).toBe("mock-tweet-id"); + expect(tweet.text).toBe("Mock tweet"); + expect(tweet.permanentUrl).toBe( + "https://twitter.com/testuser/status/mock-tweet-id" + ); + }); }); diff --git a/packages/plugin-twitter/src/post.ts b/packages/plugin-twitter/src/post.ts index 24093fd3400..2bde17c1351 100644 --- a/packages/plugin-twitter/src/post.ts +++ b/packages/plugin-twitter/src/post.ts @@ -40,9 +40,6 @@ export class TwitterPostClient { client: ClientBase; runtime: IAgentRuntime; twitterUsername: string; - private isProcessing = false; - private lastProcessTime = 0; - private stopProcessingActions = false; private isDryRun: boolean; private state: any; @@ -289,6 +286,7 @@ export class TwitterPostClient { mediaData ); } + const tweet = this.createTweetObject( result, client, @@ -303,7 +301,8 @@ export class TwitterPostClient { rawTweetContent ); } catch (error) { - logger.error("Error sending tweet:", error); + logger.error("Error sending tweet:"); + throw error; } } @@ -317,14 +316,17 @@ export class TwitterPostClient { const roomId = stringToUuid( "twitter_generate_room-" + this.client.profile.username ); + await this.runtime.ensureUserExists( this.runtime.agentId, this.client.profile.username, this.runtime.character.name, "twitter" ); + - const topics = this.runtime.character.topics.join(", "); + const topics = this.runtime.character.topics?.join(", "); + const state = await this.runtime.composeState( { userId: this.runtime.agentId, @@ -339,11 +341,12 @@ export class TwitterPostClient { twitterUserName: this.client.profile.username } ); + const context = composeContext({ state, template: - this.runtime.character.templates?.twitterPostTemplate || + this.runtime.character?.templates?.twitterPostTemplate || twitterPostTemplate, }); @@ -441,6 +444,6 @@ export class TwitterPostClient { } async stop() { - this.stopProcessingActions = true; + } } From b2cf4c069593140f14f4e1a5708ce109a328d8c2 Mon Sep 17 00:00:00 2001 From: Ting Chien Meng Date: Mon, 17 Feb 2025 15:52:18 +0800 Subject: [PATCH 3/4] clean code --- .../plugin-twitter/__tests__/post.test.ts | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/packages/plugin-twitter/__tests__/post.test.ts b/packages/plugin-twitter/__tests__/post.test.ts index 19d62f96864..27989d27401 100644 --- a/packages/plugin-twitter/__tests__/post.test.ts +++ b/packages/plugin-twitter/__tests__/post.test.ts @@ -19,31 +19,14 @@ vi.mock("@elizaos/core", async () => { info: vi.fn(), error: vi.fn(), debug: vi.fn(), + warn: vi.fn(), }, - stringToUuid: (str: string) => str, - messageCompletionFooter: - "# INSTRUCTIONS: Choose the best response for the agent.", - shouldRespondFooter: "# INSTRUCTIONS: Choose if the agent should respond.", - generateMessageResponse: vi.fn(), generateText: vi .fn() .mockResolvedValue("{text: mock text, action: mock-action}"), - generateShouldRespond: vi.fn().mockResolvedValue("IGNORE"), // Prevent API calls by always returning "IGNORE" - composeContext: vi.fn(), - ModelClass: { - TEXT_SMALL: "TEXT_SMALL", - }, - ServiceType: { - VIDEO: "VIDEO", - BROWSER: "BROWSER", - }, }; }); -vi.mock("./utils.ts", () => ({ - fetchMediaData: vi.fn(), -})); - describe("Twitter Post Client", () => { let mockRuntime: IAgentRuntime; let mockConfig: TwitterConfig; @@ -199,7 +182,7 @@ describe("Twitter Post Client", () => { expect.stringContaining("Error sending tweet:") ); }); - + it("should process a tweet and cache it", async () => { const tweetData = { rest_id: "mock-tweet-id", From 0104dd0fabfdffa0f6a6963c1756f4c9b7142e41 Mon Sep 17 00:00:00 2001 From: Ting Chien Meng Date: Mon, 17 Feb 2025 16:10:32 +0800 Subject: [PATCH 4/4] clean code --- packages/plugin-twitter/__tests__/post.test.ts | 2 +- packages/plugin-twitter/src/post.ts | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/plugin-twitter/__tests__/post.test.ts b/packages/plugin-twitter/__tests__/post.test.ts index 27989d27401..f27e85dfd6a 100644 --- a/packages/plugin-twitter/__tests__/post.test.ts +++ b/packages/plugin-twitter/__tests__/post.test.ts @@ -70,8 +70,8 @@ describe("Twitter Post Client", () => { templates: { twitterPostTemplate: "Mock template", }, + topics: [], }, - topics: [], } as unknown as IAgentRuntime; mockConfig = { diff --git a/packages/plugin-twitter/src/post.ts b/packages/plugin-twitter/src/post.ts index 2bde17c1351..8fb8ddccab9 100644 --- a/packages/plugin-twitter/src/post.ts +++ b/packages/plugin-twitter/src/post.ts @@ -286,7 +286,6 @@ export class TwitterPostClient { mediaData ); } - const tweet = this.createTweetObject( result, client, @@ -316,17 +315,14 @@ export class TwitterPostClient { const roomId = stringToUuid( "twitter_generate_room-" + this.client.profile.username ); - await this.runtime.ensureUserExists( this.runtime.agentId, this.client.profile.username, this.runtime.character.name, "twitter" ); - - const topics = this.runtime.character.topics?.join(", "); - + const topics = this.runtime.character.topics.join(", "); const state = await this.runtime.composeState( { userId: this.runtime.agentId, @@ -341,12 +337,11 @@ export class TwitterPostClient { twitterUserName: this.client.profile.username } ); - const context = composeContext({ state, template: - this.runtime.character?.templates?.twitterPostTemplate || + this.runtime.character.templates?.twitterPostTemplate || twitterPostTemplate, });