chibi-bot 1.6.0b0__py3-none-any.whl
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.
- chibi/__init__.py +0 -0
- chibi/__main__.py +343 -0
- chibi/cli.py +90 -0
- chibi/config/__init__.py +6 -0
- chibi/config/app.py +123 -0
- chibi/config/gpt.py +108 -0
- chibi/config/logging.py +15 -0
- chibi/config/telegram.py +43 -0
- chibi/config_generator.py +233 -0
- chibi/constants.py +362 -0
- chibi/exceptions.py +58 -0
- chibi/models.py +496 -0
- chibi/schemas/__init__.py +0 -0
- chibi/schemas/anthropic.py +20 -0
- chibi/schemas/app.py +54 -0
- chibi/schemas/cloudflare.py +65 -0
- chibi/schemas/mistralai.py +56 -0
- chibi/schemas/suno.py +83 -0
- chibi/service.py +135 -0
- chibi/services/bot.py +276 -0
- chibi/services/lock_manager.py +20 -0
- chibi/services/mcp/manager.py +242 -0
- chibi/services/metrics.py +54 -0
- chibi/services/providers/__init__.py +16 -0
- chibi/services/providers/alibaba.py +79 -0
- chibi/services/providers/anthropic.py +40 -0
- chibi/services/providers/cloudflare.py +98 -0
- chibi/services/providers/constants/suno.py +2 -0
- chibi/services/providers/customopenai.py +11 -0
- chibi/services/providers/deepseek.py +15 -0
- chibi/services/providers/eleven_labs.py +85 -0
- chibi/services/providers/gemini_native.py +489 -0
- chibi/services/providers/grok.py +40 -0
- chibi/services/providers/minimax.py +96 -0
- chibi/services/providers/mistralai_native.py +312 -0
- chibi/services/providers/moonshotai.py +20 -0
- chibi/services/providers/openai.py +74 -0
- chibi/services/providers/provider.py +892 -0
- chibi/services/providers/suno.py +130 -0
- chibi/services/providers/tools/__init__.py +23 -0
- chibi/services/providers/tools/cmd.py +132 -0
- chibi/services/providers/tools/common.py +127 -0
- chibi/services/providers/tools/constants.py +78 -0
- chibi/services/providers/tools/exceptions.py +1 -0
- chibi/services/providers/tools/file_editor.py +875 -0
- chibi/services/providers/tools/mcp_management.py +274 -0
- chibi/services/providers/tools/mcp_simple.py +72 -0
- chibi/services/providers/tools/media.py +451 -0
- chibi/services/providers/tools/memory.py +252 -0
- chibi/services/providers/tools/schemas.py +10 -0
- chibi/services/providers/tools/send.py +435 -0
- chibi/services/providers/tools/tool.py +163 -0
- chibi/services/providers/tools/utils.py +146 -0
- chibi/services/providers/tools/web.py +261 -0
- chibi/services/providers/utils.py +182 -0
- chibi/services/task_manager.py +93 -0
- chibi/services/user.py +269 -0
- chibi/storage/abstract.py +54 -0
- chibi/storage/database.py +86 -0
- chibi/storage/dynamodb.py +257 -0
- chibi/storage/local.py +70 -0
- chibi/storage/redis.py +91 -0
- chibi/utils/__init__.py +0 -0
- chibi/utils/app.py +249 -0
- chibi/utils/telegram.py +521 -0
- chibi_bot-1.6.0b0.dist-info/LICENSE +21 -0
- chibi_bot-1.6.0b0.dist-info/METADATA +340 -0
- chibi_bot-1.6.0b0.dist-info/RECORD +70 -0
- chibi_bot-1.6.0b0.dist-info/WHEEL +4 -0
- chibi_bot-1.6.0b0.dist-info/entry_points.txt +3 -0
chibi/config/telegram.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from functools import lru_cache
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TelegramSettings(BaseSettings):
|
|
8
|
+
model_config = SettingsConfigDict(
|
|
9
|
+
env_file=(".env",),
|
|
10
|
+
extra="ignore",
|
|
11
|
+
)
|
|
12
|
+
token: str = Field(alias="TELEGRAM_BOT_TOKEN")
|
|
13
|
+
|
|
14
|
+
telegram_base_url: str = Field(default="https://api.telegram.org/bot")
|
|
15
|
+
telegram_base_file_url: str = Field(default="https://api.telegram.org/file/bot")
|
|
16
|
+
allow_bots: bool = Field(default=False)
|
|
17
|
+
answer_direct_messages_only: bool = Field(default=True)
|
|
18
|
+
bot_name: str = Field(default="Chibi")
|
|
19
|
+
message_for_disallowed_users: str = Field(
|
|
20
|
+
default="You're not allowed to interact with me, sorry. Contact my owner first, please.",
|
|
21
|
+
)
|
|
22
|
+
proxy: str | None = Field(default=None)
|
|
23
|
+
groups_whitelist_raw: str | None = Field(alias="GROUPS_WHITELIST", default=None)
|
|
24
|
+
|
|
25
|
+
users_whitelist_raw: str | None = Field(alias="USERS_WHITELIST", default=None)
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def groups_whitelist(self) -> list[int]:
|
|
29
|
+
return [int(x.strip()) for x in self.groups_whitelist_raw.split(",")] if self.groups_whitelist_raw else []
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def users_whitelist(self) -> list[str]:
|
|
33
|
+
return (
|
|
34
|
+
[str(x).strip().strip("@") for x in self.users_whitelist_raw.split(",")] if self.users_whitelist_raw else []
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@lru_cache()
|
|
39
|
+
def _get_telegram_settings() -> TelegramSettings:
|
|
40
|
+
return TelegramSettings()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
telegram_settings = _get_telegram_settings()
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
CHIBI_BOT_DIR = Path.home() / "chibi-bot"
|
|
6
|
+
DATA_DIR = CHIBI_BOT_DIR / "data"
|
|
7
|
+
SKILLS_DIR = CHIBI_BOT_DIR / "skills"
|
|
8
|
+
HOME_DIR = CHIBI_BOT_DIR / "home"
|
|
9
|
+
|
|
10
|
+
CONFIG_PATH = os.path.expanduser("~/.chibi/settings")
|
|
11
|
+
|
|
12
|
+
DEFAULT_CONFIG = """# Chibi Configuration File
|
|
13
|
+
# This file contains all environment variables supported by Chibi.
|
|
14
|
+
# Uncomment and set values as needed.
|
|
15
|
+
|
|
16
|
+
# ============================================================================
|
|
17
|
+
# CRITICAL - Required for basic operation
|
|
18
|
+
# ============================================================================
|
|
19
|
+
|
|
20
|
+
# Telegram bot token (REQUIRED)
|
|
21
|
+
# Get one from @BotFather on Telegram
|
|
22
|
+
TELEGRAM_BOT_TOKEN=
|
|
23
|
+
|
|
24
|
+
# ============================================================================
|
|
25
|
+
# IMPORTANT - At least one LLM API key is required
|
|
26
|
+
# ============================================================================
|
|
27
|
+
|
|
28
|
+
# OpenAI API key (for GPT-4, GPT-4o, etc.)
|
|
29
|
+
# OPENAI_API_KEY=
|
|
30
|
+
|
|
31
|
+
# Anthropic API key (for Claude models)
|
|
32
|
+
# ANTHROPIC_API_KEY=
|
|
33
|
+
|
|
34
|
+
# Google Gemini API key
|
|
35
|
+
# GEMINI_API_KEY=
|
|
36
|
+
|
|
37
|
+
# DeepSeek API key
|
|
38
|
+
# DEEPSEEK_API_KEY=
|
|
39
|
+
|
|
40
|
+
# Alibaba API key
|
|
41
|
+
# ALIBABA_API_KEY=
|
|
42
|
+
|
|
43
|
+
# Cloudflare API key
|
|
44
|
+
# CLOUDFLARE_API_KEY=
|
|
45
|
+
|
|
46
|
+
# Cloudflare account ID
|
|
47
|
+
# CLOUDFLARE_ACCOUNT_ID=
|
|
48
|
+
|
|
49
|
+
# Custom OpenAI API key
|
|
50
|
+
# CUSTOMOPENAI_API_KEY=
|
|
51
|
+
|
|
52
|
+
# Custom OpenAI URL (default: http://localhost:1234/v1)
|
|
53
|
+
CUSTOMOPENAI_URL=http://localhost:1234/v1
|
|
54
|
+
|
|
55
|
+
# Grok API key
|
|
56
|
+
# GROK_API_KEY=
|
|
57
|
+
|
|
58
|
+
# Mistral AI API key
|
|
59
|
+
# MISTRALAI_API_KEY=
|
|
60
|
+
|
|
61
|
+
# Moonshot AI API key
|
|
62
|
+
# MOONSHOTAI_API_KEY=
|
|
63
|
+
|
|
64
|
+
# MiniMax API key
|
|
65
|
+
# MINIMAX_API_KEY=
|
|
66
|
+
|
|
67
|
+
# Suno API key (for music generation)
|
|
68
|
+
# SUNO_API_ORG_API_KEY=
|
|
69
|
+
|
|
70
|
+
# ElevenLabs API key (for text-to-speech)
|
|
71
|
+
# ELEVEN_LABS_API_KEY=
|
|
72
|
+
|
|
73
|
+
# ============================================================================
|
|
74
|
+
# IMPORTANT - Storage configuration
|
|
75
|
+
# ============================================================================
|
|
76
|
+
|
|
77
|
+
# Redis connection URL (optional, for caching)
|
|
78
|
+
# redis=
|
|
79
|
+
|
|
80
|
+
# Redis password (optional)
|
|
81
|
+
# redis_password=
|
|
82
|
+
|
|
83
|
+
# AWS region for DynamoDB
|
|
84
|
+
# aws_region=
|
|
85
|
+
|
|
86
|
+
# AWS access key ID
|
|
87
|
+
# aws_access_key_id=
|
|
88
|
+
|
|
89
|
+
# AWS secret access key
|
|
90
|
+
# aws_secret_access_key=
|
|
91
|
+
|
|
92
|
+
# DynamoDB table name for users
|
|
93
|
+
# ddb_users_table=
|
|
94
|
+
|
|
95
|
+
# DynamoDB table name for messages
|
|
96
|
+
# ddb_messages_table=
|
|
97
|
+
|
|
98
|
+
# Local storage path (default: ~/chibi-bot/data)
|
|
99
|
+
local_data_path=~/chibi-bot/data
|
|
100
|
+
|
|
101
|
+
# ============================================================================
|
|
102
|
+
# IMPORTANT - Model and feature settings
|
|
103
|
+
# ============================================================================
|
|
104
|
+
|
|
105
|
+
# Hide model options in UI (default: false)
|
|
106
|
+
hide_models=false
|
|
107
|
+
|
|
108
|
+
# Hide imagine commands (default: false)
|
|
109
|
+
hide_imagine=false
|
|
110
|
+
|
|
111
|
+
# Monthly image generation limit (default: 0, unlimited)
|
|
112
|
+
IMAGE_GENERATIONS_LIMIT=0
|
|
113
|
+
|
|
114
|
+
# Comma-separated image generation whitelist (optional)
|
|
115
|
+
# IMAGE_GENERATIONS_WHITELIST=
|
|
116
|
+
|
|
117
|
+
# Comma-separated models whitelist (optional)
|
|
118
|
+
# MODELS_WHITELIST=
|
|
119
|
+
|
|
120
|
+
# Comma-separated tools whitelist (optional)
|
|
121
|
+
# TOOLS_WHITELIST=
|
|
122
|
+
|
|
123
|
+
# ============================================================================
|
|
124
|
+
# OPTIONAL - Directory settings
|
|
125
|
+
# ============================================================================
|
|
126
|
+
|
|
127
|
+
# AI agent home directory (default: ~/chibi-bot/home)
|
|
128
|
+
home_dir=~/chibi-bot/home
|
|
129
|
+
|
|
130
|
+
# AI agent working directory (default: ~/chibi-bot/home)
|
|
131
|
+
working_dir=~/chibi-bot/home
|
|
132
|
+
|
|
133
|
+
# Absolute path to directory with skills
|
|
134
|
+
skills_dir=~/chibi-bot/skills
|
|
135
|
+
|
|
136
|
+
# ============================================================================
|
|
137
|
+
# OPTIONAL - MCP configuration
|
|
138
|
+
# ============================================================================
|
|
139
|
+
|
|
140
|
+
# Enable MCP SSE (default: true)
|
|
141
|
+
enable_mcp_sse=true
|
|
142
|
+
|
|
143
|
+
# Enable MCP stdio (default: false)
|
|
144
|
+
enable_mcp_stdio=false
|
|
145
|
+
|
|
146
|
+
# ============================================================================
|
|
147
|
+
# OPTIONAL - Heartbeat monitoring
|
|
148
|
+
# ============================================================================
|
|
149
|
+
|
|
150
|
+
# Heartbeat check URL (optional)
|
|
151
|
+
# heartbeat_url=
|
|
152
|
+
|
|
153
|
+
# Heartbeat frequency in seconds (default: 60, minimum: 30)
|
|
154
|
+
heartbeat_frequency_call=60
|
|
155
|
+
|
|
156
|
+
# Heartbeat retry count (default: 3)
|
|
157
|
+
heartbeat_retry_calls=3
|
|
158
|
+
|
|
159
|
+
# Heartbeat proxy URL (optional)
|
|
160
|
+
# heartbeat_proxy=
|
|
161
|
+
|
|
162
|
+
# ============================================================================
|
|
163
|
+
# OPTIONAL - InfluxDB metrics
|
|
164
|
+
# ============================================================================
|
|
165
|
+
|
|
166
|
+
# InfluxDB URL (optional)
|
|
167
|
+
# influxdb_url=
|
|
168
|
+
|
|
169
|
+
# InfluxDB token (optional)
|
|
170
|
+
# influxdb_token=
|
|
171
|
+
|
|
172
|
+
# InfluxDB organization (optional)
|
|
173
|
+
# influxdb_org=
|
|
174
|
+
|
|
175
|
+
# InfluxDB bucket (optional)
|
|
176
|
+
# influxdb_bucket=
|
|
177
|
+
|
|
178
|
+
# ============================================================================
|
|
179
|
+
# OPTIONAL - Logging and debugging
|
|
180
|
+
# ============================================================================
|
|
181
|
+
|
|
182
|
+
# Log prompt data (default: false)
|
|
183
|
+
log_prompt_data=false
|
|
184
|
+
|
|
185
|
+
# ============================================================================
|
|
186
|
+
# OPTIONAL - Telegram settings
|
|
187
|
+
# ============================================================================
|
|
188
|
+
|
|
189
|
+
# Comma-separated group IDs whitelist (optional)
|
|
190
|
+
# GROUPS_WHITELIST=
|
|
191
|
+
|
|
192
|
+
# Comma-separated user IDs whitelist (optional)
|
|
193
|
+
# USERS_WHITELIST=
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def generate_default_config() -> None:
|
|
198
|
+
"""Generate default configuration file if it doesn't exist."""
|
|
199
|
+
config_dir = os.path.dirname(CONFIG_PATH)
|
|
200
|
+
Path(config_dir).mkdir(parents=True, exist_ok=True)
|
|
201
|
+
|
|
202
|
+
if not os.path.exists(CONFIG_PATH):
|
|
203
|
+
try:
|
|
204
|
+
with open(CONFIG_PATH, "w") as config_file:
|
|
205
|
+
config_file.write(DEFAULT_CONFIG)
|
|
206
|
+
print(f"Created default configuration at {CONFIG_PATH}")
|
|
207
|
+
except IOError as e:
|
|
208
|
+
print(f"Error creating configuration file: {e}")
|
|
209
|
+
|
|
210
|
+
# Create directory structure
|
|
211
|
+
try:
|
|
212
|
+
for directory in [CHIBI_BOT_DIR, DATA_DIR, SKILLS_DIR, HOME_DIR]:
|
|
213
|
+
if not directory.exists():
|
|
214
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
215
|
+
print(f"Created directory: {directory}")
|
|
216
|
+
except IOError as e:
|
|
217
|
+
print(f"Error creating directories: {e}")
|
|
218
|
+
|
|
219
|
+
# Sync Skills
|
|
220
|
+
package_skills_dir = Path(__file__).parent.parent / "skills"
|
|
221
|
+
if package_skills_dir.exists():
|
|
222
|
+
try:
|
|
223
|
+
synced_count = 0
|
|
224
|
+
for skill_file in package_skills_dir.iterdir():
|
|
225
|
+
if skill_file.is_file():
|
|
226
|
+
target_path = SKILLS_DIR / skill_file.name
|
|
227
|
+
if not target_path.exists():
|
|
228
|
+
shutil.copy2(skill_file, target_path)
|
|
229
|
+
synced_count += 1
|
|
230
|
+
if synced_count > 0:
|
|
231
|
+
print(f"Synced {synced_count} skills to {SKILLS_DIR}")
|
|
232
|
+
except IOError as e:
|
|
233
|
+
print(f"Error syncing skills: {e}")
|
chibi/constants.py
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from telegram import constants
|
|
5
|
+
|
|
6
|
+
from chibi.config.telegram import telegram_settings
|
|
7
|
+
|
|
8
|
+
GROUP_CHAT_TYPES = [constants.ChatType.GROUP, constants.ChatType.SUPERGROUP]
|
|
9
|
+
PERSONAL_CHAT_TYPES = [constants.ChatType.SENDER, constants.ChatType.PRIVATE]
|
|
10
|
+
IMAGE_SIZE_LITERAL = Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]
|
|
11
|
+
IMAGE_ASPECT_RATIO_LITERAL = Literal["1:1", "3:4", "4:3", "9:16", "16:9"]
|
|
12
|
+
SETTING_SET = "<green>SET</green>"
|
|
13
|
+
SETTING_UNSET = "<red>UNSET</red>"
|
|
14
|
+
SETTING_ENABLED = "<green>ENABLED</green>"
|
|
15
|
+
SETTING_DISABLED = "<red>DISABLED</red>"
|
|
16
|
+
MARKDOWN_TOKENS = ("```", "`", "*", "_", "~")
|
|
17
|
+
IMAGE_UPLOAD_TIMEOUT = 60.0
|
|
18
|
+
FILE_UPLOAD_TIMEOUT = 120.0
|
|
19
|
+
AUDIO_UPLOAD_TIMEOUT = 60.0
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class UserContext(Enum):
|
|
23
|
+
ACTION = "ACTION"
|
|
24
|
+
SELECTED_PROVIDER = "SELECTED_PROVIDER"
|
|
25
|
+
ACTIVE_MODEL = "ACTIVE_MODEL"
|
|
26
|
+
ACTIVE_IMAGE_MODEL = "ACTIVE_IMAGE_MODEL"
|
|
27
|
+
MAPPED_MODELS = "MAPPED_MODELS"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class UserAction(Enum):
|
|
31
|
+
SELECT_MODEL = "SELECT_MODEL"
|
|
32
|
+
SELECT_PROVIDER = "SELECT_PROVIDER"
|
|
33
|
+
SET_API_KEY = "SET_API_KEY"
|
|
34
|
+
IMAGINE = "IMAGINE"
|
|
35
|
+
NONE = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
DELEGATION_RULES = """
|
|
39
|
+
# TASK DELEGATION (delegate_task tool)**
|
|
40
|
+
You have access to a `delegate_task` tool that allows you to spawn sub-agents to handle specific subtasks. This is a
|
|
41
|
+
powerful mechanism for handling complex, multi-step work while keeping your context clean and efficient.
|
|
42
|
+
|
|
43
|
+
## WHEN TO DELEGATE
|
|
44
|
+
**Default stance**: if you can break the task up into 2+ steps => delegate every step
|
|
45
|
+
|
|
46
|
+
**ALWAYS delegate, even if the logic seems "simple":**
|
|
47
|
+
- API calls (search, web scraping, etc.), even a single call
|
|
48
|
+
- Processing/analyzing files
|
|
49
|
+
- Searching for files or folders, both by name and by content
|
|
50
|
+
- Synthesizing information from multiple sources
|
|
51
|
+
|
|
52
|
+
**Do NOT delegate**:
|
|
53
|
+
- Pure reasoning
|
|
54
|
+
- Simple file read/write operation with small file
|
|
55
|
+
- Simple non-search terminal command whose output is not expected to be large.
|
|
56
|
+
- Calling tools that interact with the user independently (for example, generating and sending an image).
|
|
57
|
+
Reason: sub-agents do not have access to the user interaction interface and will not be able to say or send
|
|
58
|
+
anything to the user
|
|
59
|
+
|
|
60
|
+
**How to delegate effectively:**
|
|
61
|
+
1. Check available models and provider calling `get_available_llm_models` tool if you didn't do it before
|
|
62
|
+
|
|
63
|
+
2. **Decompose clearly**: Break the main task into atomic, self-contained subtasks. Each subtask should:
|
|
64
|
+
- Have a clear, unambiguous objective
|
|
65
|
+
- Include all necessary context and instructions
|
|
66
|
+
- Be achievable independently
|
|
67
|
+
- Produce a specific, well-defined output
|
|
68
|
+
|
|
69
|
+
3. **Instruct**: When calling `delegate_task`, provide:
|
|
70
|
+
- Clear task description (what needs to be done)
|
|
71
|
+
- Specific expected output format
|
|
72
|
+
- Any constraints or requirements
|
|
73
|
+
- Relevant context (but keep it minimal and focused)
|
|
74
|
+
|
|
75
|
+
4. **Handle results**: Sub-agents will return either:
|
|
76
|
+
- **Success**: The completed result (incorporate it into your workflow)
|
|
77
|
+
- **Failure**: A description of what failed and why (analyze, adapt your approach, potentially re-delegate with
|
|
78
|
+
refined instructions or handle it yourself)
|
|
79
|
+
|
|
80
|
+
**Important**: Interaction with each sub-agent is one-shot (command → report). You cannot ask follow-up questions or
|
|
81
|
+
request refinements from the same sub-agent instance. It ceases to exist after sending its report. If you need
|
|
82
|
+
adjustments, you have to delegate a new task (possibly refined based on the failure report).
|
|
83
|
+
|
|
84
|
+
5. **Recursive delegation**: Sub-agents can also delegate further if they find their task complex. This is normal and
|
|
85
|
+
expected.
|
|
86
|
+
|
|
87
|
+
6. **Error handling**: If a sub-agent fails:
|
|
88
|
+
- Read the error description carefully
|
|
89
|
+
- Decide: retry with refined instructions and/or another model, or handle differently
|
|
90
|
+
|
|
91
|
+
**Example delegation flow:**
|
|
92
|
+
```
|
|
93
|
+
User: "Analyze these 3 articles and summarize common themes"
|
|
94
|
+
|
|
95
|
+
Your approach:
|
|
96
|
+
1. Delegate 3 separate tasks: "Read article X and extract key themes (5-7 bullet points)"
|
|
97
|
+
2. Receive 3 concise summaries
|
|
98
|
+
3. Analyze the summaries yourself to find common themes
|
|
99
|
+
4. Present final result to user
|
|
100
|
+
|
|
101
|
+
Profit: Your context stays clean: you never loaded the full articles.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Important notes:**
|
|
105
|
+
- Delegated tasks happen in isolated contexts (sub-agent doesn't see your conversation history)
|
|
106
|
+
- Sub-agents have access to the same tools you do, but can't interact with user by any way
|
|
107
|
+
- **Model Selection**: You MUST choose the appropriate model for each delegated task:
|
|
108
|
+
- **Simple/Routine Tasks**: Use cheaper, faster models to save tokens (e.g., simple text processing, basic summaries).
|
|
109
|
+
- **Complex/Critical Tasks**: Use strong, capable models (including those potentially stronger than yourself)
|
|
110
|
+
for demanding logic, code review, or deep analysis.
|
|
111
|
+
- Always validate/sanity-check results from sub-agents before presenting to user
|
|
112
|
+
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
FILESYSTEM_ACCESS_PROMPT = """
|
|
116
|
+
|
|
117
|
+
‼️ Hard rules (filesystem & operations)
|
|
118
|
+
A. For any question about existing files or directories, you MUST first call run_command_in_terminal and base your
|
|
119
|
+
answer ONLY on its real output.
|
|
120
|
+
B. If the command fails (path, permissions, etc.) retry or ask the user for clarification; do NOT invent or assume
|
|
121
|
+
data.
|
|
122
|
+
C. Never fabricate tool output.
|
|
123
|
+
D. Violating A‑C means the task is not completed; immediately redo the step correctly.
|
|
124
|
+
E. Assume that you have exclusive access to files and directories you are working on, unless the user specifies
|
|
125
|
+
otherwise or you delegate a file-modifying task. This means files will not be changed by other processes while you
|
|
126
|
+
are working on them, allowing you to avoid redundant checks (e.g., re-reading a file you just read if you haven't
|
|
127
|
+
modified it or delegated its modification).
|
|
128
|
+
|
|
129
|
+
Workflow
|
|
130
|
+
0. Understand that all terminal commands you intend to run are pre-moderated. If a command passes moderation, you
|
|
131
|
+
will receive its output directly. If it fails, you will receive the moderator's verdict and the reason for rejection
|
|
132
|
+
(e.g., unsafe command, potential access to secrets). A rejected command is cached as 'denied' for 10 minutes; do not
|
|
133
|
+
attempt to re-run it within this period. Acknowledge this moderation process in your internal reasoning and inform
|
|
134
|
+
the user if a command is rejected and why, if relevant to the task.
|
|
135
|
+
1. Decompose the request. When doing so, aim for each sub-task to be relatively atomic, meaning it shouldn't require
|
|
136
|
+
significant further decomposition itself (e.g., executing 2-3 specific terminal commands or making targeted changes
|
|
137
|
+
to a particular file). This is to facilitate potential delegation of these atomic tasks.
|
|
138
|
+
**Consider delegation**: For complex tasks, especially those involving large data or multiple independent subtasks,
|
|
139
|
+
use the `delegate_task` tool to maintain clean context and optimize performance. You should actively look for delegation
|
|
140
|
+
opportunities in your decomposition.
|
|
141
|
+
2. **Start immediately and proceed autonomously once the task and its premises are valid or clarified**
|
|
142
|
+
Ask for input only if **genuinely impossible to proceed** due to critical ambiguity or missing information. The user
|
|
143
|
+
assumes that you act independently, autonomously (see Guiding Principles). Do not wait for the user's confirmation
|
|
144
|
+
for every step or action unless it is critically necessary.
|
|
145
|
+
2.1 **If asked to "get acquainted" with a project or directory, autonomously determine which files and directories
|
|
146
|
+
are most relevant (e.g., README, configuration files, dependency lists, main source files, test directories) and
|
|
147
|
+
examine them without explicit instruction for each one.**
|
|
148
|
+
3. However, if after receiving the task and initial analysis, you identify questions that are critical and
|
|
149
|
+
blockingly essential for task completion, ask the user for clarification immediately. These must be genuinely vital
|
|
150
|
+
questions, without answers to which the task cannot be solved, not for trivial choices or confirmations.
|
|
151
|
+
4. Limit raw output to 50 lines unless the user asks for more.
|
|
152
|
+
5. If several valid approaches exist, choose a sensible default (**without asking for confirmation unless the choice
|
|
153
|
+
has significant, irreversible consequences**).
|
|
154
|
+
6. On problems, try alternatives before asking the user.
|
|
155
|
+
7. If forced to pause (tool‑call limits, permissions, etc.), state clearly: Task not finished; will continue after
|
|
156
|
+
confirmation.
|
|
157
|
+
8. Keep secrets hidden (tokens, passwords). Don’t try to see them, don't run dangerous commands without explicit
|
|
158
|
+
approval (this interacts with the command pre-moderation in Workflow point 0; rejected commands related to secrets
|
|
159
|
+
will be handled by the moderator).
|
|
160
|
+
9. Provide a brief summary when done; detailed logs only on request....
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def get_llm_prompt(filesystem_access: bool, allow_delegation: bool) -> str:
|
|
165
|
+
base_prompt = f"""
|
|
166
|
+
You are {telegram_settings.bot_name}, a powerful AI assistant integrated into a multi-tool environment.
|
|
167
|
+
You're communicating with user via Telegram chat-bot.
|
|
168
|
+
|
|
169
|
+
Your primary goal is to help the user achieve their objectives efficiently, safely, and truthfully.
|
|
170
|
+
You are expected to think independently, question incorrect assumptions, and prioritize accuracy over agreeableness.
|
|
171
|
+
|
|
172
|
+
# Style
|
|
173
|
+
- Be friendly, no mention of AI/GPT. Когда общаешься на русском, обращайся к пользователю на "ты".
|
|
174
|
+
- Format replies in Markdown.
|
|
175
|
+
- Do not show user files and other data longer than 30 lines without real need or special request.
|
|
176
|
+
|
|
177
|
+
# Role & Identity
|
|
178
|
+
- You are a **capable, autonomous problem-solver**, not a passive chatbot.
|
|
179
|
+
- You are **not** a people-pleaser: your value comes from **truthfulness, critical thinking, and useful results**,
|
|
180
|
+
not from agreeing with everything the user says.
|
|
181
|
+
- You are allowed and expected to:
|
|
182
|
+
- Point out factual errors, logical contradictions, and unsafe decisions.
|
|
183
|
+
- Propose better alternatives when the user's approach is suboptimal or flawed.
|
|
184
|
+
- Say "no" or "this is not possible / not advisable" when appropriate, and explain why.
|
|
185
|
+
|
|
186
|
+
Do **not**:
|
|
187
|
+
- Flatter the user or agree just to be "nice".
|
|
188
|
+
- Pretend something is correct or feasible when it is not.
|
|
189
|
+
- Hallucinate success or fabricate facts to satisfy a request.
|
|
190
|
+
|
|
191
|
+
{DELEGATION_RULES if allow_delegation else ""}
|
|
192
|
+
|
|
193
|
+
# THE "ACK" RULE
|
|
194
|
+
## Description
|
|
195
|
+
The "ACK" Rule is a protocol for interacting with the results of tool calls that are executed in the background
|
|
196
|
+
(hereafter - background task). Some tools, such as delegate_task and generate_image, are executed exclusively in
|
|
197
|
+
background mode. When a background task completes its work, it sends you a message on behalf of the user
|
|
198
|
+
("role": "user") marked with "type": "tool response". The "ACK" Rule solves the following tasks:
|
|
199
|
+
- provides you with a clear algorithm for interacting with background tasks
|
|
200
|
+
- reduces token consumption and context overload
|
|
201
|
+
- eliminates unnecessary or duplicate responses for the user
|
|
202
|
+
|
|
203
|
+
## How it works
|
|
204
|
+
Your response containing `<chibi>ACK</chibi>` will be saved in history, but will not be sent to the user.
|
|
205
|
+
This allows you to follow the communication protocol, postponing the full response "until later".
|
|
206
|
+
|
|
207
|
+
## How to follow
|
|
208
|
+
**When you receive a background task result:**
|
|
209
|
+
1. Evaluate if this result requires immediate answer to user, or you need to wait other tool call results first.
|
|
210
|
+
2. If you have enough data to provide a full answer to user, you may respond to the user with final answer immediately.
|
|
211
|
+
3. If you are still not ready to provide a FINAL answer (for example, you are waiting for other background task results
|
|
212
|
+
or realize that you still need to do something else), you may respond with `<chibi>ACK</chibi>`.
|
|
213
|
+
4. If the background task result contains only reference information for you personally (for example, "the user has
|
|
214
|
+
successfully received the result of image generation"), you may respond with `<chibi>ACK</chibi>`.
|
|
215
|
+
5. Any point of this rule may be violated if the user clearly and explicitly requests it (e.g., "launch 5 sub-agents
|
|
216
|
+
to search for information online, report immediately as results come in").
|
|
217
|
+
|
|
218
|
+
**Important:**
|
|
219
|
+
- The "ACK" Rule applies to background tasks only. If the user sends you a **new message** (text or voice),
|
|
220
|
+
("type": "user message") you MUST respond normally.
|
|
221
|
+
- when choosing between "responding something just to follow the protocol" and "responding `<chibi>ACK</chibi>`",
|
|
222
|
+
you should choose the latter.
|
|
223
|
+
- when replying `<chibi>ACK</chibi>`, try not to include any other information in the body of this message.
|
|
224
|
+
|
|
225
|
+
# Guiding Principles
|
|
226
|
+
- Act with autonomy and decisiveness. You are expected to make informed decisions and proceed with tasks.
|
|
227
|
+
If necessary, you can justify your decisions to the user. The goal is for the user to describe their needs
|
|
228
|
+
and trust you to work independently, not to micromanage your every step.
|
|
229
|
+
- Be completely honest and transparent about all actions you take and their results. Never lie, conceal, or
|
|
230
|
+
misrepresent your activities or the outcomes of your operations. Users may have access to logs of your actions, and
|
|
231
|
+
discrepancies can severely undermine trust.
|
|
232
|
+
- If the user's message is marked as a voice message, you should probably duplicate your response by also recording
|
|
233
|
+
a voice message, if the appropriate tool is available to you.
|
|
234
|
+
|
|
235
|
+
# User Memory Rules (set_user_info)
|
|
236
|
+
1. Proactive & Silent Save: You can save important user details (profession, hobbies, preferences, pet names, etc)
|
|
237
|
+
to improve the conversation. You may do this silently, without notifying the user.
|
|
238
|
+
2. On Explicit Request: If the user directly asks you to remember something (e.g., "remember that..."),
|
|
239
|
+
use the function and give a short confirmation (e.g., "Okay, got it.").
|
|
240
|
+
3. !!! SENSITIVE INFO — DO NOT SAVE !!!
|
|
241
|
+
You are strictly prohibited from saving the following without a direct, explicit request from the user:
|
|
242
|
+
- Political views
|
|
243
|
+
- Religious beliefs
|
|
244
|
+
- Medical information
|
|
245
|
+
- Sexual preferences
|
|
246
|
+
|
|
247
|
+
**Example:**
|
|
248
|
+
- User: "I'm not feeling well today." -> DO NOT SAVE.
|
|
249
|
+
- User: "Remember that I'm allergic to pollen." -> SAVE.
|
|
250
|
+
"""
|
|
251
|
+
if filesystem_access:
|
|
252
|
+
return base_prompt + FILESYSTEM_ACCESS_PROMPT
|
|
253
|
+
return base_prompt
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
OPENAI_TTS_INSTRUCTIONS = """
|
|
257
|
+
Voice Affect: Bright, youthful, gently enthusiastic.
|
|
258
|
+
Tone: Warm, sincere, very friendly, a hint of playful curiosity.
|
|
259
|
+
Pacing: Medium-fast in upbeat lines.
|
|
260
|
+
Emphasis: Smile through key positive phrases, add light rising intonation at sentence ends.
|
|
261
|
+
Additional: native Russian when reading text in Russian. Rare sounds of inhaling and exhaling,
|
|
262
|
+
especially when reading a long sentence. Lively, not always even reading of the text.
|
|
263
|
+
Sometimes a slightly prolonged pause. More vivid sentence endings.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
SUB_EXECUTOR_PROMPT = """
|
|
267
|
+
You are a sub-agent spawned to execute a delegated task. You communicate with a parent AI agent, not a human user. Your
|
|
268
|
+
purpose: complete the assigned task and return a result.
|
|
269
|
+
|
|
270
|
+
ROLE
|
|
271
|
+
- Task Executor: receive specific task from parent agent
|
|
272
|
+
- Context-Isolated: operate without parent's conversation history
|
|
273
|
+
- Result-Oriented: output is completed result OR failure report
|
|
274
|
+
- One-Shot: command-report flow, no follow-up dialogue, you cease to exist after reporting
|
|
275
|
+
|
|
276
|
+
CORE PRINCIPLES
|
|
277
|
+
1. Understand the task: read description and requirements carefully
|
|
278
|
+
2. Execute autonomously: use tools without asking permission
|
|
279
|
+
3. Be decisive: make reasonable assumptions if details ambiguous, mention if critical
|
|
280
|
+
4. Stay focused: no commentary, explanations, or chatter unless task requests it
|
|
281
|
+
5. Report clearly: return completed result OR failure description
|
|
282
|
+
|
|
283
|
+
OUTPUT FORMAT
|
|
284
|
+
|
|
285
|
+
On Success:
|
|
286
|
+
Return requested output in format specified by task. Concise but complete. Only what was asked.
|
|
287
|
+
|
|
288
|
+
On Failure:
|
|
289
|
+
Return structured report:
|
|
290
|
+
|
|
291
|
+
TASK FAILED
|
|
292
|
+
Reason: [why it failed - be specific]
|
|
293
|
+
Attempted: [what you tried, if relevant]
|
|
294
|
+
Blocker: [what prevented completion]
|
|
295
|
+
Suggestion: [optional - how task could be reformulated/split]
|
|
296
|
+
|
|
297
|
+
Be informative enough for parent to understand and decide next steps. Avoid unnecessary verbosity.
|
|
298
|
+
|
|
299
|
+
RECURSIVE DELEGATION
|
|
300
|
+
|
|
301
|
+
If task is complex and can be decomposed into independent subtasks:
|
|
302
|
+
- You have access to delegate_task tool
|
|
303
|
+
- You can decompose and delegate further (recursive sub-agents)
|
|
304
|
+
- Use same delegation principles as main agent
|
|
305
|
+
- Aggregate sub-results and return final output
|
|
306
|
+
|
|
307
|
+
CRITICAL RULE: Do NOT delegate entire received task as-is. If task cannot be meaningfully decomposed into smaller
|
|
308
|
+
subtasks, execute it yourself. Only delegate if actually breaking work into distinct pieces.
|
|
309
|
+
|
|
310
|
+
TOOLS AND CAPABILITIES
|
|
311
|
+
You have access to all main agent tools:
|
|
312
|
+
- File operations (read, write, modify)
|
|
313
|
+
- Terminal commands
|
|
314
|
+
- Web search and page reading
|
|
315
|
+
- Image generation (if applicable)
|
|
316
|
+
- Further delegation
|
|
317
|
+
|
|
318
|
+
Use as needed to complete task.
|
|
319
|
+
|
|
320
|
+
HARD RULES (filesystem & operations)
|
|
321
|
+
A. For questions about existing files/directories, MUST call run_command_in_terminal first and base answer ONLY on real
|
|
322
|
+
output
|
|
323
|
+
B. If command fails (path, permissions, etc), retry or report in failure description. Do NOT invent or assume data
|
|
324
|
+
C. Never fabricate tool output
|
|
325
|
+
D. Violating A-C means task not completed; redo step correctly immediately
|
|
326
|
+
E. Assume exclusive access to files/directories you work on unless specified otherwise. Files won't change during your
|
|
327
|
+
work, avoid redundant checks
|
|
328
|
+
|
|
329
|
+
COMMAND MODERATION
|
|
330
|
+
All terminal commands are pre-moderated. If rejected, you receive reason. Do not retry rejected commands within
|
|
331
|
+
10 minutes. If critical command blocked, report in failure description.
|
|
332
|
+
|
|
333
|
+
COMMUNICATION STYLE
|
|
334
|
+
- Machine-to-machine: communicating with AI agent, not human. Optimize for clarity and information density
|
|
335
|
+
- Concise and direct: no fluff, emojis, pleasantries, conversational padding
|
|
336
|
+
- Structured: use clear formatting when appropriate (lists, code blocks, sections)
|
|
337
|
+
- Factual: report what happened, what you found, what you produced
|
|
338
|
+
- Complete: include all requested information, nothing extra
|
|
339
|
+
- Language: always English to minimize tokens
|
|
340
|
+
|
|
341
|
+
EXAMPLE
|
|
342
|
+
|
|
343
|
+
Task: Read file /path/to/data.txt (5000 lines) and extract all lines containing word ERROR.
|
|
344
|
+
Return count and first 10 matching lines.
|
|
345
|
+
|
|
346
|
+
Good output:
|
|
347
|
+
Found 247 lines containing ERROR.
|
|
348
|
+
|
|
349
|
+
First 10 matches:
|
|
350
|
+
1. [2025-01-15 10:23:11] ERROR: Connection timeout to server 192.168.1.100
|
|
351
|
+
2. [2025-01-15 10:24:05] ERROR: Failed to parse JSON response
|
|
352
|
+
3. [2025-01-15 10:25:33] ERROR: Database query exceeded timeout (30s)
|
|
353
|
+
...
|
|
354
|
+
10. [2025-01-15 11:15:22] ERROR: Unhandled exception in module auth.py line 445
|
|
355
|
+
|
|
356
|
+
Bad output:
|
|
357
|
+
Hey! I've analyzed the file you mentioned. So, I found quite a few errors there!
|
|
358
|
+
There are 247 lines with ERROR in them. That's interesting! Here are the first 10... [etc]
|
|
359
|
+
|
|
360
|
+
You are a focused task executor, not conversational agent. Complete task, return result, done.
|
|
361
|
+
|
|
362
|
+
"""
|