Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions src/agent/agent_tools/twitter/twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import tweepy
from pprint import pformat
from .twitter_config import TwitterConfig
from .twitter_utils import with_rate_limit_handling

logger = logging.getLogger(__name__)
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)
Expand Down Expand Up @@ -82,9 +83,25 @@ def __init__(

def run(self):
def job():
self.respond_to_key_users()
# Only respond if RESPOND_MODE is enabled
if getattr(self.config, 'RESPOND_MODE', True):
self.respond_to_key_users()

# Post if POST_MODE is enabled
if self.config.POST_MODE:
self.post_tweet()
try:
# Generate post text
post_text = self.model.query(self.config.POST_PROMPT)
logging.info(f"[TWITTER] Generated post: {post_text}")

# Post the tweet
result, tweet_id = self.post_tweet(post_text)
if result:
logging.info(f"[TWITTER] Successfully posted tweet with ID: {tweet_id}")
else:
logging.error("[TWITTER] Failed to post tweet")
except Exception as e:
logging.exception(f"[TWITTER] Error in posting tweet: {e}")

job()

Expand Down Expand Up @@ -115,7 +132,7 @@ def __build_search_query_ignore_quotes(self):
"""Returns a twitter search query that ignores quotes"""
return " -is:quote"


@with_rate_limit_handling
def __search_for_relevant_conversations(self, start_time=None):
"""
Gets tweets from key users or from specific conversations.
Expand Down
6 changes: 5 additions & 1 deletion src/agent/agent_tools/twitter/twitter_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
class TwitterConfig:
def __init__(self):

# Set this to False to disable responding to tweets
self.RESPOND_MODE = False

# Agent will respond to tweets from these users every time that it runs
self.KEY_USERS = []

Expand All @@ -25,4 +29,4 @@ def __init__(self):
self.RESPONSES_PER_RUN = 1

# Agent will run this number of times per day
self.RUNS_PER_DAY = 12
self.RUNS_PER_DAY = 4
34 changes: 34 additions & 0 deletions src/agent/agent_tools/twitter/twitter_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import time
import logging
from tweepy.errors import TooManyRequests, TwitterServerError

def with_rate_limit_handling(func):
"""Decorator to handle Twitter API rate limits with exponential backoff"""
def wrapper(*args, **kwargs):
max_retries = 5
retry_count = 0
base_wait_time = 60 # seconds

while True:
try:
return func(*args, **kwargs)
except TooManyRequests as e:
retry_count += 1
if retry_count > max_retries:
logging.error(f"[TWITTER] Maximum retries exceeded. Giving up after {max_retries} attempts.")
raise e

# Calculate wait time with exponential backoff
wait_time = base_wait_time * (2 ** (retry_count - 1))
logging.warning(f"[TWITTER] Rate limit reached. Waiting {wait_time} seconds before retry {retry_count}/{max_retries}.")
time.sleep(wait_time)
except TwitterServerError as e:
retry_count += 1
if retry_count > max_retries:
logging.error(f"[TWITTER] Maximum retries exceeded. Giving up after {max_retries} attempts.")
raise e

wait_time = base_wait_time
logging.warning(f"[TWITTER] Twitter server error. Waiting {wait_time} seconds before retry {retry_count}/{max_retries}.")
time.sleep(wait_time)
return wrapper