@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 +303 -477
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import {
|
|
3
|
-
ChannelType as
|
|
4
|
-
EventTypes as
|
|
3
|
+
ChannelType as ChannelType7,
|
|
4
|
+
EventTypes as EventTypes4,
|
|
5
5
|
Role,
|
|
6
6
|
Service,
|
|
7
|
-
createUniqueUuid as
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3679
|
-
const res = await
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
|
7677
|
-
createUniqueUuid as
|
|
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
|
|
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
|
|
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.
|
|
7959
|
+
const existingMemories2 = await this.runtime.getMemoriesByRoomIds({
|
|
7960
|
+
tableName: "messages",
|
|
8020
7961
|
roomIds: cachedTimeline.map(
|
|
8021
|
-
(tweet) =>
|
|
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(
|
|
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(
|
|
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
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
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:
|
|
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 ?
|
|
8018
|
+
inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid4(this.runtime, tweet.inReplyToStatusId) : void 0
|
|
8057
8019
|
};
|
|
8058
|
-
|
|
8059
|
-
|
|
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(
|
|
8048
|
+
roomIds.add(createUniqueUuid4(this.runtime, tweet.conversationId));
|
|
8093
8049
|
}
|
|
8094
|
-
const existingMemories = await this.runtime.
|
|
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(
|
|
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
|
|
8112
|
-
|
|
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:
|
|
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 ?
|
|
8106
|
+
inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid4(this.runtime, tweet.inReplyToStatusId) : void 0
|
|
8126
8107
|
};
|
|
8127
|
-
await this.runtime.
|
|
8128
|
-
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.
|
|
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.
|
|
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
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
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
|
|
8243
|
-
id:
|
|
8244
|
-
type:
|
|
8245
|
-
userId:
|
|
8246
|
-
username:
|
|
8247
|
-
name:
|
|
8248
|
-
targetTweetId:
|
|
8249
|
-
targetTweet:
|
|
8250
|
-
quoteTweet:
|
|
8251
|
-
retweetId:
|
|
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
|
|
8251
|
+
ChannelType as ChannelType5,
|
|
8342
8252
|
EventTypes as EventTypes2,
|
|
8343
|
-
|
|
8253
|
+
ModelType as ModelType4,
|
|
8344
8254
|
composePrompt as composePrompt2,
|
|
8345
|
-
createUniqueUuid as
|
|
8255
|
+
createUniqueUuid as createUniqueUuid5,
|
|
8346
8256
|
logger as logger6
|
|
8347
8257
|
} from "@elizaos/core";
|
|
8348
8258
|
|
|
8349
8259
|
// src/types.ts
|
|
8350
|
-
var
|
|
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 =
|
|
8421
|
-
const existingResponse = await this.runtime.
|
|
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
|
|
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:
|
|
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
|
|
8441
|
-
|
|
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
|
-
...
|
|
8457
|
-
|
|
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
|
-
...
|
|
8474
|
-
|
|
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.
|
|
8464
|
+
await this.runtime.createMemory(memory, "messages");
|
|
8532
8465
|
const reactionMessage = {
|
|
8533
|
-
id:
|
|
8466
|
+
id: createUniqueUuid5(this.runtime, interaction.targetTweetId),
|
|
8534
8467
|
content: {
|
|
8535
8468
|
text: interaction.targetTweet.text,
|
|
8536
8469
|
source: "twitter"
|
|
8537
8470
|
},
|
|
8538
|
-
entityId:
|
|
8539
|
-
roomId:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
8737
|
-
const tweetExists = await this.runtime.
|
|
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 =
|
|
8741
|
-
const roomId =
|
|
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:
|
|
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:
|
|
8653
|
+
type: ChannelType5.GROUP,
|
|
8755
8654
|
channelId: tweet.conversationId,
|
|
8756
|
-
worldId:
|
|
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 ?
|
|
8664
|
+
inReplyTo: tweet.inReplyToStatusId ? createUniqueUuid5(this.runtime, tweet.inReplyToStatusId) : void 0,
|
|
8766
8665
|
source: "twitter",
|
|
8767
|
-
channelType:
|
|
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(
|
|
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 =
|
|
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.
|
|
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.
|
|
8764
|
+
const memory = await this.runtime.getMemoryById(createUniqueUuid5(this.runtime, currentTweet.id));
|
|
8866
8765
|
if (!memory) {
|
|
8867
|
-
const roomId =
|
|
8868
|
-
const entityId =
|
|
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:
|
|
8774
|
+
type: ChannelType5.GROUP
|
|
8876
8775
|
});
|
|
8877
|
-
this.runtime.
|
|
8878
|
-
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 ?
|
|
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 :
|
|
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:
|
|
8830
|
+
id: createUniqueUuid5(this.runtime, id),
|
|
8932
8831
|
agentId: this.runtime.agentId,
|
|
8933
|
-
entityId:
|
|
8934
|
-
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
|
|
8947
|
-
|
|
8948
|
-
|
|
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
|
-
`-
|
|
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:
|
|
8952
|
+
type: ChannelType6.FEED
|
|
9061
8953
|
});
|
|
9062
8954
|
await runtime.ensureParticipantInRoom(runtime.agentId, roomId);
|
|
9063
|
-
await runtime.
|
|
9064
|
-
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 =
|
|
9182
|
-
const
|
|
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 =
|
|
9084
|
+
const postedTweetId = createUniqueUuid6(
|
|
9242
9085
|
this.runtime,
|
|
9243
|
-
|
|
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
|
|
9092
|
+
roomId,
|
|
9250
9093
|
content: {
|
|
9251
9094
|
...content,
|
|
9252
9095
|
source: "twitter",
|
|
9253
|
-
channelType:
|
|
9096
|
+
channelType: ChannelType6.FEED,
|
|
9254
9097
|
type: "post",
|
|
9255
9098
|
metadata: {
|
|
9256
|
-
tweetId
|
|
9099
|
+
tweetId,
|
|
9257
9100
|
postedAt: Date.now()
|
|
9258
9101
|
}
|
|
9259
9102
|
},
|
|
9260
9103
|
createdAt: Date.now()
|
|
9261
9104
|
};
|
|
9262
|
-
await this.runtime.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
9145
|
+
() => this.client.twitterClient.sendTweet(text.substring(0, 280))
|
|
9315
9146
|
);
|
|
9316
|
-
|
|
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
|
-
|
|
9340
|
-
createUniqueUuid as
|
|
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(
|
|
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 =
|
|
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 =
|
|
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:
|
|
9589
|
-
roomId:
|
|
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(
|
|
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 =
|
|
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 =
|
|
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:
|
|
9551
|
+
type: ChannelType7.FEED,
|
|
9727
9552
|
channelId: `${twitterId}-home`,
|
|
9728
9553
|
serverId: twitterId,
|
|
9729
9554
|
worldId
|
|
9730
9555
|
};
|
|
9731
|
-
const mentionsRoomId =
|
|
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:
|
|
9561
|
+
type: ChannelType7.GROUP,
|
|
9737
9562
|
channelId: `${twitterId}-mentions`,
|
|
9738
9563
|
serverId: twitterId,
|
|
9739
9564
|
worldId
|
|
9740
9565
|
};
|
|
9741
|
-
const twitterUserId =
|
|
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 */,
|
|
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,
|