Skip to content

Commit 752c24b

Browse files
committed
chore: improve twitter in anda_bot
1 parent dfe9f92 commit 752c24b

File tree

2 files changed

+56
-50
lines changed

2 files changed

+56
-50
lines changed

agents/anda_bot/nitro_enclave/amd64.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ RUN mv linux-amd64/dnsproxy ./ && chmod +x dnsproxy
2626
RUN wget -O ic_tee_nitro_gateway https://github.com/ldclabs/ic-tee/releases/download/v0.2.11/ic_tee_nitro_gateway
2727
RUN chmod +x ic_tee_nitro_gateway
2828

29-
RUN wget -O anda_bot https://github.com/ldclabs/anda/releases/download/v0.2.14/anda_bot
29+
RUN wget -O anda_bot https://github.com/ldclabs/anda/releases/download/v0.2.15/anda_bot
3030
RUN chmod +x anda_bot
3131

3232
FROM --platform=linux/amd64 debian:bookworm-slim AS runtime

agents/anda_bot/src/twitter.rs

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use anda_engine::{
44
context::AgentCtx, engine::Engine, extension::character::CharacterAgent, rand_number,
55
};
66
use anda_lancedb::knowledge::KnowledgeStore;
7-
use log::{debug, error, info};
87
use std::sync::Arc;
98
use tokio::{
109
sync::RwLock,
@@ -42,13 +41,13 @@ impl TwitterDaemon {
4241
}
4342

4443
pub async fn run(&self, cancel_token: CancellationToken) -> Result<(), BoxError> {
45-
info!(target: LOG_TARGET, "starting Twitter bot");
44+
log::info!(target: LOG_TARGET, "starting Twitter bot");
4645

4746
loop {
4847
{
4948
let status = self.status.read().await;
5049
if *status == ServiceStatus::Stopped {
51-
info!(target: LOG_TARGET, "Twitter task stopped");
50+
log::info!(target: LOG_TARGET, "Twitter task stopped");
5251
tokio::select! {
5352
_ = cancel_token.cancelled() => {
5453
return Ok(());
@@ -57,52 +56,47 @@ impl TwitterDaemon {
5756
}
5857
continue;
5958
}
60-
info!(target: LOG_TARGET, "run a Twitter task");
59+
log::info!(target: LOG_TARGET, "run a Twitter task");
6160
// release read lock
6261
}
6362

64-
match rand_number(0..=2) {
65-
0 => {
66-
if let Err(err) = self.post_new_tweet().await {
67-
error!(target: LOG_TARGET, "post_new_tweet error: {err:?}");
68-
}
69-
}
70-
1 => {
71-
if let Err(err) = self.handle_home_timeline().await {
72-
error!(target: LOG_TARGET, "handle_home_timeline error: {err:?}");
73-
}
74-
}
75-
2 => {
76-
match self
77-
.scraper
78-
.search_tweets(
79-
&format!("@{}", self.agent.character.username.clone()),
80-
5,
81-
SearchMode::Latest,
82-
None,
83-
)
84-
.await
85-
{
86-
Ok(mentions) => {
87-
for tweet in mentions.tweets {
88-
if let Err(err) = self.handle_mention(tweet).await {
89-
error!(target: LOG_TARGET, "handle mention error: {err:?}");
90-
}
91-
92-
tokio::select! {
93-
_ = cancel_token.cancelled() => {
94-
return Ok(());
95-
},
96-
_ = sleep(Duration::from_secs(rand_number(3..=10))) => {},
97-
}
98-
}
63+
if let Err(err) = self.handle_home_timeline().await {
64+
log::error!(target: LOG_TARGET, "handle_home_timeline error: {err:?}");
65+
}
66+
67+
match self
68+
.scraper
69+
.search_tweets(
70+
&format!("@{}", self.agent.character.username.clone()),
71+
5,
72+
SearchMode::Latest,
73+
None,
74+
)
75+
.await
76+
{
77+
Ok(mentions) => {
78+
for tweet in mentions.tweets {
79+
if let Err(err) = self.handle_mention(tweet).await {
80+
log::error!(target: LOG_TARGET, "handle mention error: {err:?}");
9981
}
100-
Err(err) => {
101-
error!(target: LOG_TARGET, "fetch mentions error: {err:?}");
82+
83+
tokio::select! {
84+
_ = cancel_token.cancelled() => {
85+
return Ok(());
86+
},
87+
_ = sleep(Duration::from_secs(rand_number(3..=10))) => {},
10288
}
10389
}
10490
}
105-
_ => unreachable!(),
91+
Err(err) => {
92+
log::error!(target: LOG_TARGET, "fetch mentions error: {err:?}");
93+
}
94+
}
95+
96+
if rand_number(0..=9) == 0 {
97+
if let Err(err) = self.post_new_tweet().await {
98+
log::error!(target: LOG_TARGET, "post_new_tweet error: {err:?}");
99+
}
106100
}
107101

108102
// Sleep between tasks
@@ -120,6 +114,8 @@ impl TwitterDaemon {
120114
if knowledges.is_empty() {
121115
return Ok(());
122116
}
117+
118+
log::info!(target: LOG_TARGET, "post new tweet with {} knowledges", knowledges.len());
123119
let ctx = self.engine.ctx_with(
124120
self.agent.as_ref(),
125121
Some(self.agent.character.username.clone()),
@@ -143,6 +139,10 @@ impl TwitterDaemon {
143139
Some(reason) => Err(format!("Failed to generate response for tweet: {reason}").into()),
144140
None => {
145141
let _ = self.scraper.send_tweet(&res.content, None, None).await?;
142+
log::info!(target: LOG_TARGET,
143+
"post new tweet: {}",
144+
res.content.chars().take(100).collect::<String>()
145+
);
146146
Ok(())
147147
}
148148
}
@@ -155,8 +155,11 @@ impl TwitterDaemon {
155155
Some(self.agent.character.username.clone()),
156156
None,
157157
)?;
158-
debug!(target: LOG_TARGET, "process home timeline, {} tweets", tweets.len());
158+
log::info!(target: LOG_TARGET, "process home timeline, {} tweets", tweets.len());
159159

160+
let mut likes = 0;
161+
let mut retweets = 0;
162+
let mut quotes = 0;
160163
for tweet in tweets {
161164
let tweet_user = tweet["core"]["user_results"]["result"]["legacy"]["screen_name"]
162165
.as_str()
@@ -192,15 +195,19 @@ impl TwitterDaemon {
192195
.await;
193196

194197
if self.handle_like(&ctx, &tweet_content, &tweet_id).await? {
198+
likes += 1;
195199
if self.handle_quote(&ctx, &tweet_content, &tweet_id).await? {
196200
// TODO: save tweet to knowledge store
201+
quotes += 1;
197202
} else {
198203
self.handle_retweet(&ctx, &tweet_content, &tweet_id).await?;
204+
retweets += 1;
199205
}
200206
}
201207

202208
sleep(Duration::from_secs(rand_number(1..=10))).await;
203209
}
210+
log::info!(target: LOG_TARGET, "home timeline: likes {}, retweets {}, quotes {}", likes, retweets, quotes);
204211
Ok(())
205212
}
206213

@@ -217,12 +224,13 @@ impl TwitterDaemon {
217224
}
218225
let ctx = self
219226
.engine
220-
.ctx_with(self.agent.as_ref(), Some(tweet_user), None)?;
227+
.ctx_with(self.agent.as_ref(), Some(tweet_user.clone()), None)?;
221228

222229
let handle_key = format!("D_{}", tweet_id);
223230
if ctx.cache_contains(&handle_key) {
224231
return Ok(());
225232
}
233+
226234
ctx.cache_set(
227235
&handle_key,
228236
(
@@ -266,15 +274,13 @@ impl TwitterDaemon {
266274
.collect();
267275

268276
// Reply to the original tweet
269-
let tweet_id: Option<&str> = tweet.id.as_deref();
277+
let tweet: Option<&str> = tweet.id.as_deref();
270278
for chunk in &chunks {
271-
let _ = self
272-
.scraper
273-
.send_tweet(chunk.as_str(), tweet_id, None)
274-
.await?;
279+
let _ = self.scraper.send_tweet(chunk.as_str(), tweet, None).await?;
275280
sleep(Duration::from_secs(rand_number(1..=3))).await;
276281
}
277282

283+
log::info!(target: LOG_TARGET, "handle mention: {} - {}, {} chunks", tweet_user, tweet_id, chunks.len());
278284
Ok(())
279285
}
280286

0 commit comments

Comments
 (0)