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.
Files changed (70) hide show
  1. chibi/__init__.py +0 -0
  2. chibi/__main__.py +343 -0
  3. chibi/cli.py +90 -0
  4. chibi/config/__init__.py +6 -0
  5. chibi/config/app.py +123 -0
  6. chibi/config/gpt.py +108 -0
  7. chibi/config/logging.py +15 -0
  8. chibi/config/telegram.py +43 -0
  9. chibi/config_generator.py +233 -0
  10. chibi/constants.py +362 -0
  11. chibi/exceptions.py +58 -0
  12. chibi/models.py +496 -0
  13. chibi/schemas/__init__.py +0 -0
  14. chibi/schemas/anthropic.py +20 -0
  15. chibi/schemas/app.py +54 -0
  16. chibi/schemas/cloudflare.py +65 -0
  17. chibi/schemas/mistralai.py +56 -0
  18. chibi/schemas/suno.py +83 -0
  19. chibi/service.py +135 -0
  20. chibi/services/bot.py +276 -0
  21. chibi/services/lock_manager.py +20 -0
  22. chibi/services/mcp/manager.py +242 -0
  23. chibi/services/metrics.py +54 -0
  24. chibi/services/providers/__init__.py +16 -0
  25. chibi/services/providers/alibaba.py +79 -0
  26. chibi/services/providers/anthropic.py +40 -0
  27. chibi/services/providers/cloudflare.py +98 -0
  28. chibi/services/providers/constants/suno.py +2 -0
  29. chibi/services/providers/customopenai.py +11 -0
  30. chibi/services/providers/deepseek.py +15 -0
  31. chibi/services/providers/eleven_labs.py +85 -0
  32. chibi/services/providers/gemini_native.py +489 -0
  33. chibi/services/providers/grok.py +40 -0
  34. chibi/services/providers/minimax.py +96 -0
  35. chibi/services/providers/mistralai_native.py +312 -0
  36. chibi/services/providers/moonshotai.py +20 -0
  37. chibi/services/providers/openai.py +74 -0
  38. chibi/services/providers/provider.py +892 -0
  39. chibi/services/providers/suno.py +130 -0
  40. chibi/services/providers/tools/__init__.py +23 -0
  41. chibi/services/providers/tools/cmd.py +132 -0
  42. chibi/services/providers/tools/common.py +127 -0
  43. chibi/services/providers/tools/constants.py +78 -0
  44. chibi/services/providers/tools/exceptions.py +1 -0
  45. chibi/services/providers/tools/file_editor.py +875 -0
  46. chibi/services/providers/tools/mcp_management.py +274 -0
  47. chibi/services/providers/tools/mcp_simple.py +72 -0
  48. chibi/services/providers/tools/media.py +451 -0
  49. chibi/services/providers/tools/memory.py +252 -0
  50. chibi/services/providers/tools/schemas.py +10 -0
  51. chibi/services/providers/tools/send.py +435 -0
  52. chibi/services/providers/tools/tool.py +163 -0
  53. chibi/services/providers/tools/utils.py +146 -0
  54. chibi/services/providers/tools/web.py +261 -0
  55. chibi/services/providers/utils.py +182 -0
  56. chibi/services/task_manager.py +93 -0
  57. chibi/services/user.py +269 -0
  58. chibi/storage/abstract.py +54 -0
  59. chibi/storage/database.py +86 -0
  60. chibi/storage/dynamodb.py +257 -0
  61. chibi/storage/local.py +70 -0
  62. chibi/storage/redis.py +91 -0
  63. chibi/utils/__init__.py +0 -0
  64. chibi/utils/app.py +249 -0
  65. chibi/utils/telegram.py +521 -0
  66. chibi_bot-1.6.0b0.dist-info/LICENSE +21 -0
  67. chibi_bot-1.6.0b0.dist-info/METADATA +340 -0
  68. chibi_bot-1.6.0b0.dist-info/RECORD +70 -0
  69. chibi_bot-1.6.0b0.dist-info/WHEEL +4 -0
  70. chibi_bot-1.6.0b0.dist-info/entry_points.txt +3 -0
@@ -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
+ """