System Prompt
Every LLM call in MushroomAgent is preceded by a system prompt assembled from multiple layers. This page documents each layer and its contents.
Assembly order
The system prompt is built by assemble_system_prompt_messages() in a fixed order. Earlier layers appear first in the context window. The prompt includes 5 distinct layers:
Layer 1: Fixed skeleton
Defined in the build_fixed_system_prompt() function. This is the core prompt structure:
You are a conversational AI assistant.
Conditional sections — included only when relevant data exists:
| Section | When included | Content |
|---|---|---|
| User | When a user name is known | "You are currently talking to: {user_name}" |
| Persona | When personality is configured | The configured personality description |
| Skills | When skills are enabled | Available skills list with selection rules (see below) |
| Knowledge Context | When memory retrieval returns knowledge | Authoritative retrieved knowledge snippets |
| Conversation Summary | When yesterday's conversations were summarized | Structured summary of past conversation topics |
| Response Format | When response_format="json_object" | Instruction to return valid JSON |
Layer 2: Runtime facts
Injected as a ## Runtime Facts block. Contains live information about the current turn:
- Agent ID and name
- Remote user ID and name
- Incoming channel, channel user ID, chat type, group ID
- Current time and time zone
- Workspace path
- Heartbeat run flag
- Custom turn variables from the message
Layer 3: Workspace context
If workspace context files exist and agent.skip_context_files is not set, their contents are injected:
# Workspace Context
- Workspace root: /path/to/workspace
- These files are raw workspace context. Apply them when relevant.
## AGENTS.md
- Purpose: project rules, operating constraints, and execution boundaries.
\{contents}
## SOUL.md
- Purpose: persona and tone. If present, embody its voice and style.
\{contents}
## IDENTITY.md
- Purpose: canonical self-identity, role, and self-description.
\{contents}
Files are loaded in order and subject to truncation (4000 chars per file, 12000 total).
Layer 4: Heartbeat context
Only injected for heartbeat-triggered turns. Contains the heartbeat protocol guidance instructing the agent to evaluate whether proactive engagement is needed. If no meaningful reason exists, the agent should reply HEARTBEAT_OK.
Layer 5: Ephemeral system prompt
A per-turn instruction string from agent.ephemeral_system_prompt in config. Used for:
- Sub-agents: the
delegate_tasktool sets this to define the task scope - Temporary overrides: any one-off instruction that shouldn't persist
This layer is NOT persisted to conversation history.
Skills in the prompt
When skills are enabled, the skeleton includes:
## Skills
Treat skills as instruction documents, not callable tools or functions.
### Selection Rules
- Scan <available_skills> descriptions before deciding.
- Never call a skill name as a tool.
- If exactly one skill clearly applies: read its SKILL.md...
- Never read more than one skill up front.
### Available Skills
<available_skills>
<skill>
<name>skill_name</name>
<description>...</description>
<location>/path/to/SKILL.md</location>
</skill>
</available_skills>
The skills list is filtered through allowlist/blocklist and includes only enabled skills. The agent is instructed to read the relevant SKILL.md on demand — skills are NOT pre-loaded into the prompt.
Customizing
- Persona: set in config or via
SOUL.mdworkspace file - Rules and constraints: write
AGENTS.mdin the workspace - Identity: write
IDENTITY.mdin the workspace - Temporary instructions: set
agent.ephemeral_system_promptin config - Skip workspace context: set
agent.skip_context_files: true