MAESTROBOT
Configuration
MaestroBot keeps static operator-authored config in config.yaml under
the runtime root.
The file is real YAML and is written in a stable, human-oriented layout so operators can edit it directly.
Top-Level Sections
service
nameLogical service name. Defaults tomaestrobot.
runtime
resident_limitMax number of resident channel contexts.scheduler_workersMax number of channel runs the daemon may execute concurrently. Each individual channel still executes serially.scheduler_tickScheduler polling interval.default_timeout_secondsDefault foreground timeout after finalization.default_sleep_secondsDefault sleep threshold used during channel finalization.llm_timeout_secondsShared timeout in seconds for MaestroBot LLM API calls and generated Myria LLM request timeouts.log_levelHost log level and generated Myria log level.
onboarding
notice_limitNumber of deterministic onboarding notices an unknown external account may trigger before the daemon silently ignores that account until it is attached. Defaults to3.archive_after_hoursHours after the last observed message before an unresolved unknown identity moves from the active list to the archive list. Defaults to24.notice_messageFixed notice sent by the runtime/frontend gate to unknown accounts. This is not generated by the agent and does not enter the agent loop.
The daemon always writes structured JSON logs to logs/service.log.
When a chat request asks for verbose tracing, the daemon attaches a
channel-run trace_id and emits prompt, LLM, tool, and finalization
events into that same log. The CLI only filters and streams those
daemon-produced events.
Prompt composition now lives under the runtime-root maestro/
directory:
channel_loop.mstrsubagent_loop.mstr
The host runtime injects the structured runtime sections, but the prompt layout, ordering, and most operator-facing wording live in those user-editable Maestro files, with prompt text embedded directly in the schema source rather than separate Markdown templates.
SOUL.md is the exclusive identity file. Put the agent’s name, voice,
persona, and standing preferences there. Keep maestro/*.mstr
identity-neutral: those files should define operating behavior and tool
flow, not who the agent is. The daemon logs a warning if SOUL.md is
missing or empty.
The same Maestro files select the state-local host surface. They can
request tool groups such as @plan, @workspace, @web, @browser,
@myria, or exact tool names, and they can request a bounded list of
context sections for the prompt. The daemon expands those schema
requests against the available runtime catalog and fails fast on unknown
required tools.
providers
- keyed provider map
- v1 expects an
openrouterentry with:base_urlapi_key
profile
Controls durable user-profile memory injected into agent context.
autonomous_updatesAllows the agent to update known users’ profiles through the host-validated profile tool.max_bytesMaximum size of oneusers/<user-id>/profile.mdfile. The default is20480.max_bulletsMaximum number of profile bullets retained across all profile sections. The default is200.
Profiles are for stable preferences, constraints, communication style, and stable user facts. They are not transcript history, task history, or secret storage.
presets
Concrete model presets keyed by preset id.
Each concrete preset defines:
- provider id
- model id
- provider sort preference
- context limit in tokens
- reasoning profile
- short description of capability and speed tradeoffs
sort controls OpenRouter provider ordering for that preset. Supported values are:
defaultKeep OpenRouter’s default routing and load balancing behavior.exactoPrefer OpenRouter’s quality-first route selection.pricePrefer the lowest-price provider.throughputPrefer the highest-throughput provider.latencyPrefer the lowest-latency provider.
MaestroBot does not pin a concrete OpenRouter provider. It passes only
the configured model and optional provider sort, then lets OpenRouter
choose the route. Cache hits still depend on the selected provider and
model route. MaestroBot sends stable operating instructions as the first
message and high-churn runtime context as the final message to improve
provider-side prompt-cache reuse. maestrobot models cache runs a
two-request cache probe for each
preset and reports cached input and cache-write tokens.
context_limit_tokens caps the prompt, tool-definition, and safety
margin budget MaestroBot will send to the model for that preset. The
generated default is 262144. Lower it for models with smaller context
windows. Before an LLM request, MaestroBot performs deterministic
compaction of high-growth context sections and rejects the request if it
still cannot fit under the preset cap.
preset_refs
quickhighsubagent_high
These are references to entries under presets.
starting-model is not a config entry. It is a runtime-attached
selection chosen from the referenced preset descriptions when a
subagent starts.
myria
config_pathRelative path to generatedmyria/myria.jsonunder the runtime root.template_pathRelative path to the generated OpenRouter request template.postgres_dsnOptional PostgreSQL DSN for Myria.schemaPostgreSQL schema name.log_fileRuntime log file path for the supervised Myria process.max_tool_roundsMax Myria tool-call rounds written to the generated Myria config.structured_tool_callsWhether the generated Myria config requires structured tool calls.
MaestroBot installs the needed runtime binaries under <root>/bin/ and
does not require operator-authored repo paths in config.yaml. The
daemon uses:
<root>/bin/maestrocto compile the root-localmaestro/source<root>/bin/myriato supervise the Myria subprocess
The actual Myria config and OpenRouter request template are generated
from config.yaml during init, preflight tests, and daemon startup.
Treat files under <root>/myria/ as derived runtime files.
tools
- optional map of external MCP servers
- each server may define:
transportcommandurlheadersworkdirenvdescriptionmanifestsource
These servers can also be registered and removed dynamically through the daemon:
maestrobot tools register-stdio example --description "Example MCP server" -- /abs/path/server --stdio
maestrobot tools register-remote remote-example --transport streamable-http --url https://example.invalid/mcp
maestrobot tools discover --path .
maestrobot tools import-manifest /abs/path/mcp.json example
maestrobot tools inspect example
maestrobot tools enable example
maestrobot tools disable example
maestrobot tools remove example
Discovery currently understands:
- dedicated JSON manifests such as
mcp.json,.mcp.json, andmcp-server.json - Claude-style
claude_desktop_config.jsonfiles withmcpServers
Supported external MCP transports are:
stdiostreamable-httpsse
Separate from configured external tool servers, MaestroBot also ships a
built-in internal.* developer tool surface for:
- VFS inspection and mutation
- recursive file search
- synchronous command execution
- long-running command sessions with stdin/poll/wait/kill control
- Playwright-backed browser sessions
- direct web fetch/search
- image metadata and OCR
The Playwright runtime stores its driver, browser binaries, and browser artifacts under:
<root>/cache/playwright/driver<root>/cache/playwright/browsers<root>/cache/playwright/screenshots
frontends
- keyed frontend map
- built-in frontend types:
local-clitelegram
Telegram frontend fields:
telegram.bot_tokenBot token used for Bot API polling and delivery.telegram.api_base_urlBot API base URL. Defaults tohttps://api.telegram.org.telegram.poll_interval_secondsDelay between poll attempts.telegram.long_poll_secondsLong-poll timeout used bygetUpdates.telegram.prefer_entitiesPrefertext + entitiesoutput over parse-mode HTML.telegram.allow_html_fallbackAllow HTML parse-mode fallback when entity rendering fails.telegram.preserve_code_languagePreserve fenced-code language metadata when rendering Telegram code blocks.telegram.max_message_unitsMax Telegram message size in UTF-16 code units.telegram.allowed_chat_idsOptional hard safety allow-list of Telegram chat ids. This is not the normal onboarding mechanism. With no allow-list, unknown Telegram DMs can still be discovered, rate-limited, and listed for operator attachment.
Telegram output is rendered from canonical Markdown through a dedicated frontend pipeline. The runtime does not ask the agent to produce Telegram-specific output directly.
While a Telegram-backed channel run is active, the frontend also sends a
Telegram typing chat action until the run delivers its reply or
finalizes.
Bootstrap
The simplest bootstrap flow is:
maestrobot init --workspace-root . --openrouter-api-key "$OPENROUTER_API_KEY" --model "$MAESTROBOT_MODEL"
maestrobot init --workspace-root . --openrouter-api-key "$OPENROUTER_API_KEY" --model "$MAESTROBOT_MODEL" --telegram-bot-token "$TELEGRAM_BOT_TOKEN"
After bootstrap, the intended setup surface is only:
$EDITOR ~/.maestrobot/config.yaml
$EDITOR ~/.maestrobot/SOUL.md
maestrobot doctor
Edit config.yaml for deployment mechanics: provider credentials,
model presets, frontends, onboarding policy, runtime limits, and
optional tools. Edit SOUL.md for identity, voice, and standing
preferences. maestrobot doctor checks the edited files and live
service prerequisites before the daemon starts.
That command:
- creates the runtime root
- writes
config.yaml - creates
state.json - writes
SOUL.md - writes
runtime.yaml - seeds
<root>/maestro/with editable default Maestro programs - writes the OpenRouter request template for Myria
- writes a default
myria/myria.json
Runtime Config
Mutable desired runtime config lives in runtime.yaml, not
config.yaml.
Current user entries look like:
users:
-
id: usr_k7m4x9q2p8vd
name: Ada Lovelace
Internal user IDs are generated randomly when you run:
maestrobot user onboard "Ada Lovelace"
External accounts are attached separately:
maestrobot user unknown
maestrobot user attach usr_k7m4x9q2p8vd unknown-0001
The account-to-user mapping is observed daemon state in state.json.
That split keeps names and stable internal users editable while keeping
platform account discovery and queue state daemon-owned.
Myria Storage
For the current MaestroBot version, SQLite is written as the default backend only for convenience. It gives a persistent local file-backed setup with minimal operator work. It should be treated as the easiest bootstrap mode, not as a statement that Myria is architecturally SQLite-first.
Default generated values:
storage.kind = "sqlite"sqlite.path = "<root>/myria/myria.sqlite3"
The SQLite backend is file-backed and persists across restarts. The
generated Myria files are derived from MaestroBot config and may be
rewritten by maestrobot init, maestrobot test, and daemon startup.