Skip to content

Commit 902b31e

Browse files
authored
Merge pull request elizaOS#1997 from elizaOS/tcm-fix-dryrun
fix: client twitter dryrun
2 parents 540c3ee + e1389d6 commit 902b31e

File tree

2 files changed

+132
-140
lines changed

2 files changed

+132
-140
lines changed

packages/client-twitter/src/interactions.ts

+51-41
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ Thread of Tweets You Are Replying To:
9090
export class TwitterInteractionClient {
9191
client: ClientBase;
9292
runtime: IAgentRuntime;
93+
private isDryRun: boolean;
9394
constructor(client: ClientBase, runtime: IAgentRuntime) {
9495
this.client = client;
9596
this.runtime = runtime;
97+
this.isDryRun = this.client.twitterConfig.TWITTER_DRY_RUN;
9698
}
9799

98100
async start() {
@@ -430,54 +432,62 @@ export class TwitterInteractionClient {
430432
response.text = removeQuotes(response.text);
431433

432434
if (response.text) {
433-
try {
434-
const callback: HandlerCallback = async (response: Content) => {
435-
const memories = await sendTweet(
436-
this.client,
437-
response,
438-
message.roomId,
439-
this.client.twitterConfig.TWITTER_USERNAME,
440-
tweet.id
441-
);
442-
return memories;
443-
};
435+
if (this.isDryRun) {
436+
elizaLogger.info(
437+
`Dry run: Selected Post: ${tweet.id} - ${tweet.username}: ${tweet.text}\nAgent's Output:\n${response.text}`
438+
);
439+
} else {
440+
try {
441+
const callback: HandlerCallback = async (
442+
response: Content
443+
) => {
444+
const memories = await sendTweet(
445+
this.client,
446+
response,
447+
message.roomId,
448+
this.client.twitterConfig.TWITTER_USERNAME,
449+
tweet.id
450+
);
451+
return memories;
452+
};
444453

445-
const responseMessages = await callback(response);
454+
const responseMessages = await callback(response);
446455

447-
state = (await this.runtime.updateRecentMessageState(
448-
state
449-
)) as State;
456+
state = (await this.runtime.updateRecentMessageState(
457+
state
458+
)) as State;
450459

451-
for (const responseMessage of responseMessages) {
452-
if (
453-
responseMessage ===
454-
responseMessages[responseMessages.length - 1]
455-
) {
456-
responseMessage.content.action = response.action;
457-
} else {
458-
responseMessage.content.action = "CONTINUE";
460+
for (const responseMessage of responseMessages) {
461+
if (
462+
responseMessage ===
463+
responseMessages[responseMessages.length - 1]
464+
) {
465+
responseMessage.content.action = response.action;
466+
} else {
467+
responseMessage.content.action = "CONTINUE";
468+
}
469+
await this.runtime.messageManager.createMemory(
470+
responseMessage
471+
);
459472
}
460-
await this.runtime.messageManager.createMemory(
461-
responseMessage
462-
);
463-
}
464473

465-
await this.runtime.processActions(
466-
message,
467-
responseMessages,
468-
state,
469-
callback
470-
);
474+
await this.runtime.processActions(
475+
message,
476+
responseMessages,
477+
state,
478+
callback
479+
);
471480

472-
const responseInfo = `Context:\n\n${context}\n\nSelected Post: ${tweet.id} - ${tweet.username}: ${tweet.text}\nAgent's Output:\n${response.text}`;
481+
const responseInfo = `Context:\n\n${context}\n\nSelected Post: ${tweet.id} - ${tweet.username}: ${tweet.text}\nAgent's Output:\n${response.text}`;
473482

474-
await this.runtime.cacheManager.set(
475-
`twitter/tweet_generation_${tweet.id}.txt`,
476-
responseInfo
477-
);
478-
await wait();
479-
} catch (error) {
480-
elizaLogger.error(`Error sending response tweet: ${error}`);
483+
await this.runtime.cacheManager.set(
484+
`twitter/tweet_generation_${tweet.id}.txt`,
485+
responseInfo
486+
);
487+
await wait();
488+
} catch (error) {
489+
elizaLogger.error(`Error sending response tweet: ${error}`);
490+
}
481491
}
482492
}
483493
}

packages/client-twitter/src/post.ts

+81-99
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
ModelClass,
88
stringToUuid,
99
TemplateType,
10-
UUID
10+
UUID,
1111
} from "@elizaos/core";
1212
import { elizaLogger } from "@elizaos/core";
1313
import { ClientBase } from "./base.ts";
@@ -215,33 +215,16 @@ export class TwitterPostClient {
215215
}
216216

217217
// Only start tweet generation loop if not in dry run mode
218-
if (!this.isDryRun) {
219-
generateNewTweetLoop();
220-
elizaLogger.log("Tweet generation loop started");
221-
} else {
222-
elizaLogger.log("Tweet generation loop disabled (dry run mode)");
223-
}
218+
generateNewTweetLoop();
219+
elizaLogger.log("Tweet generation loop started");
224220

225-
if (
226-
this.client.twitterConfig.ENABLE_ACTION_PROCESSING &&
227-
!this.isDryRun
228-
) {
221+
if (this.client.twitterConfig.ENABLE_ACTION_PROCESSING) {
229222
processActionsLoop().catch((error) => {
230223
elizaLogger.error(
231224
"Fatal error in process actions loop:",
232225
error
233226
);
234227
});
235-
} else {
236-
if (this.isDryRun) {
237-
elizaLogger.log(
238-
"Action processing loop disabled (dry run mode)"
239-
);
240-
} else {
241-
elizaLogger.log(
242-
"Action processing loop disabled by configuration"
243-
);
244-
}
245228
}
246229
}
247230

@@ -618,26 +601,21 @@ export class TwitterPostClient {
618601

619602
elizaLogger.log("Processing tweet actions");
620603

621-
if (this.isDryRun) {
622-
elizaLogger.log("Dry run mode: simulating tweet actions");
623-
return [];
624-
}
625-
626604
await this.runtime.ensureUserExists(
627605
this.runtime.agentId,
628606
this.twitterUsername,
629607
this.runtime.character.name,
630608
"twitter"
631609
);
632610

633-
const homeTimeline = await this.client.fetchTimelineForActions(
611+
const timelines = await this.client.fetchTimelineForActions(
634612
MAX_TIMELINES_TO_FETCH
635613
);
636614
const maxActionsProcessing =
637615
this.client.twitterConfig.MAX_ACTIONS_PROCESSING;
638616
const processedTimelines = [];
639617

640-
for (const tweet of homeTimeline) {
618+
for (const tweet of timelines) {
641619
try {
642620
// Skip if we've already processed this tweet
643621
const memory =
@@ -770,56 +748,47 @@ export class TwitterPostClient {
770748
const executedActions: string[] = [];
771749
// Execute actions
772750
if (actionResponse.like) {
773-
try {
774-
if (this.isDryRun) {
775-
elizaLogger.info(
776-
`Dry run: would have liked tweet ${tweet.id}`
777-
);
778-
executedActions.push("like (dry run)");
779-
} else {
751+
if (this.isDryRun) {
752+
elizaLogger.info(
753+
`Dry run: would have liked tweet ${tweet.id}`
754+
);
755+
executedActions.push("like (dry run)");
756+
} else {
757+
try {
780758
await this.client.twitterClient.likeTweet(tweet.id);
781759
executedActions.push("like");
782760
elizaLogger.log(`Liked tweet ${tweet.id}`);
761+
} catch (error) {
762+
elizaLogger.error(
763+
`Error liking tweet ${tweet.id}:`,
764+
error
765+
);
783766
}
784-
} catch (error) {
785-
elizaLogger.error(
786-
`Error liking tweet ${tweet.id}:`,
787-
error
788-
);
789767
}
790768
}
791769

792770
if (actionResponse.retweet) {
793-
try {
794-
if (this.isDryRun) {
795-
elizaLogger.info(
796-
`Dry run: would have retweeted tweet ${tweet.id}`
797-
);
798-
executedActions.push("retweet (dry run)");
799-
} else {
771+
if (this.isDryRun) {
772+
elizaLogger.info(
773+
`Dry run: would have retweeted tweet ${tweet.id}`
774+
);
775+
executedActions.push("retweet (dry run)");
776+
} else {
777+
try {
800778
await this.client.twitterClient.retweet(tweet.id);
801779
executedActions.push("retweet");
802780
elizaLogger.log(`Retweeted tweet ${tweet.id}`);
781+
} catch (error) {
782+
elizaLogger.error(
783+
`Error retweeting tweet ${tweet.id}:`,
784+
error
785+
);
803786
}
804-
} catch (error) {
805-
elizaLogger.error(
806-
`Error retweeting tweet ${tweet.id}:`,
807-
error
808-
);
809787
}
810788
}
811789

812790
if (actionResponse.quote) {
813791
try {
814-
// Check for dry run mode
815-
if (this.isDryRun) {
816-
elizaLogger.info(
817-
`Dry run: would have posted quote tweet for ${tweet.id}`
818-
);
819-
executedActions.push("quote (dry run)");
820-
continue;
821-
}
822-
823792
// Build conversation thread for context
824793
const thread = await buildConversationThread(
825794
tweet,
@@ -915,32 +884,43 @@ export class TwitterPostClient {
915884
"Generated quote tweet content:",
916885
quoteContent
917886
);
918-
919-
// Send the tweet through request queue
920-
const result = await this.client.requestQueue.add(
921-
async () =>
922-
await this.client.twitterClient.sendQuoteTweet(
923-
quoteContent,
924-
tweet.id
925-
)
926-
);
927-
928-
const body = await result.json();
929-
930-
if (body?.data?.create_tweet?.tweet_results?.result) {
931-
elizaLogger.log("Successfully posted quote tweet");
932-
executedActions.push("quote");
933-
934-
// Cache generation context for debugging
935-
await this.runtime.cacheManager.set(
936-
`twitter/quote_generation_${tweet.id}.txt`,
937-
`Context:\n${enrichedState}\n\nGenerated Quote:\n${quoteContent}`
887+
// Check for dry run mode
888+
if (this.isDryRun) {
889+
elizaLogger.info(
890+
`Dry run: A quote tweet for tweet ID ${tweet.id} would have been posted with the following content: "${quoteContent}".`
938891
);
892+
executedActions.push("quote (dry run)");
939893
} else {
940-
elizaLogger.error(
941-
"Quote tweet creation failed:",
942-
body
894+
// Send the tweet through request queue
895+
const result = await this.client.requestQueue.add(
896+
async () =>
897+
await this.client.twitterClient.sendQuoteTweet(
898+
quoteContent,
899+
tweet.id
900+
)
943901
);
902+
903+
const body = await result.json();
904+
905+
if (
906+
body?.data?.create_tweet?.tweet_results?.result
907+
) {
908+
elizaLogger.log(
909+
"Successfully posted quote tweet"
910+
);
911+
executedActions.push("quote");
912+
913+
// Cache generation context for debugging
914+
await this.runtime.cacheManager.set(
915+
`twitter/quote_generation_${tweet.id}.txt`,
916+
`Context:\n${enrichedState}\n\nGenerated Quote:\n${quoteContent}`
917+
);
918+
} else {
919+
elizaLogger.error(
920+
"Quote tweet creation failed:",
921+
body
922+
);
923+
}
944924
}
945925
} catch (error) {
946926
elizaLogger.error(
@@ -978,21 +958,23 @@ export class TwitterPostClient {
978958
roomId
979959
);
980960

981-
// Then create the memory
982-
await this.runtime.messageManager.createMemory({
983-
id: stringToUuid(tweet.id + "-" + this.runtime.agentId),
984-
userId: stringToUuid(tweet.userId),
985-
content: {
986-
text: tweet.text,
987-
url: tweet.permanentUrl,
988-
source: "twitter",
989-
action: executedActions.join(","),
990-
},
991-
agentId: this.runtime.agentId,
992-
roomId,
993-
embedding: getEmbeddingZeroVector(),
994-
createdAt: tweet.timestamp * 1000,
995-
});
961+
if (!this.isDryRun) {
962+
// Then create the memory
963+
await this.runtime.messageManager.createMemory({
964+
id: stringToUuid(tweet.id + "-" + this.runtime.agentId),
965+
userId: stringToUuid(tweet.userId),
966+
content: {
967+
text: tweet.text,
968+
url: tweet.permanentUrl,
969+
source: "twitter",
970+
action: executedActions.join(","),
971+
},
972+
agentId: this.runtime.agentId,
973+
roomId,
974+
embedding: getEmbeddingZeroVector(),
975+
createdAt: tweet.timestamp * 1000,
976+
});
977+
}
996978

997979
results.push({
998980
tweetId: tweet.id,

0 commit comments

Comments
 (0)