@elizaos/plugin-twitter 1.0.0-alpha.58 → 1.0.0-alpha.59

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
@@ -1,10 +1,10 @@
1
1
  // src/index.ts
2
2
  import {
3
- ChannelType as ChannelType6,
4
- EventTypes as EventTypes3,
3
+ ChannelType as ChannelType7,
4
+ EventTypes as EventTypes4,
5
5
  Role,
6
6
  Service,
7
- createUniqueUuid as createUniqueUuid7,
7
+ createUniqueUuid as createUniqueUuid8,
8
8
  logger as logger9
9
9
  } from "@elizaos/core";
10
10
 
@@ -15,7 +15,12 @@ import {
15
15
  } from "@elizaos/core";
16
16
 
17
17
  // src/spaces.ts
18
- import { ModelTypes as ModelTypes3, logger as logger3 } from "@elizaos/core";
18
+ import {
19
+ ChannelType as ChannelType3,
20
+ ModelType as ModelType3,
21
+ createUniqueUuid as createUniqueUuid3,
22
+ logger as logger3
23
+ } from "@elizaos/core";
19
24
 
20
25
  // src/client/api.ts
21
26
  import { Headers as Headers2 } from "headers-polyfill";
@@ -576,7 +581,7 @@ async function getScreenNameByUserId(userId, auth) {
576
581
  value: legacy.screen_name
577
582
  };
578
583
  }
