manolo-bot 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Carlos Cesar Caballero Díaz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,421 @@
1
+ Metadata-Version: 2.4
2
+ Name: manolo-bot
3
+ Version: 0.1.0
4
+ Summary: AI-powered Telegram Chat Bot and Library using LLMs
5
+ Author-email: Carlos Cesar Caballero Díaz <ccesarcaball.cc@gmail.com>
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: aiohttp>=3.11.11
10
+ Requires-Dist: aiogram>=3.17.0
11
+ Requires-Dist: beautifulsoup4>=4.13.3
12
+ Requires-Dist: ddgs>=9.6.0
13
+ Requires-Dist: envmodel>=0.2
14
+ Requires-Dist: google-generativeai>=0.8.4
15
+ Requires-Dist: langchain>=0.3.20
16
+ Requires-Dist: langchain-community>=0.3.19
17
+ Requires-Dist: langchain-core>=0.3.52
18
+ Requires-Dist: langchain-google-genai>=2.0.10
19
+ Requires-Dist: langchain-mcp-adapters>=0.1.4
20
+ Requires-Dist: langchain-ollama>=0.2.3
21
+ Requires-Dist: langchain-openai>=0.3.8
22
+ Requires-Dist: langgraph>=0.5.4
23
+ Requires-Dist: mcp>=1.3.1
24
+ Requires-Dist: pillow>=11.1.0
25
+ Requires-Dist: python-dotenv>=1.0.1
26
+ Requires-Dist: telegramify-markdown[mermaid]>=0.5.1
27
+ Requires-Dist: transformers>=4.53.0
28
+ Requires-Dist: youtube-transcript-api>=1.1.1
29
+ Requires-Dist: langchain-tavily>=0.2.17
30
+ Requires-Dist: html2text>=2025.4.15
31
+ Provides-Extra: docs
32
+ Requires-Dist: sphinx>=9.1.0; extra == "docs"
33
+ Requires-Dist: sphinx-rtd-theme>=3.1.0; extra == "docs"
34
+ Requires-Dist: myst-parser>=5.1.0; extra == "docs"
35
+ Requires-Dist: sphinx-autodoc-typehints>=3.10.3; extra == "docs"
36
+ Dynamic: license-file
37
+
38
+ # manolo-bot: AI-powered Telegram Chat Bot and Library
39
+
40
+ [![Documentation Status](https://readthedocs.org/projects/manolo-bot/badge/?version=latest)](https://manolo-bot.readthedocs.io/en/latest/?badge=latest)
41
+
42
+ `manolo-bot` is an AI-powered Telegram Chat Bot and Library built with Python, leveraging modern LLM frameworks and the
43
+ Model Context Protocol (MCP).
44
+ It is designed to be both a standalone application and a reusable library for building your own AI-powered bots.
45
+
46
+ ## Documentation
47
+
48
+ Full documentation is available at [https://manolo-bot.readthedocs.io/](https://manolo-bot.readthedocs.io/)
49
+
50
+ ## Installation
51
+
52
+ ### From PyPI (Recommended)
53
+
54
+ You can install `manolo-bot` directly from PyPI:
55
+
56
+ ```shell
57
+ pip install manolo-bot
58
+ ```
59
+
60
+ ### From Source
61
+
62
+ If you want to run the bot from the source code, you need to install the required packages using [uv](https://docs.astral.sh/uv/):
63
+
64
+ ```shell
65
+ uv sync --no-dev
66
+ ```
67
+
68
+ ## Configuration
69
+
70
+ You can copy and rename the provided `env.example` to `.env` and edit the file according to your data
71
+
72
+ You can create a bot on Telegram and get its API token by following
73
+ the [official instructions](https://core.telegram.org/bots#how-do-i-create-a-bot).
74
+
75
+ To use the bot in a group, you have to use the @BotFather bot
76
+ to [set the Group Privacy off](https://stackoverflow.com/questions/50204633/allow-bot-to-access-telegram-group-messages/50236522#50236522).
77
+ This allows the bot to access all group messages.
78
+
79
+ #### Required environment variables.
80
+
81
+ You can use the `GOOGLE_API_KEY`, `OPENAI_API_KEY`, `OPENAI_API_BASE_URL` or `OLLAMA_MODEL` for selecting the required
82
+ LLM provider.
83
+ The `OPENAI_API_BASE_URL` will look for an OpenAI API like, as the LM Studio API
84
+
85
+ - <b>Note:</b> When `GOOGLE_API_KEY` option is selected, the default model will be Gemini 2.0 Flash.
86
+
87
+ `TELEGRAM_BOT_NAME`: Your Telegram bot name
88
+
89
+ `TELEGRAM_BOT_USERNAME`: Your Telegram bot username
90
+
91
+ `TELEGRAM_BOT_TOKEN`: Your Telegram bot token
92
+
93
+ #### Advanced Identity Settings
94
+
95
+ `BOT_UUID`: A unique identifier for this bot instance (default: `default-bot-uuid`). Used to isolate conversation
96
+ history in storage.
97
+
98
+ `USER_ID`: Your Telegram User ID (default: `0`). Used for internal tracking and metadata.
99
+
100
+ #### Selecting OpenAI Model.
101
+
102
+ `OPENAI_API_MODEL`: LLM to use for OpenAI or OpenAI-like API; if not provided, the default model will be used.
103
+
104
+ #### Selecting Google API Model.
105
+
106
+ `GOOGLE_API_MODEL`: LLM to use for Google API; if not provided, the default model will be used.
107
+
108
+ #### Enabling Agent Mode
109
+
110
+ `AGENT_MODE`: Enable agent mode (True, False). Default is False. When agent mode is enabled, the bot will use **agentic
111
+ capabilities**. This means the bot will use the LLM as a reasoning engine, allowing it to iterate through multiple
112
+ steps (like searching the internet and analyzing results) to complete complex tasks.
113
+
114
+ `AGENT_INSTRUCTIONS`: (Optional) Custom instructions to guide the agent's behavior and reasoning when in agent mode.
115
+
116
+ #### Enabling image Generation with Stable Diffusion
117
+
118
+ `WEBUI_SD_API_URL`: you can define a Stable Diffusion Web UI API URL for image generation. If this option is enabled the
119
+ bot will answer image generation requests using Stable Diffusion generated images.
120
+
121
+ `WEBUI_SD_API_PARAMS`: A JSON string containing Stable Diffusion Web UI API params. If not provided, default parameters
122
+ for the SDXL Turbo model will be used.
123
+
124
+ #### Setting custom bot character instructions
125
+
126
+ `TELEGRAM_BOT_INSTRUCTIONS_CHARACTER`: You can define a custom character for the bot instructions.
127
+ This will override the default bot character. For example:
128
+ `You are a software engineer, geek and nerd, user of linux and free software technologies.`
129
+
130
+ #### Setting extra bot instructions
131
+
132
+ `TELEGRAM_BOT_INSTRUCTIONS_EXTRA`: You can include extra LLM system instructions using this variable.
133
+
134
+ #### Setting custom bot instructions
135
+
136
+ `TELEGRAM_BOT_INSTRUCTIONS`: You can define custom LLM system instructions using this variable.
137
+ This will override the default instructions, and the custom bot character instructions.
138
+
139
+ #### Limiting Bot interaction
140
+
141
+ `TELEGRAM_ALLOWED_CHATS`: You can use a comma-separated list of allowed chat IDs to limit bot interaction to those
142
+ chats.
143
+
144
+ `ALLOW_PRIVATE_CHATS`: Enable or disable direct bot interaction in private chats (True, False). Default is True.
145
+
146
+ `ADD_NO_ANSWER`: If `True`, the bot will reply with "NO_ANSWER" if it doesn't understand a message or isn't sure if it
147
+ should respond (True, False). Default is False.
148
+
149
+ #### Enable multimodal capabilities
150
+
151
+ `IMAGE_MULTIMODAL`: Enable multimodal capabilities for images (True, False). The selected model must support multimodal
152
+ capabilities.
153
+
154
+ `AUDIO_MULTIMODAL`: **(Experimental)** Enable multimodal capabilities for audio/voice messages (True, False). Currently,
155
+ this feature only works with the Gemini API.
156
+
157
+ #### Enable group assistant
158
+
159
+ `ENABLE_GROUP_ASSISTANT`: Enable group assistant for group chats (True, False). The bot will respond to group chats with
160
+ a question mark. The default value is False.
161
+
162
+ #### Enable rate limiting
163
+
164
+ `RATE_LIMITER_REQUESTS_PER_SECOND`: The number of requests per second allowed by the bot.
165
+ `RATE_LIMITER_CHECK_EVERY_N_SECONDS`: The number of seconds between rate limit checks.
166
+ `RATE_LIMITER_MAX_BUCKET_SIZE`: The maximum bucket size for rate limiting.
167
+
168
+ #### Set preferred language
169
+
170
+ `PREFERRED_LANGUAGE`: The preferred language for the bot. (English, Spanish, etc.)
171
+
172
+ #### Set context max tokens
173
+
174
+ `CONTEXT_MAX_TOKENS`: The maximum number of tokens allowed for the bot's context.
175
+
176
+ #### Web Content Retrieval Configuration
177
+
178
+ `WEB_CONTENT_REQUEST_TIMEOUT_SECONDS`: Timeout in seconds for HTTP requests when retrieving web content. Default is 10
179
+ seconds.
180
+
181
+ #### Simulate typing human behavior
182
+
183
+ `SIMULATE_TYPING`: Enable simulating human typing behavior. The default is False. This typing simulation will influence
184
+ the bot's response time in all chats.
185
+
186
+ `SIMULATE_TYPING_WPM`: The words per minute for simulating human typing behavior. Default is 100.
187
+
188
+ `SIMULATE_TYPING_MAX_TIME`: The maximum time in seconds for simulating human typing behavior. Default is 10 seconds (we
189
+ usually don't want to wait too long).
190
+
191
+ #### Tools usage
192
+
193
+ `USE_TOOLS`: Enable tool usage (True, False). Default is False. When tool usage is enabled, the bot will use the LLM's
194
+ tools capabilities. When tool usage is disabled, the bot will use the prompt-based pseudo-tools implementation.
195
+
196
+ #### Search Configuration
197
+
198
+ The bot uses DuckDuckGo by default for web searches. You can optionally enable **Tavily Search** for more advanced
199
+ search capabilities.
200
+
201
+ `USE_TAVILY_SEARCH`: Enable Tavily Search (True, False). Default is False.
202
+
203
+ `TAVILY_SEARCH_KEY`: Your Tavily API key. Required if `USE_TAVILY_SEARCH` is set to True.
204
+
205
+ #### Storage Configuration
206
+
207
+ `STORAGE_TYPE`: Sets the storage type for conversation context (memory, redis). Default is memory.
208
+
209
+ `REDIS_URL`: The Redis URL for storage when `STORAGE_TYPE` is set to redis. Default is `redis://localhost:6379/0`.
210
+
211
+ ### MCP (Model Context Protocol) Support
212
+
213
+ manolo_bot supports the [Model Context Protocol](https://modelcontextprotocol.io/) for connecting to external tool
214
+ servers.
215
+
216
+ #### Enabling MCP
217
+
218
+ Set the following environment variables:
219
+
220
+ `ENABLE_MCP`: Enable MCP support (True, False). Default is False.
221
+
222
+ `MCP_SERVERS_CONFIG`: MCP server configuration in JSON format.
223
+
224
+ #### MCP Server Configuration
225
+
226
+ MCP servers are configured via the `MCP_SERVERS_CONFIG` environment variable, which accepts a JSON object mapping server
227
+ names to their configurations.
228
+
229
+ **stdio transport example:**
230
+
231
+ ```json
232
+ {
233
+ "math": {
234
+ "command": "python",
235
+ "args": [
236
+ "/path/to/math_server.py"
237
+ ],
238
+ "transport": "stdio"
239
+ }
240
+ }
241
+ ```
242
+
243
+ **streamable_http transport example:**
244
+
245
+ ```json
246
+ {
247
+ "weather": {
248
+ "url": "http://localhost:8000/mcp/",
249
+ "transport": "streamable_http"
250
+ }
251
+ }
252
+ ```
253
+
254
+ **Multiple servers:**
255
+
256
+ ```json
257
+ {
258
+ "math": {
259
+ "command": "python",
260
+ "args": [
261
+ "/path/to/math_server.py"
262
+ ],
263
+ "transport": "stdio"
264
+ },
265
+ "weather": {
266
+ "url": "http://localhost:8000/mcp/",
267
+ "transport": "streamable_http"
268
+ }
269
+ }
270
+ ```
271
+
272
+ **Notes:**
273
+
274
+ - MCP tools are loaded alongside custom tools defined in `ai/tools.py`
275
+ - If tool name conflicts occur, MCP tools will override custom tools (a warning is logged)
276
+ - The bot will start successfully even if MCP initialization fails (graceful degradation)
277
+ - MCP is only loaded when both `ENABLE_MCP=True` and valid `MCP_SERVERS_CONFIG` are provided
278
+
279
+ #### Logging Level
280
+
281
+ `LOGGING_LEVEL`: Sets the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL), defaulting to INFO.
282
+
283
+ ### Available Commands
284
+
285
+ The bot supports the following commands:
286
+
287
+ - `/flushcontext` - Clears the conversation context for the current chat. In group chats, only admins can use this
288
+ command. The bot will respond with a confirmation message in the configured language.
289
+
290
+ ### Running the Bot
291
+
292
+ You can run the bot using the following command:
293
+
294
+ ```shell
295
+ uv run manolo-bot
296
+ ```
297
+
298
+ ## Developers information
299
+
300
+ Use `uv sync --dev` to install the development dependencies.
301
+
302
+ ### Pre-commit hooks
303
+
304
+ After installing the development dependencies, to install pre-commit scripts, including ruff checks, you can run
305
+ the following command:
306
+
307
+ ```shell
308
+ pre-commit install
309
+ ```
310
+
311
+ ### Running tests
312
+
313
+ You can run the tests using the following command:
314
+
315
+ ```shell
316
+ uv run python -m unittest discover tests
317
+ ```
318
+
319
+ ## Library Usage
320
+
321
+ `manolo-bot` can also be used as a library to build your own AI assistants. It provides a clean abstraction for LLM
322
+ providers, message storage, and agentic capabilities.
323
+
324
+ ### Using LLMAgent (Recommended)
325
+
326
+ The `LLMAgent` is the most powerful way to use the library. It allows the bot to use tools and iterate through multiple
327
+ steps to solve complex queries.
328
+
329
+ ```python
330
+ import asyncio
331
+ from manolo_bot.ai.llmagent import LLMAgent
332
+ from manolo_bot.ai.llmbot import LLMBuilder
333
+ from manolo_bot.ai.config import BotConfig, LLMConfig
334
+ from manolo_bot.storage.memory_storage import MemoryMessagesStorage
335
+ from manolo_bot.ai.tools import get_tools
336
+
337
+
338
+ async def main():
339
+ # 1. Configure LLM (Google, OpenAI, or Ollama)
340
+ llm_config = LLMConfig(google_api_key="your_api_key")
341
+ llm = LLMBuilder(llm_config).get_llm()
342
+
343
+ # 2. Define Bot identity
344
+ bot_config = BotConfig(bot_uuid="my-bot", bot_name="Assistant")
345
+
346
+ # 3. Setup Storage for a specific conversation
347
+ storage = MemoryMessagesStorage(bot_uuid="my-bot", chat_id=123)
348
+ await storage.refresh_messages()
349
+
350
+ # 4. Initialize Agent with tools
351
+ tools = get_tools()
352
+ agent = LLMAgent(
353
+ llm=llm,
354
+ config=bot_config,
355
+ system_instructions="You are a helpful assistant.",
356
+ storage=storage,
357
+ tools=tools
358
+ )
359
+
360
+ # 5. Interact
361
+ # The agent can search the web, analyze content, etc.
362
+ response = await agent.answer_message(chat_id=123, message="What is the current price of Bitcoin?")
363
+ print(f"Agent: {response.content}")
364
+
365
+ # 6. Persistent changes (if using Redis)
366
+ await storage.commit()
367
+
368
+
369
+ if __name__ == "__main__":
370
+ asyncio.run(main())
371
+ ```
372
+
373
+ ### Custom Tools
374
+
375
+ You can provide your own tools when initializing `LLMAgent` or `LLMBot`:
376
+
377
+ ```python
378
+ from langchain_core.tools import tool
379
+ from manolo_bot.ai.llmagent import LLMAgent
380
+
381
+
382
+ @tool
383
+ def my_tool(query: str) -> str:
384
+ """Description of my tool."""
385
+ return "Result"
386
+
387
+
388
+ agent = LLMAgent(..., tools=[my_tool])
389
+ ```
390
+
391
+ ### Using LLMBot (Simple)
392
+
393
+ For simpler use cases or when using models that don't support tool calling, you can use the basic `LLMBot`. It provides
394
+ a direct chat interface without iterative reasoning.
395
+
396
+ ```python
397
+ from manolo_bot.ai.llmbot import LLMBot
398
+
399
+ # ... (same setup as above)
400
+
401
+ bot = LLMBot(
402
+ llm=llm,
403
+ config=bot_config,
404
+ system_instructions="You are a simple assistant.",
405
+ storage=storage
406
+ )
407
+
408
+ response = await bot.answer_message(chat_id=123, message="Hello!")
409
+ ```
410
+
411
+ For more advanced usage and full API details, please refer to
412
+ the [Full Documentation](https://manolo-bot.readthedocs.io/).
413
+
414
+ ## Contributing
415
+
416
+ If you'd like to contribute to this project, feel free to submit a pull request. We're always open to new ideas or
417
+ improvements to the code.
418
+
419
+ ## License
420
+
421
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.