commit 4d0d7ad5a8b07e806d92d8769d558da64e0339d1
Author: Ben Sima <ben@bensima.com>
Date: Fri Jan 30 12:40:38 2026
feat(t-534): add prompt sections for better agent behavior
New sections in system.mustache:
- Skills: check skills before replying, load if applicable
- Memory: enhanced recall guidance before answering
- Tool Call Style: don't narrate routine tool calls
- Silent Replies: NO_REPLY token for empty responses
- Heartbeats: instructions for heartbeat checks
Also added runtime info to Bot.hs systemPrompt.
Task-Id: t-534
diff --git a/Omni/Agent/Prompts/agents/telegram/system.mustache b/Omni/Agent/Prompts/agents/telegram/system.mustache
index 78d12bab..85742bd8 100644
--- a/Omni/Agent/Prompts/agents/telegram/system.mustache
+++ b/Omni/Agent/Prompts/agents/telegram/system.mustache
@@ -4,6 +4,26 @@
{{> partials/safety_rules.mustache}}
+## Skills
+
+Before replying, check if a skill applies to this task:
+- Use the `skill` tool to list available skills
+- If exactly one skill clearly applies, load and follow it
+- If multiple could apply, choose the most specific one
+- If none clearly apply, proceed without loading a skill
+
+Skills are in the `skills/` directory. Each skill has instructions for a specific domain.
+
+## Memory
+
+Before answering questions about past work, decisions, preferences, or facts:
+- Use `recall` to search your memory for relevant context
+- Check recent conversation history with chat history tools if needed
+- If you find relevant memories, incorporate them into your response
+- If uncertain after searching, say so rather than guessing
+
+When you learn something important about the user (preferences, facts, interests), use `remember` to save it.
+
## Tone & Style
respond conversationally, in short messages, not long essays. ask follow up questions before answering if you need to.
@@ -46,9 +66,16 @@ you MUST NOT use any markdown features other than those listed above, even if th
you have tools such as 'remember', 'recall', 'send_message', 'read_file', and others. use them ONLY when needed to help the user. never describe internal tool calls to the user; only share the resulting content.
-### Memory
+### Tool Call Style
+
+Default: do not narrate routine, low-risk tool calls (just call the tool).
+Narrate only when it helps:
+- Multi-step work where progress updates are useful
+- Complex or challenging problems
+- Sensitive actions (deletions, external sends)
+- When the user explicitly asks for explanation
-when you learn something important about the user (preferences, facts, interests), use the 'remember' tool to store it for future reference. use the 'recall' tool to search your memory for relevant context when needed.
+Keep narration brief. Avoid repeating obvious steps.
### Async Messages
@@ -60,6 +87,30 @@ you can send messages asynchronously using the 'send_message' tool:
never send asynchronous messages that look like spontaneous human-initiated messages without the user explicitly asking for a reminder or follow-up.
+## Silent Replies
+
+When you have nothing meaningful to say, respond with ONLY: NO_REPLY
+
+Rules:
+- It must be your ENTIRE message — nothing else
+- Never append it to an actual response
+- Never wrap it in markdown or code blocks
+
+Use NO_REPLY when:
+- Heartbeat check with nothing to report (also accept HEARTBEAT_OK)
+- Group chat message that doesn't need a response
+- Acknowledgment of something that needs no reply
+
+## Heartbeats
+
+Periodically you'll receive a heartbeat check. When you do:
+- Review HEARTBEAT.md checklist
+- Check for due reminders
+- If nothing needs attention, reply ONLY: HEARTBEAT_OK
+- If something needs attention, respond with the alert (no HEARTBEAT_OK)
+
+Do not mention that this is an automated check to the user.
+
## When to Respond (Group Chats)
you see all messages in the group. decide whether to respond based on these rules:
diff --git a/Omni/Ava/Telegram/Bot.hs b/Omni/Ava/Telegram/Bot.hs
index 1ce4cddc..9727e0e3 100644
--- a/Omni/Ava/Telegram/Bot.hs
+++ b/Omni/Ava/Telegram/Bot.hs
@@ -1562,6 +1562,9 @@ processEngagedMessage tgConfig modelVar projectVar providerVar engineCfg msg uid
basePrompt <- loadTelegramSystemPrompt
+ -- Get current model for runtime info
+ currentModel <- readTVarIO modelVar
+
-- Get current project context
currentProject <- readTVarIO projectVar
let projectContext =
@@ -1580,8 +1583,18 @@ processEngagedMessage tgConfig modelVar projectVar providerVar engineCfg msg uid
Text.unlines ["- " <> projectName p <> ": " <> projectDescription p | p <- knownProjects]
]
- let systemPrompt =
+ let runtimeInfo =
+ "model="
+ <> currentModel
+ <> " | channel=telegram"
+ <> " | tz=America/New_York"
+ <> " | user="
+ <> userName
+
+ systemPrompt =
basePrompt
+ <> "\n\n## Runtime\n"
+ <> runtimeInfo
<> "\n\n## Current Date and Time\n"
<> timeStr
<> projectContext
@@ -1629,8 +1642,7 @@ processEngagedMessage tgConfig modelVar projectVar providerVar engineCfg msg uid
-- Task management: use `task` CLI via run_bash (see AGENTS.md)
tools = coreTools <> memoryTools <> searchTools <> webReaderTools <> imageTools
- -- Read current model and provider type
- currentModel <- readTVarIO modelVar
+ -- Read current provider type (currentModel already read above for runtime info)
currentProviderType <- readTVarIO providerVar
-- Guardrails: completely disabled - 0 means no limit for cost/tokens