579
- async function getUserIdByScreenName(screenName, auth) {
584
+ async function getEntityIdByScreenName(screenName, auth) {
580
585
  const cached = idCache.get(screenName);
581
586
  if (cached != null) {
582
587
  return { success: true, value: cached };
@@ -1357,7 +1362,7 @@ async function followUser(username, auth) {
1357
1362
  if (!await auth.isLoggedIn()) {
1358
1363
  throw new Error("Must be logged in to follow users");
1359
1364
  }
1360
- const userIdResult = await getUserIdByScreenName(username, auth);
1365
+ const userIdResult = await getEntityIdByScreenName(username, auth);
1361
1366
  if (!userIdResult.success) {
1362
1367
  throw new Error(`Failed to get user ID: ${userIdResult.err.message}`);
1363
1368
  }
@@ -3031,7 +3036,7 @@ async function fetchListTweets(listId, maxTweets, cursor, auth) {
3031
3036
  }
3032
3037
  function getTweets(user, maxTweets, auth) {
3033
3038
  return getTweetTimeline(user, maxTweets, async (q, mt, c) => {
3034
- const userIdRes = await getUserIdByScreenName(q, auth);
3039
+ const userIdRes = await getEntityIdByScreenName(q, auth);
3035
3040
  if (!userIdRes.success) {
3036
3041
  throw userIdRes.err;
3037
3042
  }
@@ -3046,7 +3051,7 @@ function getTweetsByUserId(userId, maxTweets, auth) {
3046
3051
  }
3047
3052
  function getTweetsAndReplies(user, maxTweets, auth) {
3048
3053
  return getTweetTimeline(user, maxTweets, async (q, mt, c) => {
3049
- const userIdRes = await getUserIdByScreenName(q, auth);
3054
+ const userIdRes = await getEntityIdByScreenName(q, auth);
3050
3055
  if (!userIdRes.success) {
3051
3056
  throw userIdRes.err;
3052
3057
  }
@@ -3675,8 +3680,8 @@ var Client = class {
3675
3680
  * @param screenName The Twitter screen name of the profile to fetch.
3676
3681
  * @returns The ID of the corresponding account.
3677
3682
  */
3678
- async getUserIdByScreenName(screenName) {
3679
- const res = await getUserIdByScreenName(screenName, this.auth);
3683
+ async getEntityIdByScreenName(screenName) {
3684
+ const res = await getEntityIdByScreenName(screenName, this.auth);
3680
3685
  return this.handleResponse(res);
3681
3686
  }
3682
3687
  /**
@@ -6521,7 +6526,7 @@ import { spawn } from "node:child_process";
6521
6526
  import {
6522
6527
  ChannelType,
6523
6528
  EventTypes,
6524
- ModelTypes,
6529
+ ModelType,
6525
6530
  createUniqueUuid,
6526
6531
  logger
6527
6532
  } from "@elizaos/core";
@@ -6680,7 +6685,7 @@ var SttTtsPlugin2 = class {
6680
6685
  }
6681
6686
  const wavBuffer = await this.convertPcmToWavInMemory(merged, 48e3);
6682
6687
  const sttText = await this.runtime.useModel(
6683
- ModelTypes.TRANSCRIPTION,
6688
+ ModelType.TRANSCRIPTION,
6684
6689
  wavBuffer
6685
6690
  );
6686
6691
  logger.log(`[SttTtsPlugin] Transcription result: "${sttText}"`);
@@ -6719,7 +6724,7 @@ var SttTtsPlugin2 = class {
6719
6724
  const { signal } = this.ttsAbortController;
6720
6725
  try {
6721
6726
  const responseStream = await this.runtime.useModel(
6722
- ModelTypes.TEXT_TO_SPEECH,
6727
+ ModelType.TEXT_TO_SPEECH,
6723
6728
  text
6724
6729
  );
6725
6730
  if (!responseStream) {
@@ -6803,7 +6808,7 @@ var SttTtsPlugin2 = class {
6803
6808
  createdAt: Date.now()
6804
6809
  };
6805
6810
  if (responseMemory.content.text?.trim()) {
6806
- await this.runtime.getMemoryManager("messages").createMemory(responseMemory);
6811
+ await this.runtime.createMemory(responseMemory);
6807
6812
  this.isProcessingAudio = false;
6808
6813
  this.volumeBuffers.clear();
6809
6814
  await this.speakText(content.text);
@@ -6922,107 +6927,11 @@ import fs from "node:fs";
6922
6927
  import path from "node:path";
6923
6928
  import {
6924
6929
  ChannelType as ChannelType2,
6925
- ModelTypes as ModelTypes2,
6930
+ ModelType as ModelType2,
6926
6931
  composePrompt,
6927
6932
  createUniqueUuid as createUniqueUuid2,
6928
6933
  logger as logger2
6929
6934
  } from "@elizaos/core";
6930
- async function buildConversationThread(tweet, client, maxReplies = 10) {
6931
- const thread = [];
6932
- const visited = /* @__PURE__ */ new Set();
6933
- async function processThread(currentTweet, depth = 0) {
6934
- logger2.debug("Processing tweet:", {
6935
- id: currentTweet.id,
6936
- inReplyToStatusId: currentTweet.inReplyToStatusId,
6937
- depth
6938
- });
6939
- if (!currentTweet) {
6940
- logger2.debug("No current tweet found for thread building");
6941
- return;
6942
- }
6943
- if (depth >= maxReplies) {
6944
- logger2.debug("Reached maximum reply depth", depth);
6945
- return;
6946
- }
6947
- const memory = await client.runtime.getMemoryManager("messages").getMemoryById(createUniqueUuid2(this.runtime, currentTweet.id));
6948
- if (!memory) {
6949
- const roomId = createUniqueUuid2(
6950
- this.runtime,
6951
- currentTweet.conversationId
6952
- );
6953
- const entityId = createUniqueUuid2(this.runtime, currentTweet.userId);
6954
- await client.runtime.ensureConnection({
6955
- entityId,
6956
- roomId,
6957
- userName: currentTweet.username,
6958
- name: currentTweet.name,
6959
- source: "twitter",
6960
- type: ChannelType2.GROUP
6961
- });
6962
- await client.runtime.getMemoryManager("messages").createMemory({
6963
- id: createUniqueUuid2(this.runtime, currentTweet.id),
6964
- agentId: client.runtime.agentId,
6965
- content: {
6966
- text: currentTweet.text,
6967
- source: "twitter",
6968
- url: currentTweet.permanentUrl,
6969
- imageUrls: currentTweet.photos.map((p) => p.url) || [],
6970
- inReplyTo: currentTweet.inReplyToStatusId ? createUniqueUuid2(this.runtime, currentTweet.inReplyToStatusId) : void 0
6971
- },
6972
- createdAt: currentTweet.timestamp * 1e3,
6973
- roomId,
6974
- entityId: currentTweet.userId === client.profile.id ? client.runtime.agentId : createUniqueUuid2(this.runtime, currentTweet.userId)
6975
- });
6976
- }
6977
- if (visited.has(currentTweet.id)) {
6978
- logger2.debug("Already visited tweet:", currentTweet.id);
6979
- return;
6980
- }
6981
- visited.add(currentTweet.id);
6982
- thread.unshift(currentTweet);
6983
- logger2.debug("Current thread state:", {
6984
- length: thread.length,
6985
- currentDepth: depth,
6986
- tweetId: currentTweet.id
6987
- });
6988
- if (currentTweet.inReplyToStatusId) {
6989
- logger2.debug("Fetching parent tweet:", currentTweet.inReplyToStatusId);
6990
- try {
6991
- const parentTweet = await client.twitterClient.getTweet(
6992
- currentTweet.inReplyToStatusId
6993
- );
6994
- if (parentTweet) {
6995
- logger2.debug("Found parent tweet:", {
6996
- id: parentTweet.id,
6997
- text: parentTweet.text?.slice(0, 50)
6998
- });
6999
- await processThread(parentTweet, depth + 1);
7000
- } else {
7001
- logger2.debug(
7002
- "No parent tweet found for:",
7003
- currentTweet.inReplyToStatusId
7004
- );
7005
- }
7006
- } catch (error) {
7007
- logger2.error("Error fetching parent tweet:", {
7008
- tweetId: currentTweet.inReplyToStatusId,
7009
- error
7010
- });
7011
- }
7012
- } else {
7013
- logger2.debug("Reached end of reply chain at:", currentTweet.id);
7014
- }
7015
- }
7016
- await processThread(tweet, 0);
7017
- logger2.debug("Final thread built:", {
7018
- totalTweets: thread.length,
7019
- tweetIds: thread.map((t) => ({
7020
- id: t.id,
7021
- text: t.text?.slice(0, 50)
7022
- }))
7023
- });
7024
- return thread;
7025
- }
7026
6935
  async function fetchMediaData(attachments) {
7027
6936
  return Promise.all(
7028
6937
  attachments.map(async (attachment) => {
@@ -7032,14 +6941,14 @@ async function fetchMediaData(attachments) {
7032
6941
  throw new Error(`Failed to fetch file: ${attachment.url}`);
7033
6942
  }
7034
6943
  const mediaBuffer = Buffer.from(await response.arrayBuffer());
7035
- const mediaType = attachment.contentType;
6944
+ const mediaType = attachment.contentType || "image/png";
7036
6945
  return { data: mediaBuffer, mediaType };
7037
6946
  }
7038
6947
  if (fs.existsSync(attachment.url)) {
7039
6948
  const mediaBuffer = await fs.promises.readFile(
7040
6949
  path.resolve(attachment.url)
7041
6950
  );
7042
- const mediaType = attachment.contentType;
6951
+ const mediaType = attachment.contentType || "image/png";
7043
6952
  return { data: mediaBuffer, mediaType };
7044
6953
  }
7045
6954
  throw new Error(
@@ -7065,7 +6974,7 @@ Only return the text, no additional formatting.
7065
6974
  ---
7066
6975
  `
7067
6976
  });
7068
- const output = await runtime.useModel(ModelTypes2.TEXT_SMALL, {
6977
+ const output = await runtime.useModel(ModelType2.TEXT_SMALL, {
7069
6978
  prompt
7070
6979
  });
7071
6980
  return output.trim();
@@ -7098,7 +7007,7 @@ Example:
7098
7007
  ---
7099
7008
  `
7100
7009
  });
7101
- const response = await runtime.useModel(ModelTypes2.TEXT_SMALL, {
7010
+ const response = await runtime.useModel(ModelType2.TEXT_SMALL, {
7102
7011
  prompt
7103
7012
  });
7104
7013
  const topics = response.split(",").map((t) => t.trim()).filter(Boolean);
@@ -7221,7 +7130,42 @@ var TwitterSpaceClient = class {
7221
7130
  this.speakerQueue = [];
7222
7131
  const broadcastInfo = await this.currentSpace.initialize(config);
7223
7132
  this.spaceId = broadcastInfo.room_id;
7224
- if (this.runtime.getModel(ModelTypes3.TEXT_TO_SPEECH) && this.runtime.getModel(ModelTypes3.TRANSCRIPTION)) {
7133
+ const userId = this.client.profile.id;
7134
+ const worldId = createUniqueUuid3(this.runtime, userId);
7135
+ const spaceRoomId = createUniqueUuid3(this.runtime, `${userId}-space-${this.spaceId}`);
7136
+ await this.runtime.ensureWorldExists({
7137
+ id: worldId,
7138
+ name: `${this.client.profile.username}'s Twitter`,
7139
+ agentId: this.runtime.agentId,
7140
+ serverId: userId,
7141
+ metadata: {
7142
+ ownership: { ownerId: userId },
7143
+ twitter: {
7144
+ username: this.client.profile.username,
7145
+ id: userId
7146
+ }
7147
+ }
7148
+ });
7149
+ await this.runtime.ensureRoomExists({
7150
+ id: spaceRoomId,
7151
+ name: config.title || "Twitter Space",
7152
+ source: "twitter",
7153
+ type: ChannelType3.GROUP,
7154
+ channelId: this.spaceId,
7155
+ serverId: userId,
7156
+ worldId,
7157
+ metadata: {
7158
+ spaceInfo: {
7159
+ title: config.title,
7160
+ description: config.description,
7161
+ startedAt: Date.now(),
7162
+ mode: config.mode,
7163
+ languages: config.languages,
7164
+ isRecording: config.record
7165
+ }
7166
+ }
7167
+ });
7168
+ if (this.runtime.getModel(ModelType3.TEXT_TO_SPEECH) && this.runtime.getModel(ModelType3.TRANSCRIPTION)) {
7225
7169
  logger3.log("[Space] Using SttTtsPlugin");
7226
7170
  this.currentSpace.use(this.sttTtsPlugin, {
7227
7171
  runtime: this.runtime,
@@ -7238,10 +7182,8 @@ var TwitterSpaceClient = class {
7238
7182
  );
7239
7183
  }
7240
7184
  this.spaceStatus = "hosting" /* HOSTING */;
7241
- await this.twitterClient.sendTweet(
7242
- broadcastInfo.share_url.replace("broadcasts", "spaces")
7243
- );
7244
7185
  const spaceUrl = broadcastInfo.share_url.replace("broadcasts", "spaces");
7186
+ await this.twitterClient.sendTweet(spaceUrl);
7245
7187
  logger3.log(`[Space] Space started => ${spaceUrl}`);
7246
7188
  await speakFiller(this.client.runtime, this.sttTtsPlugin, "WELCOME");
7247
7189
  this.currentSpace.on("occupancyUpdate", (update) => {
@@ -7566,7 +7508,7 @@ var spaceJoin_default = {
7566
7508
  for (const response of responses) {
7567
7509
  await callback(response.content);
7568
7510
  }
7569
- const manager = runtime.getService(ServiceTypes.TWITTER);
7511
+ const manager = runtime.getService(ServiceType.TWITTER);
7570
7512
  if (!manager) {
7571
7513
  throw new Error("Twitter client manager not found");
7572
7514
  }
@@ -7671,10 +7613,9 @@ var spaceJoin_default = {
7671
7613
  };
7672
7614
 
7673
7615
  // src/base.ts
7674
- import { EventEmitter as EventEmitter6 } from "node:events";
7675
7616
  import {
7676
- ChannelType as ChannelType3,
7677
- createUniqueUuid as createUniqueUuid3,
7617
+ ChannelType as ChannelType4,
7618
+ createUniqueUuid as createUniqueUuid4,
7678
7619
  logger as logger5
7679
7620
  } from "@elizaos/core";
7680
7621
  var RequestQueue = class {
@@ -7744,9 +7685,8 @@ var RequestQueue = class {
7744
7685
  await new Promise((resolve) => setTimeout(resolve, delay));
7745
7686
  }
7746
7687
  };
7747
- var _ClientBase = class _ClientBase extends EventEmitter6 {
7688
+ var _ClientBase = class _ClientBase {
7748
7689
  constructor(runtime, state) {
7749
- super();
7750
7690
  this.lastCheckedTweetId = null;
7751
7691
  this.temperature = 0.5;
7752
7692
  this.requestQueue = new RequestQueue();
@@ -7838,7 +7778,7 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
7838
7778
  conversationId: raw.conversationId ?? raw.legacy?.conversation_id_str,
7839
7779
  hashtags: raw.hashtags ?? raw.legacy?.entities?.hashtags ?? [],
7840
7780
  html: raw.html,
7841
- id: raw.id ?? raw.rest_id ?? raw.id_str ?? void 0,
7781
+ id: raw.id ?? raw.rest_id ?? raw.legacy.id_str ?? raw.id_str ?? void 0,
7842
7782
  inReplyToStatus: raw.inReplyToStatus,
7843
7783
  inReplyToStatusId: raw.inReplyToStatusId ?? raw.legacy?.in_reply_to_status_id_str ?? void 0,
7844
7784
  isQuoted: raw.legacy?.is_quote_status === true,
@@ -7852,7 +7792,7 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
7852
7792
  mentions: raw.mentions ?? raw.legacy?.entities?.user_mentions ?? [],
7853
7793
  permanentUrl: raw.permanentUrl ?? (raw.core?.user_results?.result?.legacy?.screen_name && raw.rest_id ? `https://x.com/${raw.core?.user_results?.result?.legacy?.screen_name}/status/${raw.rest_id}` : void 0),
7854
7794
  photos: raw.photos ?? (raw.legacy?.entities?.media?.filter((media) => media.type === "photo").map((media) => ({
7855
- id: media.id_str,
7795
+ id: media.id_str || media.rest_id || media.legacy.id_str,
7856
7796
  url: media.media_url_https,
7857
7797
  alt_text: media.alt_text
7858
7798
  })) || []),
@@ -7881,6 +7821,7 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
7881
7821
  return t;
7882
7822
  }
7883
7823
  async init() {
7824
+ await this.runtime.ensureAgentExists(this.runtime.character);
7884
7825
  const username = this.state?.TWITTER_USERNAME || this.runtime.getSetting("TWITTER_USERNAME");
7885
7826
  const password = this.state?.TWITTER_PASSWORD || this.runtime.getSetting("TWITTER_PASSWORD");
7886
7827
  const email = this.state?.TWITTER_EMAIL || this.runtime.getSetting("TWITTER_EMAIL");
@@ -7945,7 +7886,7 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
7945
7886
  }
7946
7887
  }
7947
7888
  }
7948
- if (retryCount === maxRetries) {
7889
+ if (retryCount >= maxRetries) {
7949
7890
  throw new Error(
7950
7891
  `Twitter login failed after ${maxRetries} attempts. Last error: ${lastError?.message}`
7951
7892
  );
@@ -7981,7 +7922,6 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
7981
7922
  async fetchHomeTimeline(count, following) {
7982
7923
  logger5.debug("fetching home timeline");
7983
7924
  const homeTimeline = following ? await this.twitterClient.fetchFollowingTimeline(count, []) : await this.twitterClient.fetchHomeTimeline(count, []);
7984
- logger5.debug(homeTimeline);
7985
7925
  const processedTimeline = homeTimeline.filter((t) => t.__typename !== "TweetWithVisibilityResults").map((tweet) => this.parseTweet(tweet));
7986
7926
  return processedTimeline;
7987
7927
  }
@@ -8016,59 +7956,75 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
8016
7956
  logger5.debug("populating timeline...");
8017
7957
  const cachedTimeline = await this.getCachedTimeline();
8018
7958
  if (cachedTimeline) {
8019
- const existingMemories2 = await this.runtime.getMemoryManager("messages").getMemoriesByRoomIds({
7959
+ const existingMemories2 = await this.runtime.getMemoriesByRoomIds({
7960
+ tableName: "messages",
8020
7961
  roomIds: cachedTimeline.map(
8021
- (tweet) => createUniqueUuid3(this.runtime, tweet.conversationId)
7962
+ (tweet) => createUniqueUuid4(this.runtime, tweet.conversationId)
8022
7963
  )
8023
7964
  });
8024
7965
  const existingMemoryIds2 = new Set(
8025
7966
  existingMemories2.map((memory) => memory.id.toString())
8026
7967
  );
8027
7968
  const someCachedTweetsExist = cachedTimeline.some(
8028
- (tweet) => existingMemoryIds2.has(createUniqueUuid3(this.runtime, tweet.id))
7969
+ (tweet) => existingMemoryIds2.has(createUniqueUuid4(this.runtime, tweet.id))
8029
7970
  );
8030
7971
  if (someCachedTweetsExist) {
8031
7972
  const tweetsToSave2 = cachedTimeline.filter(
8032
- (tweet) => tweet.userId !== this.profile.id && !existingMemoryIds2.has(createUniqueUuid3(this.runtime, tweet.id))
7973
+ (tweet) => tweet.userId !== this.profile.id && !existingMemoryIds2.has(createUniqueUuid4(this.runtime, tweet.id))
8033
7974
  );
8034
7975
  for (const tweet of tweetsToSave2) {
8035
7976
  logger5.log("Saving Tweet", tweet.id);
8036
7977
  if (tweet.userId === this.profile.id) {
8037
7978
  continue;
8038
7979
  }
8039
- const roomId = createUniqueUuid3(this.runtime, tweet.conversationId);
8040
- const entityId = createUniqueUuid3(
8041
- this.runtime,
8042
- tweet.userId === this.profile.id ? this.runtime.agentId : tweet.userId
8043
- );
7980
+ const worldId = createUniqueUuid4(this.runtime, tweet.userId);
7981
+ await this.runtime.ensureWorldExists({
7982
+ id: worldId,
7983
+ name: `${tweet.username}'s Twitter`,
7984
+ agentId: this.runtime.agentId,
7985
+ serverId: tweet.userId,
7986
+ metadata: {
7987
+ ownership: { ownerId: tweet.userId },
7988
+ twitter: {
7989
+ username: tweet.username,
7990
+ id: tweet.userId
7991
+ }
7992
+ }
7993
+ });
7994
+ const roomId = createUniqueUuid4(this.runtime, tweet.conversationId);
7995
+ await this.runtime.ensureRoomExists({
7996
+ id: roomId,
7997
+ name: `${tweet.username}'s Thread`,
7998
+ source: "twitter",
7999
+ type: ChannelType4.FEED,
8000
+ channelId: tweet.conversationId,
8001
+ serverId: tweet.userId,
8002
+ worldId
8003
+ });
8004
+ const entityId = tweet.userId === this.profile.id ? this.runtime.agentId : createUniqueUuid4(this.runtime, tweet.userId);
8044
8005
  await this.runtime.ensureConnection({
8045
8006
  entityId,
8046
8007
  roomId,
8047
8008
  userName: tweet.username,
8048
8009
  name: tweet.name,
8049
8010
  source: "twitter",
8050
- type: ChannelType3.FEED
8011
+ type: ChannelType4.FEED,
8012
+ worldId
8051
8013
  });
8052
8014
  const content = {
8053
8015
  text: tweet.text,
8054
8016
  url: tweet.permanentUrl,
8055
8017
  source: "twitter",
8056
- inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid3(this.runtime, tweet.inReplyToStatusId) : void 0
8018
+ inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid4(this.runtime, tweet.inReplyToStatusId) : void 0
8057
8019
  };
8058
- logger5.log("Creating memory for tweet", tweet.id);
8059
- const memory = await this.runtime.getMemoryManager("messages").getMemoryById(createUniqueUuid3(this.runtime, tweet.id));
8060
- if (memory) {
8061
- logger5.log("Memory already exists, skipping timeline population");
8062
- break;
8063
- }
8064
- await this.runtime.getMemoryManager("messages").createMemory({
8065
- id: createUniqueUuid3(this.runtime, tweet.id),
8020
+ await this.runtime.createMemory({
8021
+ id: createUniqueUuid4(this.runtime, tweet.id),
8066
8022
  entityId,
8067
8023
  content,
8068
8024
  agentId: this.runtime.agentId,
8069
8025
  roomId,
8070
8026
  createdAt: tweet.timestamp * 1e3
8071
- });
8027
+ }, "messages");
8072
8028
  await this.cacheTweet(tweet);
8073
8029
  }
8074
8030
  logger5.log(
@@ -8089,16 +8045,17 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
8089
8045
  const roomIds = /* @__PURE__ */ new Set();
8090
8046
  for (const tweet of allTweets) {
8091
8047
  tweetIdsToCheck.add(tweet.id);
8092
- roomIds.add(createUniqueUuid3(this.runtime, tweet.conversationId));
8048
+ roomIds.add(createUniqueUuid4(this.runtime, tweet.conversationId));
8093
8049
  }
8094
- const existingMemories = await this.runtime.getMemoryManager("messages").getMemoriesByRoomIds({
8050
+ const existingMemories = await this.runtime.getMemoriesByRoomIds({
8051
+ tableName: "messages",
8095
8052
  roomIds: Array.from(roomIds)
8096
8053
  });
8097
8054
  const existingMemoryIds = new Set(
8098
8055
  existingMemories.map((memory) => memory.id)
8099
8056
  );
8100
8057
  const tweetsToSave = allTweets.filter(
8101
- (tweet) => tweet.userId !== this.profile.id && !existingMemoryIds.has(createUniqueUuid3(this.runtime, tweet.id))
8058
+ (tweet) => tweet.userId !== this.profile.id && !existingMemoryIds.has(createUniqueUuid4(this.runtime, tweet.id))
8102
8059
  );
8103
8060
  logger5.debug({
8104
8061
  processingTweets: tweetsToSave.map((tweet) => tweet.id).join(",")
@@ -8108,30 +8065,54 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
8108
8065
  if (tweet.userId === this.profile.id) {
8109
8066
  continue;
8110
8067
  }
8111
- const roomId = createUniqueUuid3(this.runtime, tweet.conversationId);
8112
- const entityId = tweet.userId === this.profile.id ? this.runtime.agentId : createUniqueUuid3(this.runtime, tweet.userId);
8068
+ const worldId = createUniqueUuid4(this.runtime, tweet.userId);
8069
+ await this.runtime.ensureWorldExists({
8070
+ id: worldId,
8071
+ name: `${tweet.username}'s Twitter`,
8072
+ agentId: this.runtime.agentId,
8073
+ serverId: tweet.userId,
8074
+ metadata: {
8075
+ ownership: { ownerId: tweet.userId },
8076
+ twitter: {
8077
+ username: tweet.username,
8078
+ id: tweet.userId
8079
+ }
8080
+ }
8081
+ });
8082
+ const roomId = createUniqueUuid4(this.runtime, tweet.conversationId);
8083
+ await this.runtime.ensureRoomExists({
8084
+ id: roomId,
8085
+ name: `${tweet.username}'s Thread`,
8086
+ source: "twitter",
8087
+ type: ChannelType4.FEED,
8088
+ channelId: tweet.conversationId,
8089
+ serverId: tweet.userId,
8090
+ worldId
8091
+ });
8092
+ const entityId = tweet.userId === this.profile.id ? this.runtime.agentId : createUniqueUuid4(this.runtime, tweet.userId);
8113
8093
  await this.runtime.ensureConnection({
8114
8094
  entityId,
8115
8095
  roomId,
8116
8096
  userName: tweet.username,
8117
8097
  name: tweet.name,
8118
8098
  source: "twitter",
8119
- type: ChannelType3.FEED
8099
+ type: ChannelType4.FEED,
8100
+ worldId
8120
8101
  });
8121
8102
  const content = {
8122
8103
  text: tweet.text,
8123
8104
  url: tweet.permanentUrl,
8124
8105
  source: "twitter",
8125
- inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid3(this.runtime, tweet.inReplyToStatusId) : void 0
8106
+ inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid4(this.runtime, tweet.inReplyToStatusId) : void 0
8126
8107
  };
8127
- await this.runtime.getMemoryManager("messages").createMemory({
8128
- id: createUniqueUuid3(this.runtime, tweet.id),
8108
+ await this.runtime.createMemory({
8109
+ id: createUniqueUuid4(this.runtime, tweet.id),
8129
8110
  entityId,
8130
8111
  content,
8131
8112
  agentId: this.runtime.agentId,
8132
8113
  roomId,
8133
8114
  createdAt: tweet.timestamp * 1e3
8134
- });
8115
+ }, "messages");
8135
8116
  await this.cacheTweet(tweet);
8136
8117
  }
8137
8118
  await this.cacheTimeline(timeline);
@@ -8145,7 +8126,8 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
8145
8126
  }
8146
8127
  async saveRequestMessage(message, state) {
8147
8128
  if (message.content.text) {
8148
- const recentMessage = await this.runtime.getMemoryManager("messages").getMemories({
8129
+ const recentMessage = await this.runtime.getMemories({
8130
+ tableName: "messages",
8149
8131
  roomId: message.roomId,
8150
8132
  count: 1,
8151
8133
  unique: false
@@ -8153,7 +8135,7 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
8153
8135
  if (recentMessage.length > 0 && recentMessage[0].content === message.content) {
8154
8136
  logger5.debug("Message already saved", recentMessage[0].id);
8155
8137
  } else {
8156
- await this.runtime.getMemoryManager("messages").createMemory(message);
8138
+ await this.runtime.createMemory(message, "messages");
8157
8139
  }
8158
8140
  await this.runtime.evaluate(message, {
8159
8141
  ...state,
@@ -8233,102 +8215,30 @@ var _ClientBase = class _ClientBase extends EventEmitter6 {
8233
8215
  */
8234
8216
  async fetchInteractions() {
8235
8217
  try {
8236
- const interactions = await this.requestQueue.add(
8237
- () => this.twitterClient.get("statuses/mentions_timeline", {
8238
- count: 100,
8239
- include_entities: true
8240
- })
8218
+ const username = this.profile.username;
8219
+ const mentionsResponse = await this.requestQueue.add(
8220
+ () => this.twitterClient.fetchSearchTweets(
8221
+ `@${username}`,
8222
+ 100,
8223
+ 1 /* Latest */
8224
+ )
8241
8225
  );
8242
- return interactions.map((interaction) => ({
8243
- id: interaction.id_str,
8244
- type: this.getInteractionType(interaction),
8245
- userId: interaction.user.id_str,
8246
- username: interaction.user.screen_name,
8247
- name: interaction.user.name,
8248
- targetTweetId: interaction.in_reply_to_status_id_str || interaction.quoted_status_id_str,
8249
- targetTweet: interaction.quoted_status || interaction,
8250
- quoteTweet: interaction.is_quote_status ? interaction : void 0,
8251
- retweetId: interaction.retweeted_status?.id_str
8226
+ return mentionsResponse.tweets.map((tweet) => ({
8227
+ id: tweet.id,
8228
+ type: tweet.isQuoted ? "quote" : tweet.retweetedStatus ? "retweet" : "like",
8229
+ userId: tweet.userId,
8230
+ username: tweet.username,
8231
+ name: tweet.name || tweet.username,
8232
+ targetTweetId: tweet.inReplyToStatusId || tweet.quotedStatusId,
8233
+ targetTweet: tweet.quotedStatus || tweet,
8234
+ quoteTweet: tweet.isQuoted ? tweet : void 0,
8235
+ retweetId: tweet.retweetedStatus?.id
8252
8236
  }));
8253
8237
  } catch (error) {
8254
8238
  logger5.error("Error fetching Twitter interactions:", error);
8255
8239
  return [];
8256
8240
  }
8257
8241
  }
8258
- /**
8259
- * Determines the type of interaction from a Twitter API response
8260
- */
8261
- getInteractionType(interaction) {
8262
- if (interaction.retweeted_status) {
8263
- return "retweet";
8264
- }
8265
- if (interaction.is_quote_status) {
8266
- return "quote";
8267
- }
8268
- return "like";
8269
- }
8270
- /**
8271
- * Fetches recent follower changes (new followers and unfollowers)
8272
- */
8273
- async fetchFollowerChanges() {
8274
- try {
8275
- const currentFollowers = await this.requestQueue.add(
8276
- () => this.twitterClient.get("followers/list", {
8277
- count: 200,
8278
- include_user_entities: false
8279
- })
8280
- );
8281
- const cachedFollowers = await this.getCachedFollowers();
8282
- const changes = [];
8283
- for (const follower of currentFollowers.users) {
8284
- if (!cachedFollowers.some(
8285
- (f) => f.id_str === follower.id_str
8286
- )) {
8287
- changes.push({
8288
- type: "followed",
8289
- userId: follower.id_str,
8290
- username: follower.screen_name,
8291
- name: follower.name,
8292
- user: follower
8293
- });
8294
- }
8295
- }
8296
- for (const cached of cachedFollowers) {
8297
- if (!currentFollowers.users.some((f) => f.id_str === cached.id_str)) {
8298
- changes.push({
8299
- type: "unfollowed",
8300
- userId: cached.id_str,
8301
- username: cached.screen_name,
8302
- name: cached.name,
8303
- user: cached
8304
- });
8305
- }
8306
- }
8307
- await this.cacheFollowers(currentFollowers.users);
8308
- return changes;
8309
- } catch (error) {
8310
- logger5.error("Error fetching Twitter follower changes:", error);
8311
- return [];
8312
- }
8313
- }
8314
- /**
8315
- * Gets cached followers from the database
8316
- */
8317
- async getCachedFollowers() {
8318
- const cached = await this.runtime.getCache(
8319
- `twitter/${this.profile.username}/followers`
8320
- );
8321
- return cached || [];
8322
- }
8323
- /**
8324
- * Caches current followers in the database
8325
- */
8326
- async cacheFollowers(followers) {
8327
- await this.runtime.setCache(
8328
- `twitter/${this.profile.username}/followers`,
8329
- followers
8330
- );
8331
- }
8332
8242
  };
8333
8243
  _ClientBase._twitterClients = {};
8334
8244
  var ClientBase = _ClientBase;
@@ -8338,16 +8248,16 @@ var TWITTER_SERVICE_NAME = "twitter";
8338
8248
 
8339
8249
  // src/interactions.ts
8340
8250
  import {
8341
- ChannelType as ChannelType4,
8251
+ ChannelType as ChannelType5,
8342
8252
  EventTypes as EventTypes2,
8343
- ModelTypes as ModelTypes4,
8253
+ ModelType as ModelType4,
8344
8254
  composePrompt as composePrompt2,
8345
- createUniqueUuid as createUniqueUuid4,
8255
+ createUniqueUuid as createUniqueUuid5,
8346
8256
  logger as logger6
8347
8257
  } from "@elizaos/core";
8348
8258
 
8349
8259
  // src/types.ts
8350
- var ServiceTypes2 = {
8260
+ var ServiceType2 = {
8351
8261
  TWITTER: "twitter"
8352
8262
  };
8353
8263
 
@@ -8417,48 +8327,75 @@ var TwitterInteractionClient = class {
8417
8327
  uniqueTweetCandidates = uniqueTweetCandidates.sort((a, b) => a.id.localeCompare(b.id)).filter((tweet) => tweet.userId !== this.client.profile.id);
8418
8328
  for (const tweet of uniqueTweetCandidates) {
8419
8329
  if (!this.client.lastCheckedTweetId || BigInt(tweet.id) > this.client.lastCheckedTweetId) {
8420
- const tweetId = createUniqueUuid4(this.runtime, tweet.id);
8421
- const existingResponse = await this.runtime.getMemoryManager("messages").getMemoryById(tweetId);
8330
+ const tweetId = createUniqueUuid5(this.runtime, tweet.id);
8331
+ const existingResponse = await this.runtime.getMemoryById(tweetId);
8422
8332
  if (existingResponse) {
8423
8333
  logger6.log(`Already responded to tweet ${tweet.id}, skipping`);
8424
8334
  continue;
8425
8335
  }
8426
8336
  logger6.log("New Tweet found", tweet.permanentUrl);
8427
- const roomId = createUniqueUuid4(this.runtime, tweet.conversationId);
8428
- const entityId = createUniqueUuid4(
8337
+ const entityId = createUniqueUuid5(
8429
8338
  this.runtime,
8430
8339
  tweet.userId === this.client.profile.id ? this.runtime.agentId : tweet.userId
8431
8340
  );
8341
+ const worldId = createUniqueUuid5(this.runtime, tweet.userId);
8342
+ const roomId = createUniqueUuid5(this.runtime, tweet.conversationId);
8343
+ await this.runtime.ensureWorldExists({
8344
+ id: worldId,
8345
+ name: `${tweet.name}'s Twitter`,
8346
+ agentId: this.runtime.agentId,
8347
+ serverId: tweet.userId,
8348
+ metadata: {
8349
+ ownership: { ownerId: tweet.userId },
8350
+ twitter: {
8351
+ username: tweet.username,
8352
+ id: tweet.userId,
8353
+ name: tweet.name
8354
+ }
8355
+ }
8356
+ });
8432
8357
  await this.runtime.ensureConnection({
8433
8358
  entityId,
8434
8359
  roomId,
8435
8360
  userName: tweet.username,
8436
8361
  name: tweet.name,
8437
8362
  source: "twitter",
8438
- type: ChannelType4.GROUP
8363
+ type: ChannelType5.GROUP,
8364
+ channelId: tweet.conversationId,
8365
+ serverId: tweet.userId,
8366
+ worldId
8367
+ });
8368
+ await this.runtime.ensureRoomExists({
8369
+ id: roomId,
8370
+ name: `Conversation with ${tweet.name}`,
8371
+ source: "twitter",
8372
+ type: ChannelType5.GROUP,
8373
+ channelId: tweet.conversationId,
8374
+ serverId: tweet.userId,
8375
+ worldId
8439
8376
  });
8440
- const thread = await buildConversationThread(tweet, this.client);
8441
- const message = {
8377
+ const memory = {
8378
+ id: tweetId,
8379
+ agentId: this.runtime.agentId,
8442
8380
  content: {
8443
8381
  text: tweet.text,
8382
+ url: tweet.permanentUrl,
8444
8383
  imageUrls: tweet.photos?.map((photo) => photo.url) || [],
8445
- tweet,
8446
- source: "twitter"
8384
+ inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid5(this.runtime, tweet.inReplyToStatusId) : void 0,
8385
+ source: "twitter",
8386
+ channelType: ChannelType5.GROUP
8447
8387
  },
8448
- agentId: this.runtime.agentId,
8449
8388
  entityId,
8450
- roomId
8389
+ roomId,
8390
+ createdAt: tweet.timestamp * 1e3
8451
8391
  };
8392
+ await this.runtime.createMemory(memory, "messages");
8452
8393
  if (tweet.text.includes(`@${twitterUsername}`)) {
8453
8394
  const messagePayload = {
8454
8395
  runtime: this.runtime,
8455
8396
  message: {
8456
- ...message,
8457
- content: {
8458
- ...message.content,
8459
- source: "twitter"
8460
- },
8461
- roomId: message.roomId
8397
+ ...memory,
8398
+ source: "twitter"
8462
8399
  },
8463
8400
  source: "twitter",
8464
8401
  callback: async (response) => {
@@ -8470,12 +8407,8 @@ var TwitterInteractionClient = class {
8470
8407
  const mentionPayload = {
8471
8408
  runtime: this.runtime,
8472
8409
  message: {
8473
- ...message,
8474
- content: {
8475
- ...message.content,
8476
- source: "twitter"
8477
- },
8478
- roomId: message.roomId
8410
+ ...memory,
8411
+ source: "twitter"
8479
8412
  },
8480
8413
  tweet: convertToCoreTweet(tweet),
8481
8414
  user: {
@@ -8491,10 +8424,10 @@ var TwitterInteractionClient = class {
8491
8424
  };
8492
8425
  this.runtime.emitEvent("TWITTER_MENTION_RECEIVED" /* MENTION_RECEIVED */, mentionPayload);
8493
8426
  }
8494
- if (thread.length > 1) {
8427
+ if (tweet.thread.length > 1) {
8495
8428
  const threadPayload = {
8496
8429
  runtime: this.runtime,
8497
- tweets: convertToCoreTweets(thread),
8430
+ tweets: convertToCoreTweets(tweet.thread),
8498
8431
  user: {
8499
8432
  id: tweet.userId,
8500
8433
  username: tweet.username,
@@ -8502,19 +8435,19 @@ var TwitterInteractionClient = class {
8502
8435
  },
8503
8436
  source: "twitter"
8504
8437
  };
8505
- if (thread[thread.length - 1].id === tweet.id) {
8438
+ if (tweet.thread[tweet.thread.length - 1].id === tweet.id) {
8506
8439
  this.runtime.emitEvent("TWITTER_THREAD_UPDATED" /* THREAD_UPDATED */, {
8507
8440
  ...threadPayload,
8508
8441
  newTweet: convertToCoreTweet(tweet)
8509
8442
  });
8510
- } else if (thread[0].id === tweet.id) {
8443
+ } else if (tweet.thread[0].id === tweet.id) {
8511
8444
  this.runtime.emitEvent("TWITTER_THREAD_CREATED" /* THREAD_CREATED */, threadPayload);
8512
8445
  }
8513
8446
  }
8514
8447
  await this.handleTweet({
8515
8448
  tweet,
8516
- message,
8517
- thread
8449
+ message: memory,
8450
+ thread: tweet.thread
8518
8451
  });
8519
8452
  this.client.lastCheckedTweetId = BigInt(tweet.id);
8520
8453
  }
@@ -8528,15 +8461,15 @@ var TwitterInteractionClient = class {
8528
8461
  interaction.userId,
8529
8462
  interaction.targetTweet.conversationId
8530
8463
  );
8531
- await this.runtime.getMemoryManager("interactions").createMemory(memory);
8464
+ await this.runtime.createMemory(memory, "messages");
8532
8465
  const reactionMessage = {
8533
- id: createUniqueUuid4(this.runtime, interaction.targetTweetId),
8466
+ id: createUniqueUuid5(this.runtime, interaction.targetTweetId),
8534
8467
  content: {
8535
8468
  text: interaction.targetTweet.text,
8536
8469
  source: "twitter"
8537
8470
  },
8538
- entityId: createUniqueUuid4(this.runtime, interaction.targetTweet.userId),
8539
- roomId: createUniqueUuid4(this.runtime, interaction.targetTweet.conversationId),
8471
+ entityId: createUniqueUuid5(this.runtime, interaction.targetTweet.userId),
8472
+ roomId: createUniqueUuid5(this.runtime, interaction.targetTweet.conversationId),
8540
8473
  agentId: this.runtime.agentId
8541
8474
  };
8542
8475
  const basePayload = {
@@ -8559,7 +8492,7 @@ var TwitterInteractionClient = class {
8559
8492
  ...basePayload,
8560
8493
  reaction: {
8561
8494
  type: "like",
8562
- entityId: createUniqueUuid4(this.runtime, interaction.userId)
8495
+ entityId: createUniqueUuid5(this.runtime, interaction.userId)
8563
8496
  },
8564
8497
  message: reactionMessage,
8565
8498
  callback: async () => {
@@ -8579,7 +8512,7 @@ var TwitterInteractionClient = class {
8579
8512
  ...basePayload,
8580
8513
  reaction: {
8581
8514
  type: "retweet",
8582
- entityId: createUniqueUuid4(this.runtime, interaction.userId)
8515
+ entityId: createUniqueUuid5(this.runtime, interaction.userId)
8583
8516
  },
8584
8517
  message: reactionMessage,
8585
8518
  callback: async () => {
@@ -8597,7 +8530,7 @@ var TwitterInteractionClient = class {
8597
8530
  callback: async () => [],
8598
8531
  reaction: {
8599
8532
  type: "quote",
8600
- entityId: createUniqueUuid4(this.runtime, interaction.userId)
8533
+ entityId: createUniqueUuid5(this.runtime, interaction.userId)
8601
8534
  }
8602
8535
  };
8603
8536
  this.runtime.emitEvent("TWITTER_QUOTE_RECEIVED" /* QUOTE_RECEIVED */, quotePayload);
@@ -8605,7 +8538,7 @@ var TwitterInteractionClient = class {
8605
8538
  ...basePayload,
8606
8539
  reaction: {
8607
8540
  type: "quote",
8608
- entityId: createUniqueUuid4(this.runtime, interaction.userId)
8541
+ entityId: createUniqueUuid5(this.runtime, interaction.userId)
8609
8542
  },
8610
8543
  message: reactionMessage,
8611
8544
  callback: async () => {
@@ -8632,43 +8565,9 @@ var TwitterInteractionClient = class {
8632
8565
  change.userId,
8633
8566
  profileId
8634
8567
  );
8635
- await this.runtime.getMemoryManager("follower-changes").createMemory(followerMemory);
8568
+ await this.runtime.createMemory(followerMemory, "follower-changes");
8636
8569
  }
8637
8570
  };
8638
- const followerChanges = await this.client.fetchFollowerChanges();
8639
- for (const change of followerChanges) {
8640
- const changeId = createUniqueUuid4(this.runtime, `${change.type}-${change.userId}`);
8641
- const existingChange = await this.runtime.getMemoryManager("follower-changes").getMemoryById(changeId);
8642
- if (existingChange) continue;
8643
- const entityId = createUniqueUuid4(this.runtime, change.userId);
8644
- const basePayload = {
8645
- runtime: this.runtime,
8646
- user: {
8647
- id: change.userId,
8648
- username: change.username,
8649
- name: change.name
8650
- },
8651
- source: "twitter"
8652
- };
8653
- if (change.type === "followed") {
8654
- const userFollowedPayload = {
8655
- ...basePayload,
8656
- follower: change.user,
8657
- entityId: createUniqueUuid4(this.runtime, change.userId),
8658
- roomId: createUniqueUuid4(this.runtime, this.client.profile.id)
8659
- };
8660
- this.runtime.emitEvent("TWITTER_USER_FOLLOWED" /* USER_FOLLOWED */, userFollowedPayload);
8661
- } else if (change.type === "unfollowed") {
8662
- const userUnfollowedPayload = {
8663
- ...basePayload,
8664
- unfollower: change.user,
8665
- entityId: createUniqueUuid4(this.runtime, change.userId),
8666
- roomId: createUniqueUuid4(this.runtime, this.client.profile.id)
8667
- };
8668
- this.runtime.emitEvent("TWITTER_USER_UNFOLLOWED" /* USER_UNFOLLOWED */, userUnfollowedPayload);
8669
- }
8670
- await processFollowerChange(change, this.client.profile.id);
8671
- }
8672
8571
  await this.client.cacheLatestCheckedTweetId();
8673
8572
  logger6.log("Finished checking Twitter interactions");
8674
8573
  } catch (error) {
@@ -8718,7 +8617,7 @@ var TwitterInteractionClient = class {
8718
8617
  try {
8719
8618
  for (const photo of tweet.photos) {
8720
8619
  const description = await this.runtime.useModel(
8721
- ModelTypes4.IMAGE_DESCRIPTION,
8620
+ ModelType4.IMAGE_DESCRIPTION,
8722
8621
  photo.url
8723
8622
  );
8724
8623
  imageDescriptionsArray.push(description);
@@ -8733,27 +8632,27 @@ var TwitterInteractionClient = class {
8733
8632
  currentPost,
8734
8633
  formattedConversation
8735
8634
  };
8736
- const tweetId = createUniqueUuid4(this.runtime, tweet.id);
8737
- const tweetExists = await this.runtime.getMemoryManager("messages").getMemoryById(tweetId);
8635
+ const tweetId = createUniqueUuid5(this.runtime, tweet.id);
8636
+ const tweetExists = await this.runtime.getMemoryById(tweetId);
8738
8637
  if (!tweetExists) {
8739
8638
  logger6.log("tweet does not exist, saving");
8740
- const entityId = createUniqueUuid4(this.runtime, tweet.userId);
8741
- const roomId = createUniqueUuid4(this.runtime, tweet.conversationId);
8639
+ const entityId = createUniqueUuid5(this.runtime, tweet.userId);
8640
+ const roomId = createUniqueUuid5(this.runtime, tweet.conversationId);
8742
8641
  await this.runtime.ensureConnection({
8743
8642
  entityId,
8744
8643
  roomId,
8745
8644
  userName: tweet.username,
8746
8645
  name: tweet.name,
8747
8646
  source: "twitter",
8748
- type: ChannelType4.GROUP
8647
+ type: ChannelType5.GROUP
8749
8648
  });
8750
8649
  await this.runtime.ensureRoomExists({
8751
8650
  id: roomId,
8752
8651
  name: `Conversation with ${tweet.name}`,
8753
8652
  source: "twitter",
8754
- type: ChannelType4.GROUP,
8653
+ type: ChannelType5.GROUP,
8755
8654
  channelId: tweet.conversationId,
8756
- worldId: createUniqueUuid4(this.runtime, tweet.userId)
8655
+ worldId: createUniqueUuid5(this.runtime, tweet.userId)
8757
8656
  });
8758
8657
  const memory = {
8759
8658
  id: tweetId,
@@ -8762,9 +8661,9 @@ var TwitterInteractionClient = class {
8762
8661
  text: tweet.text,
8763
8662
  url: tweet.permanentUrl,
8764
8663
  imageUrls: tweet.photos?.map((photo) => photo.url) || [],
8765
- inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid4(this.runtime, tweet.inReplyToStatusId) : void 0,
8664
+ inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid5(this.runtime, tweet.inReplyToStatusId) : void 0,
8766
8665
  source: "twitter",
8767
- channelType: ChannelType4.GROUP
8666
+ channelType: ChannelType5.GROUP
8768
8667
  },
8769
8668
  entityId,
8770
8669
  roomId,
@@ -8776,7 +8675,7 @@ var TwitterInteractionClient = class {
8776
8675
  state,
8777
8676
  template: this.runtime.character.templates?.shouldRespondTemplate || ""
8778
8677
  });
8779
- const response = await this.runtime.useModel(ModelTypes4.TEXT_SMALL, {
8678
+ const response = await this.runtime.useModel(ModelType4.TEXT_SMALL, {
8780
8679
  prompt: shouldRespondPrompt
8781
8680
  });
8782
8681
  const responseActions = (response.match(/(?:RESPOND|IGNORE|STOP)/g) || [
@@ -8808,9 +8707,9 @@ var TwitterInteractionClient = class {
8808
8707
  if (!replyTweetResult) {
8809
8708
  throw new Error("Failed to create tweet response");
8810
8709
  }
8811
- const responseId = createUniqueUuid4(
8710
+ const responseId = createUniqueUuid5(
8812
8711
  this.runtime,
8813
- replyTweetResult.id_str
8712
+ replyTweetResult.id_str || replyTweetResult.rest_id || replyTweetResult.legacy.id_str || replyTweetResult.id
8814
8713
  );
8815
8714
  const responseMemory = {
8816
8715
  id: responseId,
@@ -8823,7 +8722,7 @@ var TwitterInteractionClient = class {
8823
8722
  },
8824
8723
  createdAt: Date.now()
8825
8724
  };
8826
- await this.runtime.getMemoryManager("messages").createMemory(responseMemory);
8725
+ await this.runtime.createMemory(responseMemory, "messages");
8827
8726
  return [responseMemory];
8828
8727
  } catch (error) {
8829
8728
  logger6.error("Error replying to tweet:", error);
@@ -8862,32 +8761,32 @@ var TwitterInteractionClient = class {
8862
8761
  logger6.log("Reached maximum reply depth", depth);
8863
8762
  return;
8864
8763
  }
8865
- const memory = await this.runtime.getMemoryManager("messages").getMemoryById(createUniqueUuid4(this.runtime, currentTweet.id));
8764
+ const memory = await this.runtime.getMemoryById(createUniqueUuid5(this.runtime, currentTweet.id));
8866
8765
  if (!memory) {
8867
- const roomId = createUniqueUuid4(this.runtime, tweet.conversationId);
8868
- const entityId = createUniqueUuid4(this.runtime, currentTweet.userId);
8766
+ const roomId = createUniqueUuid5(this.runtime, tweet.conversationId);
8767
+ const entityId = createUniqueUuid5(this.runtime, currentTweet.userId);
8869
8768
  await this.runtime.ensureConnection({
8870
8769
  entityId,
8871
8770
  roomId,
8872
8771
  userName: currentTweet.username,
8873
8772
  name: currentTweet.name,
8874
8773
  source: "twitter",
8875
- type: ChannelType4.GROUP
8774
+ type: ChannelType5.GROUP
8876
8775
  });
8877
- this.runtime.getMemoryManager("messages").createMemory({
8878
- id: createUniqueUuid4(this.runtime, currentTweet.id),
8776
+ this.runtime.createMemory({
8777
+ id: createUniqueUuid5(this.runtime, currentTweet.id),
8879
8778
  agentId: this.runtime.agentId,
8880
8779
  content: {
8881
8780
  text: currentTweet.text,
8882
8781
  source: "twitter",
8883
8782
  url: currentTweet.permanentUrl,
8884
8783
  imageUrls: currentTweet.photos?.map((photo) => photo.url) || [],
8885
- inReplyTo: currentTweet.inReplyToStatusId ? createUniqueUuid4(this.runtime, currentTweet.inReplyToStatusId) : void 0
8784
+ inReplyTo: currentTweet.inReplyToStatusId ? createUniqueUuid5(this.runtime, currentTweet.inReplyToStatusId) : void 0
8886
8785
  },
8887
8786
  createdAt: currentTweet.timestamp * 1e3,
8888
8787
  roomId,
8889
- entityId: currentTweet.userId === this.twitterUserId ? this.runtime.agentId : createUniqueUuid4(this.runtime, currentTweet.userId)
8890
- });
8788
+ entityId: currentTweet.userId === this.twitterUserId ? this.runtime.agentId : createUniqueUuid5(this.runtime, currentTweet.userId)
8789
+ }, "messages");
8891
8790
  }
8892
8791
  if (visited.has(currentTweet.id)) {
8893
8792
  logger6.log("Already visited tweet:", currentTweet.id);
@@ -8928,10 +8827,10 @@ var TwitterInteractionClient = class {
8928
8827
  }
8929
8828
  createMemoryObject(type, id, userId, roomId) {
8930
8829
  return {
8931
- id: createUniqueUuid4(this.runtime, id),
8830
+ id: createUniqueUuid5(this.runtime, id),
8932
8831
  agentId: this.runtime.agentId,
8933
- entityId: createUniqueUuid4(this.runtime, userId),
8934
- roomId: createUniqueUuid4(this.runtime, roomId),
8832
+ entityId: createUniqueUuid5(this.runtime, userId),
8833
+ roomId: createUniqueUuid5(this.runtime, roomId),
8935
8834
  content: {
8936
8835
  type,
8937
8836
  source: "twitter"
@@ -8943,23 +8842,12 @@ var TwitterInteractionClient = class {
8943
8842
 
8944
8843
  // src/post.ts
8945
8844
  import {
8946
- ChannelType as ChannelType5,
8947
- ModelTypes as ModelTypes5,
8948
- composePrompt as composePrompt3,
8949
- createUniqueUuid as createUniqueUuid5,
8845
+ ChannelType as ChannelType6,
8846
+ EventTypes as EventTypes3,
8847
+ createUniqueUuid as createUniqueUuid6,
8950
8848
  logger as logger7,
8951
- parseJSONObjectFromText,
8952
8849
  truncateToCompleteSentence
8953
8850
  } from "@elizaos/core";
8954
-
8955
- // src/templates.ts
8956
- var twitterPostTemplate = `# Task: Create a post in the voice and style and perspective of {{agentName}} @{{twitterUserName}}.
8957
- {{providers}}
8958
- Write a post that is {{adjective}} about {{topic}} (without mentioning {{topic}} directly), from the perspective of {{agentName}}. Do not add commentary or acknowledge this request, just write the post.
8959
- Your response should be 1, 2, or 3 sentences (choose the length at random).
8960
- Your response should not contain any questions. Brief, concise statements only. The total character count MUST be less than 280. No emojis. Use \\n\\n (double spaces) between statements if there are multiple statements in your response.`;
8961
-
8962
- // src/post.ts
8963
8851
  var TwitterPostClient = class {
8964
8852
  /**
8965
8853
  * Constructor for initializing a new Twitter client with the provided client, runtime, and state
@@ -8977,7 +8865,7 @@ var TwitterPostClient = class {
8977
8865
  logger7.log(`- Username: ${this.twitterUsername}`);
8978
8866
  logger7.log(`- Dry Run Mode: ${this.isDryRun ? "Enabled" : "Disabled"}`);
8979
8867
  logger7.log(
8980
- `- Disable Post: ${this.state?.TWITTER_ENABLE_POST_GENERATION || this.runtime.getSetting("TWITTER_ENABLE_POST_GENERATION") ? "disabled" : "enabled"}`
8868
+ `- Auto-post: ${this.state?.TWITTER_ENABLE_POST_GENERATION || this.runtime.getSetting("TWITTER_ENABLE_POST_GENERATION") ? "disabled" : "enabled"}`
8981
8869
  );
8982
8870
  logger7.log(
8983
8871
  `- Post Interval: ${this.state?.TWITTER_POST_INTERVAL_MIN || this.runtime.getSetting("TWITTER_POST_INTERVAL_MIN")}-${this.state?.TWITTER_POST_INTERVAL_MAX || this.runtime.getSetting("TWITTER_POST_INTERVAL_MAX")} minutes`
@@ -9007,6 +8895,10 @@ var TwitterPostClient = class {
9007
8895
  setTimeout(generateNewTweetLoop, interval);
9008
8896
  };
9009
8897
  setTimeout(generateNewTweetLoop, 60 * 1e3);
8898
+ if (this.runtime.getSetting("TWITTER_POST_IMMEDIATELY")) {
8899
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
8900
+ this.generateNewTweet();
8901
+ }
9010
8902
  }
9011
8903
  /**
9012
8904
  * Creates a Tweet object based on the tweet result, client information, and Twitter username.
@@ -9057,11 +8949,11 @@ var TwitterPostClient = class {
9057
8949
  id: roomId,
9058
8950
  name: "Twitter Feed",
9059
8951
  source: "twitter",
9060
- type: ChannelType5.FEED
8952
+ type: ChannelType6.FEED
9061
8953
  });
9062
8954
  await runtime.ensureParticipantInRoom(runtime.agentId, roomId);
9063
- await runtime.getMemoryManager("messages").createMemory({
9064
- id: createUniqueUuid5(this.runtime, tweet.id),
8955
+ await runtime.createMemory({
8956
+ id: createUniqueUuid6(this.runtime, tweet.id),
9065
8957
  entityId: runtime.agentId,
9066
8958
  agentId: runtime.agentId,
9067
8959
  content: {
@@ -9071,7 +8963,7 @@ var TwitterPostClient = class {
9071
8963
  },
9072
8964
  roomId,
9073
8965
  createdAt: tweet.timestamp
9074
- });
8966
+ }, "messages");
9075
8967
  }
9076
8968
  /**
9077
8969
  * Handles sending a note tweet with optional media data.
@@ -9172,94 +9064,45 @@ var TwitterPostClient = class {
9172
9064
  */
9173
9065
  async generateNewTweet() {
9174
9066
  try {
9175
- logger7.log("Generating new tweet...");
9176
9067
  const userId = this.client.profile?.id;
9177
9068
  if (!userId) {
9178
9069
  logger7.error("Cannot generate tweet: Twitter profile not available");
9179
9070
  return;
9180
9071
  }
9181
- const worldId = createUniqueUuid5(this.runtime, userId);
9182
- const timelineRoomId = createUniqueUuid5(this.runtime, `${userId}-home`);
9183
- const state = await this.runtime.composeState(null, [
9184
- "CHARACTER",
9185
- "RECENT_MESSAGES",
9186
- "TIME"
9187
- ]);
9188
- const tweetPrompt = composePrompt3({
9189
- state,
9190
- template: this.runtime.character.templates?.twitterPostTemplate || twitterPostTemplate
9191
- });
9192
- const response = await this.runtime.useModel(ModelTypes5.TEXT_LARGE, {
9193
- prompt: tweetPrompt
9194
- });
9195
- const jsonResponse = parseJSONObjectFromText(response);
9196
- if (!jsonResponse || !jsonResponse.text) {
9197
- logger7.error("Failed to generate valid tweet content");
9198
- return;
9199
- }
9200
- const cleanedText = this.cleanupTweetText(jsonResponse.text);
9201
- const mediaData = [];
9202
- if (jsonResponse.imagePrompt) {
9203
- try {
9204
- const imagePromptMedia = Array.isArray(jsonResponse.imagePrompt) ? jsonResponse.imagePrompt.map((prompt) => ({
9205
- url: prompt,
9206
- contentType: "image/png"
9207
- })) : [{
9208
- url: jsonResponse.imagePrompt,
9209
- contentType: "image/png"
9210
- }];
9211
- const fetchedMedia = await fetchMediaData(imagePromptMedia);
9212
- mediaData.push(...fetchedMedia);
9213
- } catch (error) {
9214
- logger7.error("Error fetching media for tweet:", error);
9215
- }
9216
- }
9217
- const tweetId = createUniqueUuid5(this.runtime, `tweet-${Date.now()}`);
9218
- const memory = {
9219
- id: tweetId,
9220
- entityId: this.runtime.agentId,
9221
- agentId: this.runtime.agentId,
9222
- roomId: timelineRoomId,
9223
- content: {
9224
- text: cleanedText,
9225
- source: "twitter",
9226
- channelType: ChannelType5.FEED,
9227
- thought: jsonResponse.thought || "",
9228
- plan: jsonResponse.plan || "",
9229
- type: "post"
9230
- },
9231
- createdAt: Date.now()
9232
- };
9072
+ const worldId = createUniqueUuid6(this.runtime, userId);
9073
+ const roomId = createUniqueUuid6(this.runtime, `${userId}-home`);
9233
9074
  const callback = async (content) => {
9234
9075
  try {
9235
9076
  if (this.isDryRun) {
9236
9077
  logger7.info(`[DRY RUN] Would post tweet: ${content.text}`);
9237
9078
  return [];
9238
9079
  }
9239
- const result = await this.postToTwitter(content.text, mediaData);
9080
+ const result = await this.postToTwitter(content.text, content.mediaData);
9081
+ console.log("result is", result);
9082
+ const tweetId = result.rest_id || result.id_str || result.legacy?.id_str;
9240
9083
  if (result) {
9241
- const postedTweetId = createUniqueUuid5(
9084
+ const postedTweetId = createUniqueUuid6(
9242
9085
  this.runtime,
9243
- result.id_str
9086
+ tweetId
9244
9087
  );
9245
9088
  const postedMemory = {
9246
9089
  id: postedTweetId,
9247
9090
  entityId: this.runtime.agentId,
9248
9091
  agentId: this.runtime.agentId,
9249
- roomId: timelineRoomId,
9092
+ roomId,
9250
9093
  content: {
9251
9094
  ...content,
9252
9095
  source: "twitter",
9253
- channelType: ChannelType5.FEED,
9096
+ channelType: ChannelType6.FEED,
9254
9097
  type: "post",
9255
9098
  metadata: {
9256
- tweetId: result.id_str,
9099
+ tweetId,
9257
9100
  postedAt: Date.now()
9258
9101
  }
9259
9102
  },
9260
9103
  createdAt: Date.now()
9261
9104
  };
9262
- await this.runtime.getMemoryManager("messages").createMemory(postedMemory);
9105
+ await this.runtime.createMemory(postedMemory, "messages");
9263
9106
  return [postedMemory];
9264
9107
  }
9265
9108
  return [];
@@ -9268,11 +9111,13 @@ var TwitterPostClient = class {
9268
9111
  return [];
9269
9112
  }
9270
9113
  };
9271
- this.runtime.emitEvent(["TWITTER_POST_GENERATED", "POST_GENERATED"], {
9114
+ console.log("emitting event");
9115
+ this.runtime.emitEvent([EventTypes3.POST_GENERATED, "TWITTER_POST_GENERATED" /* POST_GENERATED */], {
9272
9116
  runtime: this.runtime,
9273
- message: memory,
9274
9117
  callback,
9275
- source: "twitter"
9118
+ worldId,
9119
+ userId,
9120
+ roomId
9276
9121
  });
9277
9122
  } catch (error) {
9278
9123
  logger7.error("Error generating tweet:", error);
@@ -9290,54 +9135,34 @@ var TwitterPostClient = class {
9290
9135
  if (mediaData && mediaData.length > 0) {
9291
9136
  for (const media of mediaData) {
9292
9137
  try {
9293
- const uploadResult = await this.client.requestQueue.add(
9294
- () => this.client.twitterClient.post("media/upload", {
9295
- media_data: Buffer.isBuffer(media.data) ? media.data : Buffer.from(String(media.data).split(",")[1], "base64")
9296
- })
9297
- );
9298
- if (uploadResult && uploadResult.media_id_string) {
9299
- mediaIds.push(uploadResult.media_id_string);
9300
- }
9138
+ logger7.warn("Media upload not currently supported with the modern Twitter API");
9301
9139
  } catch (error) {
9302
9140
  logger7.error("Error uploading media:", error);
9303
9141
  }
9304
9142
  }
9305
9143
  }
9306
- const tweetParams = {
9307
- status: text.substring(0, 280)
9308
- // Twitter's character limit
9309
- };
9310
- if (mediaIds.length > 0) {
9311
- tweetParams.media_ids = mediaIds.join(",");
9312
- }
9313
9144
  const result = await this.client.requestQueue.add(
9314
- () => this.client.twitterClient.post("statuses/update", tweetParams)
9145
+ () => this.client.twitterClient.sendTweet(text.substring(0, 280))
9315
9146
  );
9316
- return result;
9147
+ const body = await result.json();
9148
+ if (!body?.data?.create_tweet?.tweet_results?.result) {
9149
+ logger7.error("Error sending tweet; Bad response:", body);
9150
+ return null;
9151
+ }
9152
+ return body.data.create_tweet.tweet_results.result;
9317
9153
  } catch (error) {
9318
9154
  logger7.error("Error posting to Twitter:", error);
9319
9155
  throw error;
9320
9156
  }
9321
9157
  }
9322
- /**
9323
- * Cleans up a tweet text by removing quotes and fixing newlines
9324
- */
9325
- cleanupTweetText(text) {
9326
- let cleanedText = text.replace(/^['"](.*)['"]$/, "$1");
9327
- cleanedText = cleanedText.replaceAll(/\\n/g, "\n\n");
9328
- if (cleanedText.length > 280) {
9329
- cleanedText = truncateToCompleteSentence(cleanedText, 280);
9330
- }
9331
- return cleanedText;
9332
- }
9333
9158
  async stop() {
9334
9159
  }
9335
9160
  };
9336
9161
 
9337
9162
  // src/tests.ts
9338
9163
  import {
9339
- ModelTypes as ModelTypes6,
9340
- createUniqueUuid as createUniqueUuid6,
9164
+ ModelType as ModelType6,
9165
+ createUniqueUuid as createUniqueUuid7,
9341
9166
  logger as logger8,
9342
9167
  stringToUuid as stringToUuid2
9343
9168
  } from "@elizaos/core";
@@ -9392,7 +9217,7 @@ var TwitterTestSuite = class {
9392
9217
  */
9393
9218
  async testInitializingClient(runtime) {
9394
9219
  try {
9395
- const manager = runtime.getService(ServiceTypes2.TWITTER);
9220
+ const manager = runtime.getService(ServiceType2.TWITTER);
9396
9221
  if (!manager) {
9397
9222
  throw new Error("Twitter client manager not found");
9398
9223
  }
@@ -9494,7 +9319,7 @@ var TwitterTestSuite = class {
9494
9319
  */
9495
9320
  async testPostTweet(runtime) {
9496
9321
  try {
9497
- const roomId = createUniqueUuid6(runtime, "twitter_mock_room");
9322
+ const roomId = createUniqueUuid7(runtime, "twitter_mock_room");
9498
9323
  const postClient = this.twitterClient.post;
9499
9324
  const tweetText = await this.generateRandomTweetContent(runtime);
9500
9325
  await postClient.postTweet(
@@ -9519,7 +9344,7 @@ var TwitterTestSuite = class {
9519
9344
  */
9520
9345
  async testPostImageTweet(runtime) {
9521
9346
  try {
9522
- const roomId = createUniqueUuid6(runtime, "twitter_mock_room");
9347
+ const roomId = createUniqueUuid7(runtime, "twitter_mock_room");
9523
9348
  const postClient = this.twitterClient.post;
9524
9349
  const tweetText = await this.generateRandomTweetContent(
9525
9350
  runtime,
@@ -9585,8 +9410,8 @@ var TwitterTestSuite = class {
9585
9410
  message: {
9586
9411
  content: { text: testTweet.text, source: "twitter" },
9587
9412
  agentId: runtime.agentId,
9588
- entityId: createUniqueUuid6(runtime, testTweet.entityId),
9589
- roomId: createUniqueUuid6(runtime, testTweet.conversationId)
9413
+ entityId: createUniqueUuid7(runtime, testTweet.entityId),
9414
+ roomId: createUniqueUuid7(runtime, testTweet.conversationId)
9590
9415
  },
9591
9416
  thread: []
9592
9417
  });
@@ -9622,7 +9447,7 @@ var TwitterTestSuite = class {
9622
9447
  - A lighthearted take on everyday situations.
9623
9448
  Do not include hashtags or emojis.`;
9624
9449
  }
9625
- return await runtime.useModel(ModelTypes6.TEXT_SMALL, {
9450
+ return await runtime.useModel(ModelType6.TEXT_SMALL, {
9626
9451
  prompt
9627
9452
  });
9628
9453
  }
@@ -9701,7 +9526,7 @@ var _TwitterService = class _TwitterService extends Service {
9701
9526
  const profile = client.client.profile;
9702
9527
  const twitterId = profile.id;
9703
9528
  const username = profile.username;
9704
- const worldId = createUniqueUuid7(runtime, twitterId);
9529
+ const worldId = createUniqueUuid8(runtime, twitterId);
9705
9530
  const world = {
9706
9531
  id: worldId,
9707
9532
  name: `${username}'s Twitter`,
@@ -9718,27 +9543,27 @@ var _TwitterService = class _TwitterService extends Service {
9718
9543
  }
9719
9544
  }
9720
9545
  };
9721
- const homeTimelineRoomId = createUniqueUuid7(runtime, `${twitterId}-home`);
9546
+ const homeTimelineRoomId = createUniqueUuid8(runtime, `${twitterId}-home`);
9722
9547
  const homeTimelineRoom = {
9723
9548
  id: homeTimelineRoomId,
9724
9549
  name: `${username}'s Timeline`,
9725
9550
  source: "twitter",
9726
- type: ChannelType6.FEED,
9551
+ type: ChannelType7.FEED,
9727
9552
  channelId: `${twitterId}-home`,
9728
9553
  serverId: twitterId,
9729
9554
  worldId
9730
9555
  };
9731
- const mentionsRoomId = createUniqueUuid7(runtime, `${twitterId}-mentions`);
9556
+ const mentionsRoomId = createUniqueUuid8(runtime, `${twitterId}-mentions`);
9732
9557
  const mentionsRoom = {
9733
9558
  id: mentionsRoomId,
9734
9559
  name: `${username}'s Mentions`,
9735
9560
  source: "twitter",
9736
- type: ChannelType6.GROUP,
9561
+ type: ChannelType7.GROUP,
9737
9562
  channelId: `${twitterId}-mentions`,
9738
9563
  serverId: twitterId,
9739
9564
  worldId
9740
9565
  };
9741
- const twitterUserId = createUniqueUuid7(runtime, twitterId);
9566
+ const twitterUserId = createUniqueUuid8(runtime, twitterId);
9742
9567
  const twitterUser = {
9743
9568
  id: twitterUserId,
9744
9569
  names: [profile.screenName || username],
@@ -9752,7 +9577,7 @@ var _TwitterService = class _TwitterService extends Service {
9752
9577
  }
9753
9578
  }
9754
9579
  };
9755
- runtime.emitEvent(["TWITTER_WORLD_JOINED" /* WORLD_JOINED */, EventTypes3.WORLD_JOINED], {
9580
+ runtime.emitEvent(["TWITTER_WORLD_JOINED" /* WORLD_JOINED */, EventTypes4.WORLD_JOINED], {
9756
9581
  runtime,
9757
9582
  world,
9758
9583
  rooms: [homeTimelineRoom, mentionsRoom],
@@ -9795,6 +9620,7 @@ var _TwitterService = class _TwitterService extends Service {
9795
9620
  if (config.TWITTER_USERNAME && // Basic auth
9796
9621
  config.TWITTER_PASSWORD && config.TWITTER_EMAIL) {
9797
9622
  logger9.info("Creating default Twitter client from character settings");
9623
+ console.log("runtime is", runtime);
9798
9624
  await twitterClientManager.createClient(
9799
9625
  runtime,
9800
9626
  runtime.agentId,