11use agent_twitter_client:: { models:: Tweet , scraper:: Scraper , search:: SearchMode } ;
22use anda_core:: { Agent , BoxError , CompletionFeatures , StateFeatures } ;
33use anda_engine:: {
4- context:: { AgentCtx , CacheStoreFeatures , ANONYMOUS } ,
5- engine:: Engine ,
4+ context:: { ANONYMOUS , AgentCtx , CacheStoreFeatures } ,
5+ engine:: { Engine , NAME } ,
66 extension:: character:: CharacterAgent ,
77 rand_number,
88} ;
99use anda_lancedb:: knowledge:: KnowledgeStore ;
1010use std:: sync:: Arc ;
1111use tokio:: {
1212 sync:: RwLock ,
13- time:: { sleep , Duration } ,
13+ time:: { Duration , sleep } ,
1414} ;
1515use tokio_util:: sync:: CancellationToken ;
1616
@@ -146,7 +146,7 @@ impl TwitterDaemon {
146146 let ctx = self . engine . ctx_with (
147147 & self . agent . as_ref ( ) . name ( ) ,
148148 ANONYMOUS ,
149- Some ( self . agent . character . username . clone ( ) ) ,
149+ Some ( NAME . to_string ( ) ) ,
150150 ) ?;
151151 let req = self
152152 . agent
@@ -157,7 +157,7 @@ impl TwitterDaemon {
157157 Be direct and concise. No questions, hashtags, or emojis.\
158158 "
159159 . to_string ( ) ,
160- ctx . user ( ) ,
160+ Some ( NAME . to_string ( ) ) ,
161161 )
162162 . append_documents ( knowledges. into ( ) ) ;
163163 let res = ctx. completion ( req) . await ?;
@@ -301,9 +301,11 @@ impl TwitterDaemon {
301301 let res = self . agent . run ( ctx. clone ( ) , tweet_text, None ) . await ?;
302302 if res. failed_reason . is_none ( ) {
303303 // Reply to the original tweet
304- let tweet: Option < & str > = tweet. id . as_deref ( ) ;
305304 let content = remove_quotes ( res. content ) ;
306- let _ = self . scraper . send_tweet ( & content, tweet, None ) . await ?;
305+ let _ = self
306+ . scraper
307+ . send_tweet ( & content, Some ( & tweet_id) , None )
308+ . await ?;
307309
308310 log:: info!(
309311 tweet_user = tweet_user,
@@ -368,40 +370,37 @@ impl TwitterDaemon {
368370 tweet_content : & str ,
369371 tweet_id : & str ,
370372 ) -> Result < bool , BoxError > {
371- if self
373+ let req = self
372374 . agent
373- . attention
374- . should_retweet ( ctx, tweet_content)
375- . await
376- {
377- let req = self
378- . agent
379- . character
380- . to_request (
381- "\
382- Reply the tweet with a single clear, natural sentence. No hashtags.\
383- "
384- . to_string ( ) ,
385- ctx. user ( ) ,
386- )
387- . context (
388- tweet_id. to_string ( ) ,
389- format ! ( "Tweet content:\n {tweet_content}" ) ,
390- ) ;
391- let res = ctx. completion ( req) . await ?;
392- match res. failed_reason {
393- Some ( reason) => {
394- return Err ( format ! ( "Failed to generate response for tweet: {reason}" ) . into ( ) ) ;
395- }
396- None => {
375+ . character
376+ . to_request (
377+ format ! ( "\
378+ Respond the tweet AS **{}** would - only reply if your persona deems it necessary. When engaging:\n \
379+ 1. Use your character's unique voice and communication style naturally\n \
380+ 2. Keep responses to one authentic-sentence without hashtags\n \
381+ 3. Return empty if your persona wouldn't respond to this tweet\n \n \
382+ ## Tweet Content:\n {:?}\
383+ ", self . agent. character. name, tweet_content) ,
384+ Some ( NAME . to_string ( ) ) ,
385+ ) ;
386+
387+ let res = ctx. completion ( req) . await ?;
388+ match res. failed_reason {
389+ Some ( reason) => {
390+ return Err ( format ! ( "Failed to generate response for tweet: {reason}" ) . into ( ) ) ;
391+ }
392+ None => {
393+ let content = remove_quotes ( res. content ) ;
394+ if !content. is_empty ( ) {
397395 let _ = self
398396 . scraper
399- . send_tweet ( & remove_quotes ( res . content ) , Some ( tweet_id) , None )
397+ . send_tweet ( & content, Some ( tweet_id) , None )
400398 . await ?;
401399 return Ok ( true ) ;
402400 }
403401 }
404402 }
403+
405404 Ok ( false )
406405 }
407406
@@ -411,30 +410,31 @@ impl TwitterDaemon {
411410 tweet_content : & str ,
412411 tweet_id : & str ,
413412 ) -> Result < bool , BoxError > {
414- if self . agent . attention . should_quote ( ctx, tweet_content) . await {
415- let req = self
416- . agent
417- . character
418- . to_request (
419- "\
420- Quote the tweet with a single clear, natural sentence. No hashtags.\
421- "
422- . to_string ( ) ,
423- ctx. user ( ) ,
424- )
425- . context (
426- tweet_id. to_string ( ) ,
427- format ! ( "Tweet content:\n {tweet_content}" ) ,
428- ) ;
429- let res = ctx. completion ( req) . await ?;
430- match res. failed_reason {
431- Some ( reason) => {
432- return Err ( format ! ( "Failed to generate response for tweet: {reason}" ) . into ( ) ) ;
433- }
434- None => {
413+ let req = self
414+ . agent
415+ . character
416+ . to_request (
417+ format ! ( "\
418+ Respond the tweet AS **{}** would - only reply if your persona deems it necessary. When engaging:\n \
419+ 1. Use your character's unique voice and communication style naturally\n \
420+ 2. Keep responses to one authentic-sentence without hashtags\n \
421+ 3. Return empty if your persona wouldn't respond to this tweet\n \n \
422+ ## Tweet Content:\n {:?}\
423+ ", self . agent. character. name, tweet_content) ,
424+ Some ( NAME . to_string ( ) ) ,
425+ ) ;
426+
427+ let res = ctx. completion ( req) . await ?;
428+ match res. failed_reason {
429+ Some ( reason) => {
430+ return Err ( format ! ( "Failed to generate response for tweet: {reason}" ) . into ( ) ) ;
431+ }
432+ None => {
433+ let content = remove_quotes ( res. content ) ;
434+ if !content. is_empty ( ) {
435435 let _ = self
436436 . scraper
437- . send_quote_tweet ( & remove_quotes ( res . content ) , tweet_id, None )
437+ . send_tweet ( & content, Some ( tweet_id) , None )
438438 . await ?;
439439 return Ok ( true ) ;
440440 }
0 commit comments