@elizaos/plugin-twitter 1.2.10 → 1.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -452,7 +452,10 @@ async function followUser(username, auth) {
452
452
  if (!meResponse.data) {
453
453
  throw new Error("Failed to get authenticated user");
454
454
  }
455
- const result = await client.v2.follow(meResponse.data.id, userResponse.data.id);
455
+ const result = await client.v2.follow(
456
+ meResponse.data.id,
457
+ userResponse.data.id
458
+ );
456
459
  return new Response(JSON.stringify(result), {
457
460
  status: result.data?.following ? 200 : 400,
458
461
  headers: new Headers({ "Content-Type": "application/json" })
@@ -748,7 +751,9 @@ async function fetchTweetsAndReplies(userId, maxTweets, cursor, auth) {
748
751
  next: response.meta.next_token
749
752
  };
750
753
  } catch (error) {
751
- throw new Error(`Failed to fetch tweets and replies: ${error?.message || error}`);
754
+ throw new Error(
755
+ `Failed to fetch tweets and replies: ${error?.message || error}`
756
+ );
752
757
  }
753
758
  }
754
759
  async function createCreateTweetRequestV2(text, auth, tweetId, options) {
@@ -822,9 +827,15 @@ function parseTweetV2ToV1(tweetV2, includes) {
822
827
  isReply: tweetV2.referenced_tweets?.some((ref) => ref.type === "replied_to") ?? false,
823
828
  isRetweet: tweetV2.referenced_tweets?.some((ref) => ref.type === "retweeted") ?? false,
824
829
  isQuoted: tweetV2.referenced_tweets?.some((ref) => ref.type === "quoted") ?? false,
825
- inReplyToStatusId: tweetV2.referenced_tweets?.find((ref) => ref.type === "replied_to")?.id,
826
- quotedStatusId: tweetV2.referenced_tweets?.find((ref) => ref.type === "quoted")?.id,
827
- retweetedStatusId: tweetV2.referenced_tweets?.find((ref) => ref.type === "retweeted")?.id
830
+ inReplyToStatusId: tweetV2.referenced_tweets?.find(
831
+ (ref) => ref.type === "replied_to"
832
+ )?.id,
833
+ quotedStatusId: tweetV2.referenced_tweets?.find(
834
+ (ref) => ref.type === "quoted"
835
+ )?.id,
836
+ retweetedStatusId: tweetV2.referenced_tweets?.find(
837
+ (ref) => ref.type === "retweeted"
838
+ )?.id
828
839
  };
829
840
  if (includes?.polls?.length) {
830
841
  const poll = includes.polls[0];
@@ -976,7 +987,12 @@ async function* getTweets(user, maxTweets, auth) {
976
987
  let cursor;
977
988
  let totalFetched = 0;
978
989
  while (totalFetched < maxTweets) {
979
- const response = await fetchTweets(userId, maxTweets - totalFetched, cursor, auth);
990
+ const response = await fetchTweets(
991
+ userId,
992
+ maxTweets - totalFetched,
993
+ cursor,
994
+ auth
995
+ );
980
996
  for (const tweet of response.tweets) {
981
997
  yield tweet;
982
998
  totalFetched++;
@@ -990,7 +1006,12 @@ async function* getTweetsByUserId(userId, maxTweets, auth) {
990
1006
  let cursor;
991
1007
  let totalFetched = 0;
992
1008
  while (totalFetched < maxTweets) {
993
- const response = await fetchTweets(userId, maxTweets - totalFetched, cursor, auth);
1009
+ const response = await fetchTweets(
1010
+ userId,
1011
+ maxTweets - totalFetched,
1012
+ cursor,
1013
+ auth
1014
+ );
994
1015
  for (const tweet of response.tweets) {
995
1016
  yield tweet;
996
1017
  totalFetched++;
@@ -1009,7 +1030,12 @@ async function* getTweetsAndReplies(user, maxTweets, auth) {
1009
1030
  let cursor;
1010
1031
  let totalFetched = 0;
1011
1032
  while (totalFetched < maxTweets) {
1012
- const response = await fetchTweetsAndReplies(userId, maxTweets - totalFetched, cursor, auth);
1033
+ const response = await fetchTweetsAndReplies(
1034
+ userId,
1035
+ maxTweets - totalFetched,
1036
+ cursor,
1037
+ auth
1038
+ );
1013
1039
  for (const tweet of response.tweets) {
1014
1040
  yield tweet;
1015
1041
  totalFetched++;
@@ -1023,7 +1049,12 @@ async function* getTweetsAndRepliesByUserId(userId, maxTweets, auth) {
1023
1049
  let cursor;
1024
1050
  let totalFetched = 0;
1025
1051
  while (totalFetched < maxTweets) {
1026
- const response = await fetchTweetsAndReplies(userId, maxTweets - totalFetched, cursor, auth);
1052
+ const response = await fetchTweetsAndReplies(
1053
+ userId,
1054
+ maxTweets - totalFetched,
1055
+ cursor,
1056
+ auth
1057
+ );
1027
1058
  for (const tweet of response.tweets) {
1028
1059
  yield tweet;
1029
1060
  totalFetched++;
@@ -1115,10 +1146,7 @@ async function getTweetV2(id, auth, options = defaultOptions) {
1115
1146
  console.warn(`Tweet data not found for ID: ${id}`);
1116
1147
  return null;
1117
1148
  }
1118
- const parsedTweet = parseTweetV2ToV1(
1119
- tweetData.data,
1120
- tweetData?.includes
1121
- );
1149
+ const parsedTweet = parseTweetV2ToV1(tweetData.data, tweetData?.includes);
1122
1150
  return parsedTweet;
1123
1151
  } catch (error) {
1124
1152
  console.error(`Error fetching tweet ${id}:`, error);
@@ -6098,18 +6126,49 @@ async function validateTwitterConfig(runtime, config = {}) {
6098
6126
  TWITTER_API_SECRET_KEY: config.TWITTER_API_SECRET_KEY ?? getSetting(runtime, "TWITTER_API_SECRET_KEY") ?? "",
6099
6127
  TWITTER_ACCESS_TOKEN: config.TWITTER_ACCESS_TOKEN ?? getSetting(runtime, "TWITTER_ACCESS_TOKEN") ?? "",
6100
6128
  TWITTER_ACCESS_TOKEN_SECRET: config.TWITTER_ACCESS_TOKEN_SECRET ?? getSetting(runtime, "TWITTER_ACCESS_TOKEN_SECRET") ?? "",
6101
- TWITTER_DRY_RUN: String((config.TWITTER_DRY_RUN ?? getSetting(runtime, "TWITTER_DRY_RUN") ?? "false").toLowerCase() === "true"),
6129
+ TWITTER_DRY_RUN: String(
6130
+ (config.TWITTER_DRY_RUN ?? getSetting(runtime, "TWITTER_DRY_RUN") ?? "false").toLowerCase() === "true"
6131
+ ),
6102
6132
  TWITTER_TARGET_USERS: config.TWITTER_TARGET_USERS ?? getSetting(runtime, "TWITTER_TARGET_USERS") ?? "",
6103
- TWITTER_ENABLE_POST: String((config.TWITTER_ENABLE_POST ?? getSetting(runtime, "TWITTER_ENABLE_POST") ?? "false").toLowerCase() === "true"),
6133
+ TWITTER_ENABLE_POST: String(
6134
+ (config.TWITTER_ENABLE_POST ?? getSetting(runtime, "TWITTER_ENABLE_POST") ?? "false").toLowerCase() === "true"
6135
+ ),
6104
6136
  TWITTER_ENABLE_REPLIES: String(
6105
6137
  config.TWITTER_ENABLE_REPLIES !== void 0 ? config.TWITTER_ENABLE_REPLIES.toLowerCase() === "true" : (getSetting(runtime, "TWITTER_ENABLE_REPLIES") ?? "true").toLowerCase() === "true"
6106
6138
  ),
6107
- TWITTER_ENABLE_ACTIONS: String((config.TWITTER_ENABLE_ACTIONS ?? getSetting(runtime, "TWITTER_ENABLE_ACTIONS") ?? "false").toLowerCase() === "true"),
6108
- TWITTER_POST_INTERVAL: String(safeParseInt(config.TWITTER_POST_INTERVAL ?? getSetting(runtime, "TWITTER_POST_INTERVAL"), 120)),
6109
- TWITTER_ENGAGEMENT_INTERVAL: String(safeParseInt(config.TWITTER_ENGAGEMENT_INTERVAL ?? getSetting(runtime, "TWITTER_ENGAGEMENT_INTERVAL"), 30)),
6110
- TWITTER_MAX_ENGAGEMENTS_PER_RUN: String(safeParseInt(config.TWITTER_MAX_ENGAGEMENTS_PER_RUN ?? getSetting(runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN"), 10)),
6111
- TWITTER_MAX_TWEET_LENGTH: String(safeParseInt(config.TWITTER_MAX_TWEET_LENGTH ?? getSetting(runtime, "TWITTER_MAX_TWEET_LENGTH"), 280)),
6112
- TWITTER_RETRY_LIMIT: String(safeParseInt(config.TWITTER_RETRY_LIMIT ?? getSetting(runtime, "TWITTER_RETRY_LIMIT"), 5))
6139
+ TWITTER_ENABLE_ACTIONS: String(
6140
+ (config.TWITTER_ENABLE_ACTIONS ?? getSetting(runtime, "TWITTER_ENABLE_ACTIONS") ?? "false").toLowerCase() === "true"
6141
+ ),
6142
+ TWITTER_POST_INTERVAL: String(
6143
+ safeParseInt(
6144
+ config.TWITTER_POST_INTERVAL ?? getSetting(runtime, "TWITTER_POST_INTERVAL"),
6145
+ 120
6146
+ )
6147
+ ),
6148
+ TWITTER_ENGAGEMENT_INTERVAL: String(
6149
+ safeParseInt(
6150
+ config.TWITTER_ENGAGEMENT_INTERVAL ?? getSetting(runtime, "TWITTER_ENGAGEMENT_INTERVAL"),
6151
+ 30
6152
+ )
6153
+ ),
6154
+ TWITTER_MAX_ENGAGEMENTS_PER_RUN: String(
6155
+ safeParseInt(
6156
+ config.TWITTER_MAX_ENGAGEMENTS_PER_RUN ?? getSetting(runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN"),
6157
+ 10
6158
+ )
6159
+ ),
6160
+ TWITTER_MAX_TWEET_LENGTH: String(
6161
+ safeParseInt(
6162
+ config.TWITTER_MAX_TWEET_LENGTH ?? getSetting(runtime, "TWITTER_MAX_TWEET_LENGTH"),
6163
+ 280
6164
+ )
6165
+ ),
6166
+ TWITTER_RETRY_LIMIT: String(
6167
+ safeParseInt(
6168
+ config.TWITTER_RETRY_LIMIT ?? getSetting(runtime, "TWITTER_RETRY_LIMIT"),
6169
+ 5
6170
+ )
6171
+ )
6113
6172
  };
6114
6173
  if (!validatedConfig.TWITTER_API_KEY || !validatedConfig.TWITTER_API_SECRET_KEY || !validatedConfig.TWITTER_ACCESS_TOKEN || !validatedConfig.TWITTER_ACCESS_TOKEN_SECRET) {
6115
6174
  throw new Error(
@@ -6161,7 +6220,9 @@ var TwitterInteractionClient = class {
6161
6220
  this.state?.TWITTER_ENGAGEMENT_INTERVAL || getSetting(this.runtime, "TWITTER_ENGAGEMENT_INTERVAL") || process.env.TWITTER_ENGAGEMENT_INTERVAL || "30"
6162
6221
  );
6163
6222
  const interactionInterval = engagementIntervalMinutes * 60 * 1e3;
6164
- logger3.info(`Twitter interaction client will check every ${engagementIntervalMinutes} minutes`);
6223
+ logger3.info(
6224
+ `Twitter interaction client will check every ${engagementIntervalMinutes} minutes`
6225
+ );
6165
6226
  this.handleTwitterInteractions();
6166
6227
  if (this.isRunning) {
6167
6228
  setTimeout(handleTwitterInteractionsLoop, interactionInterval);
@@ -6230,7 +6291,9 @@ var TwitterInteractionClient = class {
6230
6291
  if (targetUsers.length === 0 && !targetUsersConfig.includes("*")) {
6231
6292
  return;
6232
6293
  }
6233
- logger3.info(`Checking posts from target users: ${targetUsers.join(", ") || "everyone (*)"}`);
6294
+ logger3.info(
6295
+ `Checking posts from target users: ${targetUsers.join(", ") || "everyone (*)"}`
6296
+ );
6234
6297
  for (const targetUser of targetUsers) {
6235
6298
  try {
6236
6299
  const normalizedUsername = targetUser.replace(/^@/, "");
@@ -6242,8 +6305,13 @@ var TwitterInteractionClient = class {
6242
6305
  1 /* Latest */
6243
6306
  );
6244
6307
  if (searchResult.tweets.length > 0) {
6245
- logger3.info(`Found ${searchResult.tweets.length} posts from @${normalizedUsername}`);
6246
- await this.processTargetUserTweets(searchResult.tweets, normalizedUsername);
6308
+ logger3.info(
6309
+ `Found ${searchResult.tweets.length} posts from @${normalizedUsername}`
6310
+ );
6311
+ await this.processTargetUserTweets(
6312
+ searchResult.tweets,
6313
+ normalizedUsername
6314
+ );
6247
6315
  }
6248
6316
  } catch (error) {
6249
6317
  logger3.error(`Error searching posts from @${targetUser}:`, error);
@@ -6281,7 +6349,9 @@ var TwitterInteractionClient = class {
6281
6349
  }
6282
6350
  const shouldEngage = await this.shouldEngageWithTweet(tweet);
6283
6351
  if (shouldEngage) {
6284
- logger3.info(`Engaging with tweet from @${username}: ${tweet.text.substring(0, 50)}...`);
6352
+ logger3.info(
6353
+ `Engaging with tweet from @${username}: ${tweet.text.substring(0, 50)}...`
6354
+ );
6285
6355
  await this.ensureTweetContext(tweet);
6286
6356
  const engaged = await this.engageWithTweet(tweet);
6287
6357
  if (engaged) {
@@ -6305,7 +6375,9 @@ var TwitterInteractionClient = class {
6305
6375
  return tweetAge < 12 * 60 * 60 * 1e3;
6306
6376
  });
6307
6377
  if (relevantTweets.length > 0) {
6308
- logger3.info(`Found ${relevantTweets.length} relevant tweets from timeline`);
6378
+ logger3.info(
6379
+ `Found ${relevantTweets.length} relevant tweets from timeline`
6380
+ );
6309
6381
  await this.processTargetUserTweets(relevantTweets, "timeline");
6310
6382
  }
6311
6383
  } catch (error) {
@@ -6476,8 +6548,13 @@ Response (YES/NO):`;
6476
6548
  const maxInteractionsPerRun = parseInt(
6477
6549
  getSetting(this.runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN") || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
6478
6550
  );
6479
- const tweetsToProcess = uniqueTweetCandidates.slice(0, maxInteractionsPerRun);
6480
- logger3.info(`Processing ${tweetsToProcess.length} of ${uniqueTweetCandidates.length} mention tweets (max: ${maxInteractionsPerRun})`);
6551
+ const tweetsToProcess = uniqueTweetCandidates.slice(
6552
+ 0,
6553
+ maxInteractionsPerRun
6554
+ );
6555
+ logger3.info(
6556
+ `Processing ${tweetsToProcess.length} of ${uniqueTweetCandidates.length} mention tweets (max: ${maxInteractionsPerRun})`
6557
+ );
6481
6558
  for (const tweet of tweetsToProcess) {
6482
6559
  if (!this.client.lastCheckedTweetId || BigInt(tweet.id) > this.client.lastCheckedTweetId) {
6483
6560
  const tweetId = createUniqueUuid2(this.runtime, tweet.id);
@@ -6819,7 +6896,8 @@ Response (YES/NO):`;
6819
6896
  import {
6820
6897
  ChannelType as ChannelType2,
6821
6898
  createUniqueUuid as createUniqueUuid3,
6822
- logger as logger4
6899
+ logger as logger4,
6900
+ ModelType as ModelType2
6823
6901
  } from "@elizaos/core";
6824
6902
  var TwitterPostClient = class {
6825
6903
  /**
@@ -6871,11 +6949,11 @@ var TwitterPostClient = class {
6871
6949
  }
6872
6950
  };
6873
6951
  await new Promise((resolve) => setTimeout(resolve, 1e3));
6874
- const postImmediately = parseInt(
6875
- this.state?.TWITTER_POST_INTERVAL || getSetting(this.runtime, "TWITTER_POST_INTERVAL") || process.env.TWITTER_POST_INTERVAL || "120"
6876
- ) === 0;
6877
- if (postImmediately) {
6878
- logger4.info("TWITTER_POST_IMMEDIATELY is true, generating initial tweet now");
6952
+ const postImmediately = this.state?.TWITTER_POST_IMMEDIATELY || getSetting(this.runtime, "TWITTER_POST_IMMEDIATELY") || process.env.TWITTER_POST_IMMEDIATELY;
6953
+ if (postImmediately === "true" || postImmediately === true) {
6954
+ logger4.info(
6955
+ "TWITTER_POST_IMMEDIATELY is true, generating initial tweet now"
6956
+ );
6879
6957
  await this.generateNewTweet();
6880
6958
  }
6881
6959
  generateNewTweetLoop();
@@ -6892,70 +6970,85 @@ var TwitterPostClient = class {
6892
6970
  logger4.error("Cannot generate tweet: Twitter profile not available");
6893
6971
  return;
6894
6972
  }
6895
- logger4.info(`Generating tweet for user: ${this.client.profile?.username} (${userId})`);
6973
+ logger4.info(
6974
+ `Generating tweet for user: ${this.client.profile?.username} (${userId})`
6975
+ );
6896
6976
  const worldId = createUniqueUuid3(this.runtime, userId);
6897
6977
  const roomId = createUniqueUuid3(this.runtime, `${userId}-home`);
6898
- const callback = async (content) => {
6899
- logger4.info("Tweet generation callback triggered");
6900
- try {
6901
- if (this.isDryRun) {
6902
- logger4.info(`[DRY RUN] Would post tweet: ${content.text}`);
6903
- return [];
6904
- }
6905
- if (content.text.includes("Error: Missing")) {
6906
- logger4.error("Error: Missing some context", content);
6907
- return [];
6908
- }
6909
- logger4.info(`Posting tweet: ${content.text}`);
6910
- const result = await this.postToTwitter(
6911
- content.text,
6912
- content.mediaData
6913
- );
6914
- if (result === null) {
6915
- logger4.info("Skipped posting duplicate tweet");
6916
- return [];
6917
- }
6918
- const tweetId = result.id;
6919
- logger4.info(`Tweet posted successfully! ID: ${tweetId}`);
6920
- if (result) {
6921
- const postedTweetId = createUniqueUuid3(this.runtime, tweetId);
6922
- const postedMemory = {
6923
- id: postedTweetId,
6924
- entityId: this.runtime.agentId,
6925
- agentId: this.runtime.agentId,
6926
- roomId,
6927
- content: {
6928
- ...content,
6929
- source: "twitter",
6930
- channelType: ChannelType2.FEED,
6931
- type: "post",
6932
- metadata: {
6933
- tweetId,
6934
- postedAt: Date.now()
6935
- }
6936
- },
6937
- createdAt: Date.now()
6938
- };
6939
- await this.runtime.createMemory(postedMemory, "messages");
6940
- return [postedMemory];
6941
- }
6942
- return [];
6943
- } catch (error) {
6944
- logger4.error("Error in tweet generation callback:", error);
6945
- return [];
6946
- }
6947
- };
6948
- this.runtime.emitEvent(
6949
- "TWITTER_POST_GENERATED" /* POST_GENERATED */,
6978
+ const state = await this.runtime.composeState({
6979
+ agentId: this.runtime.agentId,
6980
+ entityId: this.runtime.agentId,
6981
+ roomId,
6982
+ content: { text: "", type: "post" },
6983
+ createdAt: Date.now()
6984
+ });
6985
+ const tweetPrompt = `You are ${this.runtime.character.name}.
6986
+ ${this.runtime.character.bio}
6987
+
6988
+ Generate a tweet that:
6989
+ - Reflects your personality and interests
6990
+ - Is engaging and authentic
6991
+ - Is between 50-280 characters
6992
+ - Does NOT include hashtags unless they're essential to the message
6993
+ - Does NOT include @mentions unless replying to someone
6994
+
6995
+ Your topics of interest: ${this.runtime.character.topics?.join(", ") || "general topics"}
6996
+
6997
+ Recent context:
6998
+ ${state.recentMemories?.slice(0, 5).map((m) => m.content.text).join("\n") || "No recent context"}
6999
+
7000
+ Generate a single tweet:`;
7001
+ const generatedContent = await this.runtime.useModel(
7002
+ ModelType2.TEXT_SMALL,
6950
7003
  {
6951
- callback,
6952
- entityId: this.runtime.agentId,
6953
- userId,
6954
- roomId,
6955
- source: "twitter"
7004
+ prompt: tweetPrompt,
7005
+ temperature: 0.8,
7006
+ maxTokens: 100
6956
7007
  }
6957
7008
  );
6958
- logger4.info("POST_GENERATED event emitted successfully");
7009
+ const tweetText = generatedContent.trim();
7010
+ if (!tweetText || tweetText.length === 0) {
7011
+ logger4.error("Generated empty tweet content");
7012
+ return;
7013
+ }
7014
+ if (tweetText.includes("Error: Missing")) {
7015
+ logger4.error("Error in generated content:", tweetText);
7016
+ return;
7017
+ }
7018
+ logger4.info(`Generated tweet: ${tweetText}`);
7019
+ if (this.isDryRun) {
7020
+ logger4.info(`[DRY RUN] Would post tweet: ${tweetText}`);
7021
+ return;
7022
+ }
7023
+ const result = await this.postToTwitter(tweetText, []);
7024
+ if (result === null) {
7025
+ logger4.info("Skipped posting duplicate tweet");
7026
+ return;
7027
+ }
7028
+ const tweetId = result.id;
7029
+ logger4.info(`Tweet posted successfully! ID: ${tweetId}`);
7030
+ if (result) {
7031
+ const postedTweetId = createUniqueUuid3(this.runtime, tweetId);
7032
+ const postedMemory = {
7033
+ id: postedTweetId,
7034
+ entityId: this.runtime.agentId,
7035
+ agentId: this.runtime.agentId,
7036
+ roomId,
7037
+ content: {
7038
+ text: tweetText,
7039
+ source: "twitter",
7040
+ channelType: ChannelType2.FEED,
7041
+ type: "post",
7042
+ metadata: {
7043
+ tweetId,
7044
+ postedAt: Date.now()
7045
+ }
7046
+ },
7047
+ createdAt: Date.now()
7048
+ };
7049
+ await this.runtime.createMemory(postedMemory, "messages");
7050
+ logger4.info("Tweet posted and saved to memory successfully");
7051
+ }
6959
7052
  } catch (error) {
6960
7053
  logger4.error("Error generating tweet:", error);
6961
7054
  }
@@ -7014,7 +7107,7 @@ import {
7014
7107
  ChannelType as ChannelType3,
7015
7108
  composePromptFromState,
7016
7109
  createUniqueUuid as createUniqueUuid4,
7017
- ModelType as ModelType2,
7110
+ ModelType as ModelType3,
7018
7111
  parseKeyValueXml
7019
7112
  } from "@elizaos/core";
7020
7113
  import { logger as logger5 } from "@elizaos/core";
@@ -7026,20 +7119,23 @@ var twitterActionTemplate = `
7026
7119
  {{postDirections}}
7027
7120
 
7028
7121
  Guidelines:
7029
- - ONLY engage with content that DIRECTLY relates to character's core interests
7030
- - Direct mentions are priority IF they are on-topic
7031
- - Skip ALL content that is:
7032
- - Off-topic or tangentially related
7033
- - From high-profile accounts unless explicitly relevant
7034
- - Generic/viral content without specific relevance
7035
- - Political/controversial unless central to character
7036
- - Promotional/marketing unless directly relevant
7122
+ - Engage with content that relates to character's interests and expertise
7123
+ - Direct mentions should be prioritized when relevant
7124
+ - Consider engaging with:
7125
+ - Content directly related to your topics
7126
+ - Interesting discussions you can contribute to
7127
+ - Questions you can help answer
7128
+ - Content from users you've interacted with before
7129
+ - Skip content that is:
7130
+ - Completely off-topic or spam
7131
+ - Inflammatory or highly controversial (unless it's your area)
7132
+ - Pure marketing/promotional with no value
7037
7133
 
7038
7134
  Actions (respond only with tags):
7039
- [LIKE] - Perfect topic match AND aligns with character (9.8/10)
7040
- [RETWEET] - Exceptional content that embodies character's expertise (9.5/10)
7041
- [QUOTE] - Can add substantial domain expertise (9.5/10)
7042
- [REPLY] - Can contribute meaningful, expert-level insight (9.5/10)
7135
+ [LIKE] - Content is relevant and interesting (7/10 or higher)
7136
+ [RETWEET] - Content is valuable and worth sharing (8/10 or higher)
7137
+ [QUOTE] - You can add meaningful commentary (7.5/10 or higher)
7138
+ [REPLY] - You can contribute helpful insights (7/10 or higher)
7043
7139
  `;
7044
7140
  var quoteTweetTemplate = `# Task: Write a quote tweet in the voice, style, and perspective of {{agentName}} @{{twitterUserName}}.
7045
7141
 
@@ -7105,7 +7201,9 @@ var TwitterTimelineClient = class {
7105
7201
  this.state?.TWITTER_ENGAGEMENT_INTERVAL || getSetting(this.runtime, "TWITTER_ENGAGEMENT_INTERVAL") || process.env.TWITTER_ENGAGEMENT_INTERVAL || "30"
7106
7202
  );
7107
7203
  const actionInterval = engagementIntervalMinutes * 60 * 1e3;
7108
- logger5.info(`Timeline client will check every ${engagementIntervalMinutes} minutes`);
7204
+ logger5.info(
7205
+ `Timeline client will check every ${engagementIntervalMinutes} minutes`
7206
+ );
7109
7207
  this.handleTimeline();
7110
7208
  if (this.isRunning) {
7111
7209
  setTimeout(handleTwitterTimelineLoop, actionInterval);
@@ -7173,7 +7271,7 @@ ${tweet.text}
7173
7271
 
7174
7272
  Choose any combination of [LIKE], [RETWEET], [QUOTE], and [REPLY] that are appropriate. Each action must be on its own line. Your response must only include the chosen actions.`;
7175
7273
  const actionResponse = await this.runtime.useModel(
7176
- ModelType2.TEXT_SMALL,
7274
+ ModelType3.TEXT_SMALL,
7177
7275
  {
7178
7276
  prompt: actionRespondPrompt
7179
7277
  }
@@ -7227,7 +7325,12 @@ ${actionSummary.join("\n")}`);
7227
7325
  }
7228
7326
  async processTimelineActions(tweetDecisions) {
7229
7327
  const results = [];
7230
- for (const { tweet, actionResponse, tweetState, roomId } of tweetDecisions) {
7328
+ for (const {
7329
+ tweet,
7330
+ actionResponse,
7331
+ tweetState,
7332
+ roomId
7333
+ } of tweetDecisions) {
7231
7334
  const tweetId = this.createTweetId(this.runtime, tweet);
7232
7335
  const executedActions = [];
7233
7336
  await this.runtime.createMemory(
@@ -7345,13 +7448,15 @@ ${actionSummary.join("\n")}`);
7345
7448
  }) + `
7346
7449
  You are responding to this tweet:
7347
7450
  ${tweet.text}`;
7348
- const quoteResponse = await this.runtime.useModel(ModelType2.TEXT_SMALL, {
7451
+ const quoteResponse = await this.runtime.useModel(ModelType3.TEXT_SMALL, {
7349
7452
  prompt: quotePrompt
7350
7453
  });
7351
7454
  const responseObject = parseKeyValueXml(quoteResponse);
7352
7455
  if (responseObject.post) {
7353
7456
  if (this.isDryRun) {
7354
- logger5.log(`[DRY RUN] Would have quoted tweet ${tweet.id} with: ${responseObject.post}`);
7457
+ logger5.log(
7458
+ `[DRY RUN] Would have quoted tweet ${tweet.id} with: ${responseObject.post}`
7459
+ );
7355
7460
  return;
7356
7461
  }
7357
7462
  const result = await this.client.requestQueue.add(
@@ -7396,13 +7501,15 @@ ${tweet.text}`;
7396
7501
  }) + `
7397
7502
  You are replying to this tweet:
7398
7503
  ${tweet.text}`;
7399
- const replyResponse = await this.runtime.useModel(ModelType2.TEXT_SMALL, {
7504
+ const replyResponse = await this.runtime.useModel(ModelType3.TEXT_SMALL, {
7400
7505
  prompt: replyPrompt
7401
7506
  });
7402
7507
  const responseObject = parseKeyValueXml(replyResponse);
7403
7508
  if (responseObject.post) {
7404
7509
  if (this.isDryRun) {
7405
- logger5.log(`[DRY RUN] Would have replied to tweet ${tweet.id} with: ${responseObject.post}`);
7510
+ logger5.log(
7511
+ `[DRY RUN] Would have replied to tweet ${tweet.id} with: ${responseObject.post}`
7512
+ );
7406
7513
  return;
7407
7514
  }
7408
7515
  const result = await sendTweet(
@@ -7438,7 +7545,7 @@ ${tweet.text}`;
7438
7545
  import {
7439
7546
  createUniqueUuid as createUniqueUuid5,
7440
7547
  logger as logger6,
7441
- ModelType as ModelType3
7548
+ ModelType as ModelType4
7442
7549
  } from "@elizaos/core";
7443
7550
  var TwitterDiscoveryClient = class {
7444
7551
  constructor(client, runtime, state) {
@@ -7489,7 +7596,9 @@ var TwitterDiscoveryClient = class {
7489
7596
  topics = this.extractTopicsFromBio(character.bio);
7490
7597
  }
7491
7598
  } else {
7492
- logger6.warn("Character not available in runtime, using default topics for discovery");
7599
+ logger6.warn(
7600
+ "Character not available in runtime, using default topics for discovery"
7601
+ );
7493
7602
  }
7494
7603
  return {
7495
7604
  topics,
@@ -7500,11 +7609,17 @@ var TwitterDiscoveryClient = class {
7500
7609
  getSetting(this.runtime, "TWITTER_MAX_FOLLOWS_PER_CYCLE") || process.env.TWITTER_MAX_FOLLOWS_PER_CYCLE || "5"
7501
7610
  ),
7502
7611
  maxEngagementsPerCycle: parseInt(
7503
- getSetting(this.runtime, "TWITTER_MAX_ENGAGEMENTS_PER_RUN") || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
7612
+ getSetting(
7613
+ this.runtime,
7614
+ "TWITTER_MAX_ENGAGEMENTS_PER_RUN"
7615
+ ) || process.env.TWITTER_MAX_ENGAGEMENTS_PER_RUN || "10"
7504
7616
  ),
7505
- likeThreshold: 0.6,
7506
- replyThreshold: 0.8,
7507
- quoteThreshold: 0.85
7617
+ likeThreshold: 0.3,
7618
+ // Lowered from 0.6
7619
+ replyThreshold: 0.5,
7620
+ // Lowered from 0.8
7621
+ quoteThreshold: 0.7
7622
+ // Lowered from 0.85
7508
7623
  };
7509
7624
  }
7510
7625
  extractTopicsFromBio(bio) {
@@ -7512,7 +7627,16 @@ var TwitterDiscoveryClient = class {
7512
7627
  return [];
7513
7628
  }
7514
7629
  const bioText = Array.isArray(bio) ? bio.join(" ") : bio;
7515
- const words = bioText.toLowerCase().split(/\s+/).filter((word) => word.length > 4).filter((word) => !["about", "helping", "working", "people", "making", "building"].includes(word));
7630
+ const words = bioText.toLowerCase().split(/\s+/).filter((word) => word.length > 4).filter(
7631
+ (word) => ![
7632
+ "about",
7633
+ "helping",
7634
+ "working",
7635
+ "people",
7636
+ "making",
7637
+ "building"
7638
+ ].includes(word)
7639
+ );
7516
7640
  return [...new Set(words)].slice(0, 5);
7517
7641
  }
7518
7642
  async start() {
@@ -7533,7 +7657,9 @@ var TwitterDiscoveryClient = class {
7533
7657
  );
7534
7658
  const variance = Math.random() * 20 - 10;
7535
7659
  const nextInterval = (baseInterval + variance) * 60 * 1e3;
7536
- logger6.info(`Next discovery cycle in ${(baseInterval + variance).toFixed(1)} minutes`);
7660
+ logger6.info(
7661
+ `Next discovery cycle in ${(baseInterval + variance).toFixed(1)} minutes`
7662
+ );
7537
7663
  if (this.isRunning) {
7538
7664
  setTimeout(discoveryLoop, nextInterval);
7539
7665
  }
@@ -7548,7 +7674,9 @@ var TwitterDiscoveryClient = class {
7548
7674
  logger6.info("Starting Twitter discovery cycle...");
7549
7675
  const discoveries = await this.discoverContent();
7550
7676
  const { tweets, accounts } = discoveries;
7551
- logger6.info(`Discovered ${tweets.length} tweets and ${accounts.length} accounts`);
7677
+ logger6.info(
7678
+ `Discovered ${tweets.length} tweets and ${accounts.length} accounts`
7679
+ );
7552
7680
  const followedCount = await this.processAccounts(accounts);
7553
7681
  const engagementCount = await this.processTweets(tweets);
7554
7682
  logger6.info(
@@ -7561,9 +7689,7 @@ var TwitterDiscoveryClient = class {
7561
7689
  try {
7562
7690
  const topicContent = await this.discoverFromTopics();
7563
7691
  allTweets.push(...topicContent.tweets);
7564
- topicContent.accounts.forEach(
7565
- (acc) => allAccounts.set(acc.user.id, acc)
7566
- );
7692
+ topicContent.accounts.forEach((acc) => allAccounts.set(acc.user.id, acc));
7567
7693
  } catch (error) {
7568
7694
  logger6.error("Failed to discover from topics:", error);
7569
7695
  }
@@ -7586,7 +7712,9 @@ var TwitterDiscoveryClient = class {
7586
7712
  logger6.error("Failed to discover from popular accounts:", error);
7587
7713
  }
7588
7714
  const sortedTweets = allTweets.sort((a, b) => b.relevanceScore - a.relevanceScore).slice(0, 50);
7589
- const sortedAccounts = Array.from(allAccounts.values()).sort((a, b) => b.qualityScore * b.relevanceScore - a.qualityScore * a.relevanceScore).slice(0, 20);
7715
+ const sortedAccounts = Array.from(allAccounts.values()).sort(
7716
+ (a, b) => b.qualityScore * b.relevanceScore - a.qualityScore * a.relevanceScore
7717
+ ).slice(0, 20);
7590
7718
  return { tweets: sortedTweets, accounts: sortedAccounts };
7591
7719
  }
7592
7720
  async discoverFromTopics() {
@@ -7652,17 +7780,17 @@ var TwitterDiscoveryClient = class {
7652
7780
  );
7653
7781
  for (const tweet of searchResults.tweets) {
7654
7782
  const engagementScore = (tweet.likes || 0) + (tweet.retweets || 0) * 2;
7655
- if (engagementScore < 50) continue;
7783
+ if (engagementScore < 10) continue;
7656
7784
  const scored = this.scoreTweet(tweet, "thread");
7657
7785
  tweets.push(scored);
7658
7786
  const account = this.scoreAccount({
7659
7787
  id: tweet.userId,
7660
7788
  username: tweet.username,
7661
7789
  name: tweet.name || tweet.username,
7662
- followersCount: 5e3
7663
- // Estimate for viral content creators
7790
+ followersCount: 1e3
7791
+ // Reasonable estimate for engaged users
7664
7792
  });
7665
- if (account.qualityScore > 0.6) {
7793
+ if (account.qualityScore > 0.5) {
7666
7794
  accounts.set(tweet.userId, account);
7667
7795
  }
7668
7796
  }
@@ -7687,7 +7815,7 @@ var TwitterDiscoveryClient = class {
7687
7815
  );
7688
7816
  for (const tweet of results.tweets) {
7689
7817
  const engagement = (tweet.likes || 0) + (tweet.retweets || 0) * 2;
7690
- if (engagement < 20) continue;
7818
+ if (engagement < 5) continue;
7691
7819
  const scored = this.scoreTweet(tweet, "topic");
7692
7820
  tweets.push(scored);
7693
7821
  const estimatedFollowers = Math.max(
@@ -7706,7 +7834,10 @@ var TwitterDiscoveryClient = class {
7706
7834
  }
7707
7835
  }
7708
7836
  } catch (error) {
7709
- logger6.error(`Failed to discover popular accounts for ${topic}:`, error);
7837
+ logger6.error(
7838
+ `Failed to discover popular accounts for ${topic}:`,
7839
+ error
7840
+ );
7710
7841
  }
7711
7842
  }
7712
7843
  return { tweets, accounts: Array.from(accounts.values()) };
@@ -7716,12 +7847,15 @@ var TwitterDiscoveryClient = class {
7716
7847
  scoreTweet(tweet, source) {
7717
7848
  let relevanceScore = 0;
7718
7849
  const sourceScores = {
7719
- topic: 0.5,
7720
- thread: 0.4
7850
+ topic: 0.4,
7851
+ thread: 0.35
7721
7852
  };
7722
7853
  relevanceScore += sourceScores[source];
7723
7854
  const engagementScore = Math.min(
7724
- (tweet.likes || 0) / 1e3 + (tweet.retweets || 0) / 500 + (tweet.replies || 0) / 100,
7855
+ (tweet.likes || 0) / 100 + // 100 likes = 0.1 points (was 1000)
7856
+ (tweet.retweets || 0) / 50 + // 50 retweets = 0.1 points (was 500)
7857
+ (tweet.replies || 0) / 20,
7858
+ // 20 replies = 0.1 points (was 100)
7725
7859
  0.3
7726
7860
  );
7727
7861
  relevanceScore += engagementScore;
@@ -7729,7 +7863,7 @@ var TwitterDiscoveryClient = class {
7729
7863
  const topicMatches = this.config.topics.filter(
7730
7864
  (topic) => textLower.includes(topic.toLowerCase())
7731
7865
  ).length;
7732
- relevanceScore += Math.min(topicMatches * 0.1, 0.3);
7866
+ relevanceScore += Math.min(topicMatches * 0.15, 0.3);
7733
7867
  relevanceScore = Math.min(relevanceScore, 1);
7734
7868
  let engagementType = "skip";
7735
7869
  if (relevanceScore >= this.config.quoteThreshold) {
@@ -7783,7 +7917,10 @@ var TwitterDiscoveryClient = class {
7783
7917
  followedCount++;
7784
7918
  await this.delay(2e3 + Math.random() * 3e3);
7785
7919
  } catch (error) {
7786
- logger6.error(`Failed to follow @${scoredAccount.user.username}:`, error);
7920
+ logger6.error(
7921
+ `Failed to follow @${scoredAccount.user.username}:`,
7922
+ error
7923
+ );
7787
7924
  }
7788
7925
  }
7789
7926
  return followedCount;
@@ -7794,51 +7931,76 @@ var TwitterDiscoveryClient = class {
7794
7931
  if (engagementCount >= this.config.maxEngagementsPerCycle) break;
7795
7932
  if (scoredTweet.engagementType === "skip") continue;
7796
7933
  try {
7797
- const tweetMemoryId = createUniqueUuid5(this.runtime, scoredTweet.tweet.id);
7934
+ const tweetMemoryId = createUniqueUuid5(
7935
+ this.runtime,
7936
+ scoredTweet.tweet.id
7937
+ );
7798
7938
  const existingMemory = await this.runtime.getMemoryById(tweetMemoryId);
7799
7939
  if (existingMemory) {
7800
- logger6.debug(`Already engaged with tweet ${scoredTweet.tweet.id}, skipping`);
7940
+ logger6.debug(
7941
+ `Already engaged with tweet ${scoredTweet.tweet.id}, skipping`
7942
+ );
7801
7943
  continue;
7802
7944
  }
7803
7945
  switch (scoredTweet.engagementType) {
7804
7946
  case "like":
7805
7947
  if (this.isDryRun) {
7806
- logger6.info(`[DRY RUN] Would like tweet: ${scoredTweet.tweet.id} (score: ${scoredTweet.relevanceScore.toFixed(2)})`);
7948
+ logger6.info(
7949
+ `[DRY RUN] Would like tweet: ${scoredTweet.tweet.id} (score: ${scoredTweet.relevanceScore.toFixed(2)})`
7950
+ );
7807
7951
  } else {
7808
7952
  await this.twitterClient.likeTweet(scoredTweet.tweet.id);
7809
- logger6.info(`Liked tweet: ${scoredTweet.tweet.id} (score: ${scoredTweet.relevanceScore.toFixed(2)})`);
7953
+ logger6.info(
7954
+ `Liked tweet: ${scoredTweet.tweet.id} (score: ${scoredTweet.relevanceScore.toFixed(2)})`
7955
+ );
7810
7956
  }
7811
7957
  break;
7812
7958
  case "reply":
7813
7959
  const replyText = await this.generateReply(scoredTweet.tweet);
7814
7960
  if (this.isDryRun) {
7815
- logger6.info(`[DRY RUN] Would reply to tweet ${scoredTweet.tweet.id} with: "${replyText}"`);
7961
+ logger6.info(
7962
+ `[DRY RUN] Would reply to tweet ${scoredTweet.tweet.id} with: "${replyText}"`
7963
+ );
7816
7964
  } else {
7817
- await this.twitterClient.sendTweet(replyText, scoredTweet.tweet.id);
7965
+ await this.twitterClient.sendTweet(
7966
+ replyText,
7967
+ scoredTweet.tweet.id
7968
+ );
7818
7969
  logger6.info(`Replied to tweet: ${scoredTweet.tweet.id}`);
7819
7970
  }
7820
7971
  break;
7821
7972
  case "quote":
7822
7973
  const quoteText = await this.generateQuote(scoredTweet.tweet);
7823
7974
  if (this.isDryRun) {
7824
- logger6.info(`[DRY RUN] Would quote tweet ${scoredTweet.tweet.id} with: "${quoteText}"`);
7975
+ logger6.info(
7976
+ `[DRY RUN] Would quote tweet ${scoredTweet.tweet.id} with: "${quoteText}"`
7977
+ );
7825
7978
  } else {
7826
- await this.twitterClient.sendQuoteTweet(quoteText, scoredTweet.tweet.id);
7979
+ await this.twitterClient.sendQuoteTweet(
7980
+ quoteText,
7981
+ scoredTweet.tweet.id
7982
+ );
7827
7983
  logger6.info(`Quoted tweet: ${scoredTweet.tweet.id}`);
7828
7984
  }
7829
7985
  break;
7830
7986
  }
7831
- await this.saveEngagementMemory(scoredTweet.tweet, scoredTweet.engagementType);
7987
+ await this.saveEngagementMemory(
7988
+ scoredTweet.tweet,
7989
+ scoredTweet.engagementType
7990
+ );
7832
7991
  engagementCount++;
7833
7992
  await this.delay(3e3 + Math.random() * 5e3);
7834
7993
  } catch (error) {
7835
- logger6.error(`Failed to engage with tweet ${scoredTweet.tweet.id}:`, error);
7994
+ logger6.error(
7995
+ `Failed to engage with tweet ${scoredTweet.tweet.id}:`,
7996
+ error
7997
+ );
7836
7998
  }
7837
7999
  }
7838
8000
  return engagementCount;
7839
8001
  }
7840
8002
  async checkIfFollowing(userId) {
7841
- const embedding = await this.runtime.useModel(ModelType3.TEXT_EMBEDDING, {
8003
+ const embedding = await this.runtime.useModel(ModelType4.TEXT_EMBEDDING, {
7842
8004
  text: `followed twitter user ${userId}`
7843
8005
  });
7844
8006
  const followMemories = await this.runtime.searchMemories({
@@ -7874,7 +8036,7 @@ Keep the reply:
7874
8036
  - Respectful and constructive
7875
8037
 
7876
8038
  Reply:`;
7877
- const response = await this.runtime.useModel(ModelType3.TEXT_SMALL, {
8039
+ const response = await this.runtime.useModel(ModelType4.TEXT_SMALL, {
7878
8040
  prompt,
7879
8041
  max_tokens: 100,
7880
8042
  temperature: 0.8
@@ -7906,7 +8068,7 @@ Create a quote tweet that:
7906
8068
  - Encourages further discussion
7907
8069
 
7908
8070
  Quote tweet:`;
7909
- const response = await this.runtime.useModel(ModelType3.TEXT_SMALL, {
8071
+ const response = await this.runtime.useModel(ModelType4.TEXT_SMALL, {
7910
8072
  prompt,
7911
8073
  max_tokens: 100,
7912
8074
  temperature: 0.8
@@ -7914,37 +8076,43 @@ Quote tweet:`;
7914
8076
  return response.trim();
7915
8077
  }
7916
8078
  async saveEngagementMemory(tweet, engagementType) {
7917
- const memoryId = await this.runtime.createMemory({
7918
- id: createUniqueUuid5(this.runtime, tweet.id),
7919
- entityId: createUniqueUuid5(this.runtime, tweet.userId),
7920
- content: {
7921
- text: `${engagementType} tweet from @${tweet.username}: ${tweet.text}`,
7922
- metadata: {
7923
- tweetId: tweet.id,
7924
- engagementType,
7925
- source: "discovery",
7926
- isDryRun: this.isDryRun
7927
- }
8079
+ const memoryId = await this.runtime.createMemory(
8080
+ {
8081
+ id: createUniqueUuid5(this.runtime, tweet.id),
8082
+ entityId: createUniqueUuid5(this.runtime, tweet.userId),
8083
+ content: {
8084
+ text: `${engagementType} tweet from @${tweet.username}: ${tweet.text}`,
8085
+ metadata: {
8086
+ tweetId: tweet.id,
8087
+ engagementType,
8088
+ source: "discovery",
8089
+ isDryRun: this.isDryRun
8090
+ }
8091
+ },
8092
+ roomId: createUniqueUuid5(this.runtime, tweet.conversationId)
7928
8093
  },
7929
- roomId: createUniqueUuid5(this.runtime, tweet.conversationId)
7930
- }, "messages");
8094
+ "messages"
8095
+ );
7931
8096
  }
7932
8097
  async saveFollowMemory(user) {
7933
- const memoryId = await this.runtime.createMemory({
7934
- entityId: createUniqueUuid5(this.runtime, user.id),
7935
- content: {
7936
- text: `followed twitter user ${user.id} @${user.username}`,
7937
- metadata: {
7938
- userId: user.id,
7939
- username: user.username,
7940
- name: user.name,
7941
- followersCount: user.followersCount,
7942
- source: "discovery",
7943
- isDryRun: this.isDryRun
7944
- }
8098
+ const memoryId = await this.runtime.createMemory(
8099
+ {
8100
+ entityId: createUniqueUuid5(this.runtime, user.id),
8101
+ content: {
8102
+ text: `followed twitter user ${user.id} @${user.username}`,
8103
+ metadata: {
8104
+ userId: user.id,
8105
+ username: user.username,
8106
+ name: user.name,
8107
+ followersCount: user.followersCount,
8108
+ source: "discovery",
8109
+ isDryRun: this.isDryRun
8110
+ }
8111
+ },
8112
+ roomId: createUniqueUuid5(this.runtime, `twitter-follows`)
7945
8113
  },
7946
- roomId: createUniqueUuid5(this.runtime, `twitter-follows`)
7947
- }, "messages");
8114
+ "messages"
8115
+ );
7948
8116
  }
7949
8117
  delay(ms) {
7950
8118
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -8008,7 +8176,9 @@ var RequestQueue = class {
8008
8176
  await this.exponentialBackoff(retryCount);
8009
8177
  break;
8010
8178
  } else {
8011
- logger7.error(`Max retries (${this.maxRetries}) exceeded for request, skipping`);
8179
+ logger7.error(
8180
+ `Max retries (${this.maxRetries}) exceeded for request, skipping`
8181
+ );
8012
8182
  this.retryAttempts.delete(request);
8013
8183
  }
8014
8184
  }
@@ -8541,13 +8711,17 @@ var TwitterClientInstance = class {
8541
8711
  constructor(runtime, state) {
8542
8712
  this.client = new ClientBase(runtime, state);
8543
8713
  const postEnabledSetting = getSetting(runtime, "TWITTER_ENABLE_POST") ?? process.env.TWITTER_ENABLE_POST;
8544
- logger8.debug(`TWITTER_ENABLE_POST setting value: ${JSON.stringify(postEnabledSetting)}, type: ${typeof postEnabledSetting}`);
8714
+ logger8.debug(
8715
+ `TWITTER_ENABLE_POST setting value: ${JSON.stringify(postEnabledSetting)}, type: ${typeof postEnabledSetting}`
8716
+ );
8545
8717
  const postEnabled = postEnabledSetting === "true" || postEnabledSetting === true;
8546
8718
  if (postEnabled) {
8547
8719
  logger8.info("Twitter posting is ENABLED - creating post client");
8548
8720
  this.post = new TwitterPostClient(this.client, runtime, state);
8549
8721
  } else {
8550
- logger8.info("Twitter posting is DISABLED - set TWITTER_ENABLE_POST=true to enable automatic posting");
8722
+ logger8.info(
8723
+ "Twitter posting is DISABLED - set TWITTER_ENABLE_POST=true to enable automatic posting"
8724
+ );
8551
8725
  }
8552
8726
  const repliesEnabled = (getSetting(runtime, "TWITTER_ENABLE_REPLIES") ?? process.env.TWITTER_ENABLE_REPLIES) !== "false";
8553
8727
  if (repliesEnabled) {
@@ -8572,7 +8746,9 @@ var TwitterClientInstance = class {
8572
8746
  logger8.info("Twitter discovery service is ENABLED");
8573
8747
  this.discovery = new TwitterDiscoveryClient(this.client, runtime, state);
8574
8748
  } else {
8575
- logger8.info("Twitter discovery service is DISABLED - set TWITTER_ENABLE_DISCOVERY=true to enable");
8749
+ logger8.info(
8750
+ "Twitter discovery service is DISABLED - set TWITTER_ENABLE_DISCOVERY=true to enable"
8751
+ );
8576
8752
  }
8577
8753
  }
8578
8754
  };
@@ -8635,11 +8811,17 @@ var TwitterService = _TwitterService;
8635
8811
  // src/actions/postTweet.ts
8636
8812
  import {
8637
8813
  logger as logger9,
8638
- ModelType as ModelType4
8814
+ ModelType as ModelType5
8639
8815
  } from "@elizaos/core";
8640
8816
  var postTweetAction = {
8641
8817
  name: "POST_TWEET",
8642
- similes: ["TWEET", "SEND_TWEET", "TWITTER_POST", "POST_ON_TWITTER", "SHARE_ON_TWITTER"],
8818
+ similes: [
8819
+ "TWEET",
8820
+ "SEND_TWEET",
8821
+ "TWITTER_POST",
8822
+ "POST_ON_TWITTER",
8823
+ "SHARE_ON_TWITTER"
8824
+ ],
8643
8825
  validate: async (runtime, message) => {
8644
8826
  logger9.debug("Validating POST_TWEET action");
8645
8827
  const text = message.content?.text?.trim();
@@ -8661,7 +8843,9 @@ var postTweetAction = {
8661
8843
  await client.init();
8662
8844
  }
8663
8845
  if (!client.profile) {
8664
- throw new Error("Twitter client not properly initialized - no profile found");
8846
+ throw new Error(
8847
+ "Twitter client not properly initialized - no profile found"
8848
+ );
8665
8849
  }
8666
8850
  const tweetText = message.content?.text?.trim() || "";
8667
8851
  let finalTweetText = tweetText;
@@ -8682,7 +8866,7 @@ Generate a tweet that:
8682
8866
  - Is not generic or promotional
8683
8867
 
8684
8868
  Tweet:`;
8685
- const response = await runtime.useModel(ModelType4.TEXT_SMALL, {
8869
+ const response = await runtime.useModel(ModelType5.TEXT_SMALL, {
8686
8870
  prompt: tweetPrompt,
8687
8871
  max_tokens: 100,
8688
8872
  temperature: 0.8
@@ -8702,16 +8886,19 @@ Tweet:`;
8702
8886
  }
8703
8887
  const tweetUrl = `https://twitter.com/${client.profile.username}/status/${tweetId}`;
8704
8888
  logger9.info(`Successfully posted tweet: ${tweetId}`);
8705
- await runtime.createMemory({
8706
- entityId: runtime.agentId,
8707
- content: {
8708
- text: finalTweetText,
8709
- url: tweetUrl,
8710
- source: "twitter",
8711
- action: "POST_TWEET"
8889
+ await runtime.createMemory(
8890
+ {
8891
+ entityId: runtime.agentId,
8892
+ content: {
8893
+ text: finalTweetText,
8894
+ url: tweetUrl,
8895
+ source: "twitter",
8896
+ action: "POST_TWEET"
8897
+ },
8898
+ roomId: message.roomId
8712
8899
  },
8713
- roomId: message.roomId
8714
- }, "messages");
8900
+ "messages"
8901
+ );
8715
8902
  if (callback) {
8716
8903
  await callback({
8717
8904
  text: `I've posted a tweet: "${finalTweetText}"