TeLLMgramBot 3.15.2__tar.gz → 3.15.3__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.
Files changed (26) hide show
  1. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/PKG-INFO +2 -1
  2. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/README.md +1 -0
  3. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/TeLLMgramBot.py +39 -2
  4. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/initialize.py +2 -0
  5. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot.egg-info/PKG-INFO +2 -1
  6. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/setup.py +1 -1
  7. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/LICENSE +0 -0
  8. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/__init__.py +0 -0
  9. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/archive.py +0 -0
  10. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/conversation.py +0 -0
  11. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/database.py +0 -0
  12. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/message_handlers.py +0 -0
  13. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/models.py +0 -0
  14. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/providers/__init__.py +0 -0
  15. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/providers/anthropic_provider.py +0 -0
  16. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/providers/base.py +0 -0
  17. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/providers/factory.py +0 -0
  18. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/providers/openai_provider.py +0 -0
  19. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/tools.py +0 -0
  20. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/utils.py +0 -0
  21. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot/web_utils.py +0 -0
  22. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot.egg-info/SOURCES.txt +0 -0
  23. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot.egg-info/dependency_links.txt +0 -0
  24. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot.egg-info/requires.txt +0 -0
  25. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/TeLLMgramBot.egg-info/top_level.txt +0 -0
  26. {tellmgrambot-3.15.2 → tellmgrambot-3.15.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TeLLMgramBot
3
- Version: 3.15.2
3
+ Version: 3.15.3
4
4
  Summary: LLM-powered Telegram bot (OpenAI + Anthropic)
5
5
  Home-page: https://github.com/Digital-Heresy/TeLLMgramBot
6
6
  Author: Digital Heresy
@@ -168,6 +168,7 @@ When the bot is triggered in a group and about to respond (not deferring to anot
168
168
  - `archive_days`: Days before messages are eligible for archival (optional; default 60, minimum 1). Older messages are distilled into daily summaries, then progressively compressed into monthly digests. Once archived their respective raw messages do not return to the LLM context any more, only when searching messages.
169
169
  - `document_processing`: Optional bool (default: true). Set to false to disable document and text file summarisation.
170
170
  - `allow_local_webhooks`: Set to `true` to permit webhook/MCP URLs targeting loopback or link-local addresses (optional; default `false`). Useful when tools like Home Assistant run on the same host.
171
+ - `max_conversations`: Optional max chats kept in memory at once (default: 500, minimum 1). Least-recently-used chats beyond this cap are evicted and reload from the database on their next message. Useful for deployments with memory constraints; evicted chats retain all persisted data.
171
172
  - `tools`: Optional list of webhook and MCP tool definitions (admin-only, private chat only). See [docs/tools.md](docs/tools.md) for schema and examples.
172
173
  4. **Disable group privacy mode in BotFather:**
173
174
  ```
@@ -131,6 +131,7 @@ When the bot is triggered in a group and about to respond (not deferring to anot
131
131
  - `archive_days`: Days before messages are eligible for archival (optional; default 60, minimum 1). Older messages are distilled into daily summaries, then progressively compressed into monthly digests. Once archived their respective raw messages do not return to the LLM context any more, only when searching messages.
132
132
  - `document_processing`: Optional bool (default: true). Set to false to disable document and text file summarisation.
133
133
  - `allow_local_webhooks`: Set to `true` to permit webhook/MCP URLs targeting loopback or link-local addresses (optional; default `false`). Useful when tools like Home Assistant run on the same host.
134
+ - `max_conversations`: Optional max chats kept in memory at once (default: 500, minimum 1). Least-recently-used chats beyond this cap are evicted and reload from the database on their next message. Useful for deployments with memory constraints; evicted chats retain all persisted data.
134
135
  - `tools`: Optional list of webhook and MCP tool definitions (admin-only, private chat only). See [docs/tools.md](docs/tools.md) for schema and examples.
135
136
  4. **Disable group privacy mode in BotFather:**
136
137
  ```
@@ -5,6 +5,7 @@ import logging
5
5
  import json
6
6
  import os
7
7
  import re
8
+ from collections import OrderedDict
8
9
  from math import floor
9
10
 
10
11
  from telegram import Bot, Update, Message, Chat, User, ReactionTypeEmoji, MessageEntity, InlineKeyboardButton, InlineKeyboardMarkup
@@ -79,6 +80,23 @@ def _validated_allow_local(value) -> bool:
79
80
  return value is True
80
81
 
81
82
 
83
+ def _validated_max_conversations(value) -> int:
84
+ """
85
+ Validate the max_conversations config value, defaulting to 500 on invalid input.
86
+
87
+ Caps how many Conversation objects self.conversations keeps in memory at once;
88
+ least-recently-used chats beyond this cap are evicted and reload from DB on
89
+ their next message.
90
+
91
+ Args:
92
+ value: Raw `max_conversations` value from bot config.
93
+ """
94
+ if value is not None and not (type(value) is int and value >= 1):
95
+ logger.warning(f"Invalid max_conversations '{value}' (must be an integer >= 1); using default 500")
96
+ return 500
97
+ return value if value is not None else 500
98
+
99
+
82
100
  _SEARCH_TOOL = {
83
101
  "name": "search_messages",
84
102
  "description": (
@@ -438,6 +456,12 @@ class TelegramBot:
438
456
  session (get_past_interaction) or checks for new messages since the last load
439
457
  (refresh_user_context).
440
458
 
459
+ self.conversations is an OrderedDict capped at self.llm['max_conversations'] entries.
460
+ Every call moves chat_id to the most-recently-used end; inserting past the cap evicts
461
+ the least-recently-used chat (and its token_warning entry) from memory. Eviction never
462
+ deletes persisted data - an evicted chat's next message cold-loads from DB exactly like
463
+ a chat the bot has never seen before.
464
+
441
465
  Args:
442
466
  chat_id: Telegram chat ID.
443
467
  chat_type: 'private', 'group', or 'supergroup'.
@@ -447,10 +471,15 @@ class TelegramBot:
447
471
  Returns:
448
472
  The active Conversation for this chat.
449
473
  """
450
- if chat_id not in self.conversations:
474
+ if chat_id in self.conversations:
475
+ self.conversations.move_to_end(chat_id)
476
+ else:
451
477
  self.conversations[chat_id] = Conversation(
452
478
  chat_id, chat_type, self.llm['prompt'], self.llm['chat_model'], chat_title,
453
479
  )
480
+ if len(self.conversations) > self.llm['max_conversations']:
481
+ evicted_id, _ = self.conversations.popitem(last=False)
482
+ self.token_warning.pop(evicted_id, None)
454
483
  conv = self.conversations[chat_id]
455
484
  conv.update_datetime()
456
485
 
@@ -1298,6 +1327,7 @@ class TelegramBot:
1298
1327
  persona_temp = INIT_BOT_CONFIG['persona_temp'],
1299
1328
  archive_days = INIT_BOT_CONFIG['archive_days'],
1300
1329
  document_processing = INIT_BOT_CONFIG['document_processing'],
1330
+ max_conversations = INIT_BOT_CONFIG['max_conversations'],
1301
1331
  persona_prompt = INIT_BOT_CONFIG['persona_prompt'],
1302
1332
  key_status: ApiKeyStatus | None = None,
1303
1333
  instance_name: str | None = None,
@@ -1326,6 +1356,9 @@ class TelegramBot:
1326
1356
  archive_days: Days before messages are eligible for Tier 1 archival (default: 60).
1327
1357
  Must be an integer >= 1; invalid values log a warning and fall back to 60.
1328
1358
  Tier 2 compression triggers at archive_days * 2.
1359
+ max_conversations: Max chats kept in self.conversations at once (default: 500).
1360
+ Validated by _validated_max_conversations(); least-recently-used
1361
+ chats beyond this cap are evicted in _get_or_load_conversation().
1329
1362
  webhook_schemas: Provider-compatible tool schema dicts for webhook tools (from build_tool_registry).
1330
1363
  If None, no webhook tools are registered.
1331
1364
  webhook_defs: Resolved webhook tool definitions keyed by tool name (from build_tool_registry).
@@ -1348,7 +1381,9 @@ class TelegramBot:
1348
1381
 
1349
1382
  # Initialize some variables
1350
1383
  self.token_warning = {} # Determines whether user has reached token limit by AI model
1351
- self.conversations = {} # Provides Conversation class per user based on bot response
1384
+ # Provides Conversation class per chat_id; an OrderedDict so _get_or_load_conversation()
1385
+ # can track recency via move_to_end() and evict the least-recently-used entry on overflow.
1386
+ self.conversations: OrderedDict = OrderedDict()
1352
1387
  self.webhook_schemas = webhook_schemas or [] # Provider-compatible schemas for webhook tools
1353
1388
  self.webhook_defs = webhook_defs or {} # Resolved tool definitions keyed by name
1354
1389
  self._mcp_entries = mcp_entries or [] # Raw mcp_server entries; discovered in _post_init()
@@ -1422,6 +1457,7 @@ class TelegramBot:
1422
1457
  'top_p' : 0.9,
1423
1458
  'archive_days' : archive_days if archive_days is not None else 60,
1424
1459
  'document_processing' : document_processing if document_processing is not None else True,
1460
+ 'max_conversations' : _validated_max_conversations(max_conversations),
1425
1461
  }
1426
1462
  # Set a rounded-down integer to prune a lengthy conversation by 500 tokens
1427
1463
  # Note if the upper limit is below 500, the lower limit is set to 0
@@ -1499,6 +1535,7 @@ class TelegramBot:
1499
1535
  persona_temp = config['persona_temp'],
1500
1536
  archive_days = config['archive_days'],
1501
1537
  document_processing = config['document_processing'],
1538
+ max_conversations = config['max_conversations'],
1502
1539
  persona_prompt = prompt,
1503
1540
  key_status = key_status,
1504
1541
  instance_name = config['instance_name'],
@@ -113,6 +113,7 @@ INIT_BOT_CONFIG = {
113
113
  'archive_days': None,
114
114
  'allow_local_webhooks': None,
115
115
  'document_processing': None,
116
+ 'max_conversations': None,
116
117
  'persona_prompt': 'You are a generic test bot powered by a user-configured LLM.'
117
118
  }
118
119
 
@@ -124,6 +125,7 @@ INIT_BOT_CONFIG_COMMENTS = {
124
125
  'archive_days': '# Optional, days before messages are eligible for Tier 1 archival (default: 60, min: 1). Tier 2 triggers at 2x this value.',
125
126
  'allow_local_webhooks': '# Optional, set to true to permit webhook/MCP URLs targeting loopback or link-local addresses (default: false)',
126
127
  'document_processing': '# Optional, set to false to disable document summarisation (default: true)',
128
+ 'max_conversations': '# Optional, max chats kept in memory at once; least-recently-used chats beyond this cap are evicted and reload from DB on their next message (default: 500, min: 1)',
127
129
  }
128
130
 
129
131
  # Append the framework-owned system appendix to the persona prompt.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TeLLMgramBot
3
- Version: 3.15.2
3
+ Version: 3.15.3
4
4
  Summary: LLM-powered Telegram bot (OpenAI + Anthropic)
5
5
  Home-page: https://github.com/Digital-Heresy/TeLLMgramBot
6
6
  Author: Digital Heresy
@@ -168,6 +168,7 @@ When the bot is triggered in a group and about to respond (not deferring to anot
168
168
  - `archive_days`: Days before messages are eligible for archival (optional; default 60, minimum 1). Older messages are distilled into daily summaries, then progressively compressed into monthly digests. Once archived their respective raw messages do not return to the LLM context any more, only when searching messages.
169
169
  - `document_processing`: Optional bool (default: true). Set to false to disable document and text file summarisation.
170
170
  - `allow_local_webhooks`: Set to `true` to permit webhook/MCP URLs targeting loopback or link-local addresses (optional; default `false`). Useful when tools like Home Assistant run on the same host.
171
+ - `max_conversations`: Optional max chats kept in memory at once (default: 500, minimum 1). Least-recently-used chats beyond this cap are evicted and reload from the database on their next message. Useful for deployments with memory constraints; evicted chats retain all persisted data.
171
172
  - `tools`: Optional list of webhook and MCP tool definitions (admin-only, private chat only). See [docs/tools.md](docs/tools.md) for schema and examples.
172
173
  4. **Disable group privacy mode in BotFather:**
173
174
  ```
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name='TeLLMgramBot',
8
- version='3.15.2',
8
+ version='3.15.3',
9
9
  packages=find_packages(),
10
10
  license='MIT',
11
11
  author='Digital Heresy',
File without changes
File without changes