Skip to content

BlankAdventure/acrobot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

212 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About The Project

Acrobot is a telegram bot that participates in your chat groups generating fun, creative acronyms (*technically expansions for acronyms) based on the conversation. It can be triggered on certain keywords or directly via the /acro command (see usage). The acronyms are generated via an LLM with an internally-built prompt. It can be run in polling mode or webhook mode with FastAPI and uvicorn.

Prerequisites

Telegram API

  1. You'll need a bot API key from telegram: (https://core.telegram.org/bots/tutorial#getting-ready).
  2. Add a TELEGRAM_API_KEY environment variable and assign it the key value obtained above.

LLM API

  1. Acrobot provides built-in support for Gemini and Cerebras models. To use them, you will need an API key from Gemini and/or Cerebras.
  2. For Gemini, add a GOOGLE_API_KEY environment variable and set it your Gemini API key.
  3. For Cerebras, add a CEREBRAS_API_KEY environment variable and set it to your Cerebras key.

For now, acrobot is only able to access keys via these environment variables. Alternate methods (commmand line, config file) will be added in a future release.

Installation

  1. Clone (or download) the repo: git clone https://github.com/BlankAdventure/acrobot.git
  2. Install locally via pip: pip install . -e
  3. Or with uv, navigate to acrobot and run: uv sync

Running It

Acrobot can be run in either polling mode, webhook mode, or a test mode as described below.

Polling Mode

In polling mode, the code runs a loop polling the telegram API periodically for new chat updates. It is straightforward to launch, in one of two ways:

  1. If installed, simply run the CLI command: acrobot polling
  2. Otherwise, navigate to acrobot\acrobot and run: python -m runner.py polling

Webhook Mode

In webhhok mode, a running http server is required to handle POST requests originating from the telegram server. Acrobot will handle launching a uvicorn server instance when this mode is invoked. Telegram must be provided with a webhook address, that is, an https url to send chat updates to.

  1. If installed, run the CLI command: acrobot webhook -p <PORT> -a [IP_ADDR] -w [WEBHOOK_URL]
  2. Otherwise, navigate to acrobot\acrobot and run: python -m runner.py webhook -p <PORT> -a [IP_ADDR] -w [WEBHOOK_URL]

If running locally, ngrok can be used to obtain an https forwarding url. In this case, you would substitute WEBHOOK_URL for the provided ngrok url and PORT with your chosen port. IP_ADDR can (usually) be set to 0.0.0.0.

Note that webhook mode is preferred over polling as it only induces network traffic when updates are actually available.

CLI/Test Mode

You can generate one-off acronyms directly from the command line, without telegram, as follows:

acrobot test "word" [config_name]

where config_name can be any model config block specified in the config.yaml file. If unset, it defaults to the use_config block. This can be useful for quick tests when trying new models/settings.

Quick summary of CLI options:

Command Description
acrobot polling Launch Acrobot in polling mode.
acrobot webhook -p <PORT> -a [IP_ADDR] -w [WEBHOOK_URL] Launch Acrobot in webhook mode.
acrobot test "word" [config_name] Generate one-off acronym for "word".

Usage

IMPORTANT! Don't forget to add the bot to your chat - remember you named it back when you obtained your telegram bot API key.

Acronym generation can be triggered in three ways:

  1. Detecting a keyword appearing in the chat (this can be configured).
  2. If invoked via @acro, it will pick a random word from the conversation history.
  3. Directly via the command: /acro word -> "wonderful oils require drinking"
Command Description
@acro Generates an acronym from a random word in the conversation history.
@acro /acro word Generate an acronym (technically an expansion) for the word.
@acro /add_keyword keyword1 keyword2 keyword3 ... Add keywords to the trigger list.
@acro /del_keyword keyword1 keyword2 keyword3 ... Remove keywords from the trigger list.
@acro /set config_name Set the LLM model to use config_name, a config block in config.yaml file. This command can be useful for experimenting with different settings, or swapping models if you (e.g.,) hit a usage limit.
@acro /add_message username add this message! Add a fake message to the chat context. This can be fun for secretly steering the bot's responses in a particular direction.

Note that the @acro prefix can be removed if its the only bot in the channel.

Settings / Configuration

A number of basic settings can be modified by the user via the /acrobot/acrobot/config.yaml file. They are largely self-explanatory - see the file for details. Additionally, the optional environment variable ACROBOT_CONFIG_YAML may be used to point to a custom file. A file path or URL may be specified.

Models

The code includes support for Gemini and Cerebras models (though not necessarily all model configuration options are exposed). Custom models can be provided by inheriting from the models.Model ABC class:

from acrobot.models import Model

class Custom(Model):
    def __init__(self, x=0, y=0):
        self.x=x
        self.y=y
    def generate_response(self, prompt:str) -> str:            
        ...

Or dataclasses can be used instead:

from dataclasses import dataclass
from acrobot.models import Model

@dataclass
class Custom(Model):
    x: int = 0
    y: int = 0
    def generate_response(self, prompt:str) -> str:            
        ...

A special @catch decorator is provided to enable relaying a message to the chat should a specified exception occur. For example, if AnException occurs, it will be caught, logged, and "hey you broke something" will be posted to the chat. The decorator can be applied multiple times.

    @catch(ADifferentException, "hey you broke something else!")
    @catch(AnException, "hey you broke something!")
    def generate_response(self, prompt:str) -> str:            
        ...

To invoke your model, add a custom configuration block to config.yaml:

model:
    use_config: custom # This must match a configuration block below.

# model config block
custom: 
    provider: Custom # name of class
    x: 10
    y: 20

When acrobat is started, it will simply pass any fields listed under custom (in this case x and y) into your model as kwargs.

Roadmap

(in no particular order)

  • Beautify this readme
  • Option to auto-swap models in case of API errors (time-outs, rate limits, etc)
  • Use protocol instead of inheritance for model plug-in system
  • Streamline app configuration handling:
    • Provide API keys via command line, config file, or environment variables
    • Consolidate settings in one location
  • Improve logging:
    • Log token usage / total API calls
    • Log to file or other data sink
  • Implement LLM 'referee' to review acronym quality
  • Use tenacity for retry logic
  • Move exception-handling to async event loop (prevent crashes; provide in-chat feedback)
  • Add CLI entry point for acronym generation (useful for sanity checking)
  • Allow in-chat model switching
  • Specify optional path/url for alternate yaml file via environment variable
  • Add testing for config.py

About

Telegram acronym chatbot featuring Gemini and Cerebras models

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages