A small Telegram user-session agent that watches selected chats, keeps recent message history, and uses an OpenAI-compatible local LLM endpoint to decide whether to send a short reply.
The agent is intended for personal automation experiments. It runs as your
Telegram user account through Telethon, waits a randomized delay before replying,
and skips sending when the model returns the configured no_response sentinel.
- Watches one or more configured Telegram contact or chat IDs.
- Loads recent chat history before handling live messages.
- Formats chat history with sender names, IDs, timestamps, and truncated text.
- Uses a local or self-hosted OpenAI-compatible chat completions API.
- Sends delayed replies so responses do not arrive instantly.
- Cancels stale pending replies when newer messages arrive.
- Supports a local profile/context file for style and memory hints.
- Includes pytest coverage for config parsing, formatting, logging, reply scheduling, and LLM response handling.
- Python 3.11 or newer.
- Telegram
api_idandapi_hashfrom my.telegram.org. - An OpenAI-compatible chat completions endpoint, for example a local inference
server exposed at
http://localhost:8000/v1.
Create and activate a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtCreate a local config file:
cp config.example.yaml config.yamlEdit config.yaml with your Telegram credentials:
telegram:
api_id: 123456
api_hash: your-api-hash
contact_ids:
- 100001
- 100002
session_name: my_user_sessionCreate the context file referenced by paths.context. The default example uses
memory.md:
touch memory.mdPut any stable background context, style notes, or memory hints there. The file is sent to the model as reference data together with recent chat history.
The default config.example.yaml contains all supported sections:
telegram:
api_id: null
api_hash: null
contact_ids:
- 100001
- 100002
session_name: my_user_session
history:
limit: 32
message:
max_length: 256
edge_length: 64
timezone: America/Los_Angeles
response_delay:
min_seconds: 60
max_seconds: 480
logging:
level: INFO
root_level: INFO
llm:
api_base: http://localhost:8000/v1
api_key: EMPTY
model: gemma4
max_tokens: 131072
no_response: no_response
enable_thinking: true
paths:
prompt: prompt.txt
context: memory.mdKey settings:
telegram.contact_ids: Telegram users or chats the agent is allowed to watch.history.limit: Number of recent messages loaded per configured contact.response_delay: Random delay window before a reply is generated and sent.llm.api_base: Base URL for an OpenAI-compatible API.llm.no_response: Exact sentinel that means "do not send a message".paths.prompt: System prompt template.{{self_author}}is replaced with the logged-in Telegram account label.paths.context: Local memory/context file included in the model prompt.
Start the agent in the foreground:
source .venv/bin/activate
python -u bot.pyOn first run, Telethon may ask you to complete Telegram login. The session is
stored in the file named by telegram.session_name.
Stop the foreground process with Ctrl-C.
The agent uses standard Python logging.
The default logging.level: INFO logs chat history and live message text. Set
logging.level: DEBUG to also log full model prompts and model responses:
logging:
level: DEBUG
root_level: INFOlogging.level controls this app's loggers. Third-party loggers stay at INFO
by default when app debug logging is enabled, so Telethon debug logs do not flood
the output. Set logging.root_level separately only when needed:
logging:
level: DEBUG
root_level: DEBUGRun the test suite with:
pytestThis project sends messages from your Telegram account. Keep contact_ids
narrow, review prompt.txt and your context file carefully, and test with a
private account or non-critical chat before using it with real contacts.
Do not commit local secrets or session files. config.yaml, session files, logs,
and local memory files should stay private.