You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

bot.py 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import os
  2. import logging
  3. import logging.handlers
  4. import discord
  5. from discord.ext import commands
  6. from agent_utils import solve_task
  7. logger = logging.getLogger("anny")
  8. logger.setLevel(logging.INFO)
  9. logging.getLogger("discord.http").setLevel(logging.INFO)
  10. handler = logging.handlers.RotatingFileHandler(
  11. filename="autoanny.log",
  12. encoding="utf-8",
  13. maxBytes=32 * 1024 * 1024, # 32 MiB
  14. backupCount=5, # Rotate through 5 files
  15. )
  16. dt_fmt = "%Y-%m-%d %H:%M:%S"
  17. formatter = logging.Formatter("[{asctime}] [{levelname:<8}] {name}: {message}", dt_fmt, style="{")
  18. handler.setFormatter(formatter)
  19. logger.addHandler(handler)
  20. required_env_vars = ["OAI_CONFIG_LIST", "DISCORD_TOKEN", "GH_TOKEN", "ANNY_GH_REPO"]
  21. for var in required_env_vars:
  22. if var not in os.environ:
  23. raise ValueError(f"{var} environment variable is not set.")
  24. # read token from environment variable
  25. DISCORD_TOKEN = os.environ["DISCORD_TOKEN"]
  26. REPO = os.environ["ANNY_GH_REPO"]
  27. intents = discord.Intents.default()
  28. intents.message_content = True
  29. intents.reactions = True
  30. bot = commands.Bot(command_prefix="/", intents=intents)
  31. @bot.event
  32. async def on_message(message):
  33. logger.info({"message": message.content, "author": message.author, "id": message.id})
  34. await bot.process_commands(message)
  35. @bot.event
  36. async def on_reaction_add(reaction, user):
  37. message = reaction.message
  38. logger.info(
  39. {
  40. "message": message.content,
  41. "author": message.author,
  42. "id": message.id,
  43. "reaction": reaction.emoji,
  44. "reactor": user,
  45. }
  46. )
  47. @bot.event
  48. async def on_ready():
  49. logger.info("Logged in", extra={"user": bot.user})
  50. @bot.command(description="Invoke Anny to solve a task.")
  51. async def heyanny(ctx, task: str = None):
  52. if not task or task == "help":
  53. response = help_msg()
  54. await ctx.send(response)
  55. return
  56. task_map = {
  57. "ghstatus": ghstatus,
  58. "ghgrowth": ghgrowth,
  59. "ghunattended": ghunattended,
  60. "ghstudio": ghstudio,
  61. }
  62. if task in task_map:
  63. await ctx.send("Working on it...")
  64. response = await task_map[task](ctx)
  65. await ctx.send(response)
  66. else:
  67. response = "Invalid command! Please type /heyanny help for the list of commands."
  68. await ctx.send(response)
  69. def help_msg():
  70. response = f"""
  71. Hi this is Anny an AutoGen-powered Discord bot to help with `{REPO}`. I can help you with the following tasks:
  72. - ghstatus: Find the most recent issues and PRs from today.
  73. - ghgrowth: Find the number of stars, forks, and indicators of growth.
  74. - ghunattended: Find the most issues and PRs from today from today that haven't received a response/comment.
  75. You can invoke me by typing `/heyanny <task>`.
  76. """
  77. return response
  78. async def ghstatus(ctx):
  79. response = await solve_task(
  80. f"""
  81. Find the most recent issues and PRs from `{REPO}` in last 24 hours.
  82. Separate issues and PRs.
  83. Final response should contains title, number, date/time, URLs of the issues and PRs.
  84. Markdown formatted response will make it look nice.
  85. Make sure date/time is in PST and readily readable.
  86. You can access github token from the environment variable called GH_TOKEN.
  87. """
  88. )
  89. return response
  90. async def ghgrowth(ctx):
  91. response = await solve_task(
  92. f"""
  93. Find the number of stars, forks, and indicators of growth of `{REPO}`.
  94. Compare the stars of `{REPO}` this week vs last week.
  95. Make sure date/time is in PST and readily readable.
  96. You can access github token from the environment variable called GH_TOKEN.
  97. """
  98. )
  99. return response
  100. async def ghunattended(ctx):
  101. response = await solve_task(
  102. f"""
  103. Find the issues *created* in the last 24 hours from `{REPO}` that haven't
  104. received a response/comment. Modified issues don't count.
  105. Final response should contains title, number, date/time, URLs of the issues and PRs.
  106. Make sure date/time is in PST and readily readable.
  107. You can access github token from the environment variable called GH_TOKEN.
  108. """
  109. )
  110. return response
  111. async def ghstudio(ctx):
  112. # TODO: Generalize to feature name
  113. response = await solve_task(
  114. f"""
  115. Find issues and PRs from `{REPO}` that are related to the AutoGen Studio.
  116. The title or the body of the issue or PR should give you a hint whether its related.
  117. Summarize the top 5 common complaints or issues. Cite the issue/PR number and URL.
  118. Explain why you think this is a common issue in 2 sentences.
  119. You can access github token from the environment variable called GH_TOKEN.
  120. """
  121. )
  122. return response
  123. bot.run(DISCORD_TOKEN, log_handler=None)