Configuration Reference¶
MiniBot is configured via a config.toml file.
Start from the provided example:
cp config.example.toml config.toml
Values follow standard TOML syntax. Byte-size fields accept human-readable
strings (e.g. "64KB", "5MB") in addition to raw integers.
Runtime¶
- class minibot.adapters.config.schema.RuntimeConfig(*, log_level: str = 'INFO', environment: str = 'development', agent_timeout_seconds: Annotated[int, Ge(ge=120)] = 120)¶
Top-level runtime settings. TOML section:
[runtime]log_level— root log level (default:"INFO").environment— label used in log context (default:"development").agent_timeout_seconds— hard wall-clock timeout for any agent turn (min/default:120).
Channels¶
- class minibot.adapters.config.schema.TelegramChannelConfig(*, enabled: bool = True, bot_token: str = '', allowed_chat_ids: list[int] = <factory>, allowed_user_ids: list[int] = <factory>, mode: str = 'long_polling', webhook_url: str | None = None, require_authorized: bool = True, media_enabled: bool = True, max_photo_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 5242880, max_document_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 10485760, max_total_media_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 12582912, max_attachments_per_message: Annotated[int, ~annotated_types.Gt(gt=0)] = 3, allowed_document_mime_types: list[str] = <factory>, format_repair_enabled: bool = True, format_repair_max_attempts: Annotated[int, ~annotated_types.Gt(gt=0)] = 1)¶
Telegram channel settings. TOML section:
[channels.telegram]bot_token— BotFather token (required).allowed_chat_ids/allowed_user_ids— access control lists.mode—"long_polling"(default) or"webhook".webhook_url— required whenmode = "webhook".require_authorized— reject messages from unlisted IDs (default:true).media_enabled— accept photo/document attachments (default:true).max_photo_bytes/max_document_bytes/max_total_media_bytes— per-message size caps.max_attachments_per_message— attachment count cap (default:3).allowed_document_mime_types— MIME whitelist; empty means all types are allowed.format_repair_enabled— auto-repair malformed Markdown before sending (default:true).
LLM¶
- class minibot.adapters.config.schema.LLMMConfig(*, provider: str = 'openai', api_key: str = '', base_url: str | None = None, model: str = 'gpt-4o-mini', http2: bool = False, temperature: float | None = None, max_new_tokens: Annotated[int, Gt(gt=0)] | None = None, max_tool_iterations: Annotated[int, Gt(gt=0)] = 15, request_timeout_seconds: Annotated[int, Ge(ge=45)] = 45, sock_connect_timeout_seconds: Annotated[int, Gt(gt=0)] = 10, sock_read_timeout_seconds: Annotated[int, Gt(gt=0)] = 45, retry_attempts: Annotated[int, Gt(gt=0)] = 3, retry_delay_seconds: Annotated[float, Gt(gt=0)] = 2.0, system_prompt: str = 'You are Minibot, a helpful assistant.', system_prompt_file: str | None = './prompts/main_agent_system.md', prompts_dir: str = './prompts', reasoning_effort: str | None = None, main_responses_state_mode: Literal['full_messages', 'previous_response_id'] = 'full_messages', agent_responses_state_mode: Literal['full_messages', 'previous_response_id'] = 'previous_response_id', responses_state_mode: Literal['full_messages', 'previous_response_id'] = 'full_messages', prompt_cache_enabled: bool = True, prompt_cache_retention: Literal['in-memory', '24h'] | None = None, openrouter: OpenRouterLLMConfig = OpenRouterLLMConfig(models=[], provider=None, reasoning_enabled=None, plugins=[]), xai: XAILLMConfig = XAILLMConfig(web_search_enabled=False, x_search_enabled=False, web_search=XAIWebSearchConfig(allowed_domains=[], excluded_domains=[], enable_image_understanding=False), x_search=XAIXSearchConfig(allowed_x_handles=[], excluded_x_handles=[], from_date=None, to_date=None, enable_image_understanding=False, enable_video_understanding=False)))¶
Main LLM settings. TOML section:
[llm]provider— provider name:"openai","anthropic","openrouter","xai", etc.api_key— provider API key.base_url— optional base URL (for proxies or OpenAI-compatible local servers).model— model identifier (default:"gpt-4o-mini").temperature— sampling temperature (nulluses provider default).max_new_tokens— max tokens to generate per turn.max_tool_iterations— maximum tool-call rounds before forcing a final answer (default:15).request_timeout_seconds— HTTP timeout per LLM request (min:45).system_prompt— inline system prompt (overridden bysystem_prompt_file).system_prompt_file— path to the main system prompt markdown file.prompts_dir— directory for runtime prompt fragments.reasoning_effort— reasoning budget hint for supported models (e.g."high").main_responses_state_mode— how conversation state is passed for the main agent ("full_messages"or"previous_response_id").prompt_cache_enabled— enable provider-side prompt caching (default:true).openrouter— OpenRouter-specific routing overrides ([llm.openrouter]).xai— xAI web/X search integration ([llm.xai]).
Providers¶
- class minibot.adapters.config.schema.ProviderConfig(*, api_key: str = '', base_url: str | None = None)¶
Named LLM provider credentials. TOML section:
[providers.<name>]Used to supply API keys and base URLs for secondary providers referenced by agent definitions (
model_provider).api_key— provider API key.base_url— optional base URL override (e.g. for proxies or local endpoints).
Memory¶
- class minibot.adapters.config.schema.MemoryConfig(*, backend: str = 'sqlite', sqlite_url: str = 'sqlite+aiosqlite:///./data/minibot.db', max_history_messages: Annotated[int | None, Ge(ge=1)] = None, max_history_tokens: Annotated[int | None, Ge(ge=1)] = None, context_ratio_before_compact: Annotated[float, Gt(gt=0), Le(le=1)] = 0.95, notify_compaction_updates: bool = False)¶
Conversation history memory settings. TOML section:
[memory]backend— storage backend (currently only"sqlite").sqlite_url— SQLite database URL (default:"sqlite+aiosqlite:///./data/minibot.db").max_history_messages— hard cap on stored messages per conversation (null= unlimited).max_history_tokens— token budget for history sent to the LLM (null= unlimited).context_ratio_before_compact— fraction of context window used before triggering automatic compaction (default:0.95).notify_compaction_updates— send a user-visible message when history is compacted (default:false).
Orchestration¶
- class minibot.adapters.config.schema.OrchestrationConfig(*, directory: str = './agents', default_timeout_seconds: Annotated[int, Gt(gt=0)] = 90, tool_ownership_mode: Literal['shared', 'exclusive', 'exclusive_mcp'] = 'shared', delegated_tool_call_policy: Literal['auto', 'always', 'never'] = 'auto', main_tool_use_guardrail: Literal['disabled', 'llm_classifier'] = 'disabled', main_agent: MainAgentConfig = MainAgentConfig(name='minibot', tools_allow=[], tools_deny=[]))¶
Multi-agent orchestration settings. TOML section:
[orchestration]directory— path to agent definition files (default:"./agents").default_timeout_seconds— per-agent-call timeout (default:90).tool_ownership_mode— how tools are shared between agents:"shared"(default),"exclusive", or"exclusive_mcp".delegated_tool_call_policy— whether delegated agents may call tools:"auto"(default),"always", or"never".main_tool_use_guardrail— optional guardrail before tool execution:"disabled"(default) or"llm_classifier".main_agent— tool allow/deny policy for the main agent ([orchestration.main_agent]).
Scheduler¶
- class minibot.adapters.config.schema.ScheduledPromptsConfig(*, enabled: bool = True, sqlite_url: str = 'sqlite+aiosqlite:///./data/scheduled_prompts.db', poll_interval_seconds: Annotated[int, Gt(gt=0)] = 60, lease_timeout_seconds: Annotated[int, Gt(gt=0)] = 120, batch_size: Annotated[int, Gt(gt=0)] = 10, max_attempts: Annotated[int, Gt(gt=0)] = 3, min_recurrence_interval_seconds: Annotated[int, Gt(gt=0)] = 60, pool_size: Annotated[int, Gt(gt=0)] = 5, echo: bool = False)¶
Scheduler persistence and polling settings. TOML section:
[scheduler.prompts]enabled— enable the scheduler (default:true).sqlite_url— SQLite database URL for job storage.poll_interval_seconds— how often due jobs are checked (default:60).lease_timeout_seconds— lease duration before a stalled job is retried (default:120).batch_size— max jobs processed per poll cycle (default:10).max_attempts— retries before a job is marked failed (default:3).min_recurrence_interval_seconds— floor for recurring job intervals (default:60).
Logging¶
- class minibot.adapters.config.schema.LoggingConfig(*, structured: bool = True, logfmt_enabled: bool = True, log_level: str = 'INFO', kv_separator: str = '=', record_separator: str = ' ')¶
Structured logging settings. TOML section:
[logging]structured— enable structured (JSON-like) log output (default:true).logfmt_enabled— use logfmt key=value format instead of JSON (default:true).log_level— log level for the logging subsystem (default:"INFO").kv_separator— separator between key and value in logfmt (default:"=").record_separator— separator between fields in logfmt (default:" ").
RabbitMQ¶
- class minibot.adapters.config.schema.RabbitMQConsumerConfig(*, enabled: bool = False, broker_url: str = 'amqp://guest:guest@localhost:5672/', queue_name: str = 'minibot', exchange_name: str = 'minibot.tasks', prefetch_count: Annotated[int, Gt(gt=0)] = 1, worker_timeout_seconds: Annotated[int, Gt(gt=0)] = 60, max_concurrent_workers: Annotated[int, Gt(gt=0)] = 4)¶
RabbitMQ task consumer settings. TOML section:
[rabbitmq]Requires the
rabbitmqextra:poetry install --extras rabbitmq.enabled— enable the RabbitMQ consumer (default:false).broker_url— AMQP connection URL (default:"amqp://guest:guest@localhost:5672/").queue_name— queue to consume from (default:"minibot").exchange_name— fanout exchange name (default:"minibot.tasks").prefetch_count— max unacknowledged messages per worker (default:1).worker_timeout_seconds— per-task processing timeout (default:60).max_concurrent_workers— maximum parallel task handlers (default:4).
Tool Configuration¶
Section |
Config model |
Key options |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tool Config Models¶
- class minibot.adapters.config.schema.KeyValueMemoryConfig(*, enabled: bool = False, sqlite_url: str = 'sqlite+aiosqlite:///./data/kv_memory.db', pool_size: Annotated[int, Gt(gt=0)] = 5, echo: bool = False, default_limit: Annotated[int, Gt(gt=0)] = 20, max_limit: Annotated[int, Gt(gt=0)] = 100, default_owner_id: str | None = 'primary')¶
- class minibot.adapters.config.schema.HTTPClientToolConfig(*, enabled: bool = False, timeout_seconds: Annotated[int, Gt(gt=0)] = 10, max_bytes: Annotated[int, BeforeValidator(func=_coerce_byte_size, json_schema_input_type=PydanticUndefined), Gt(gt=0)] = 16384, response_processing_mode: Literal['none', 'auto'] = 'auto', max_chars: Annotated[int, Gt(gt=0)] | None = None, normalize_whitespace: bool = True, spill_to_managed_file: bool = False, spill_after_chars: Annotated[int, Gt(gt=0)] = 16000, spill_preview_chars: Annotated[int, Gt(gt=0)] = 2000, max_spill_bytes: Annotated[int, BeforeValidator(func=_coerce_byte_size, json_schema_input_type=PydanticUndefined), Gt(gt=0)] = 5000000, spill_subdir: str = 'http_responses/tmp')¶
- class minibot.adapters.config.schema.TimeToolConfig(*, enabled: bool = True, default_format: str = '%Y-%m-%dT%H:%M:%SZ')¶
- class minibot.adapters.config.schema.CalculatorToolConfig(*, enabled: bool = True, default_scale: Annotated[int, Gt(gt=0)] = 28, max_expression_length: Annotated[int, Gt(gt=0)] = 200, max_exponent_abs: Annotated[int, Gt(gt=0)] = 1000)¶
- class minibot.adapters.config.schema.PythonExecToolConfig(*, enabled: bool = True, backend: Literal['host'] = 'host', python_path: str | None = None, venv_path: str | None = None, sandbox_mode: Literal['none', 'basic', 'rlimit', 'cgroup', 'jail']='basic', default_timeout_seconds: Annotated[int, ~annotated_types.Gt(gt=0)] = 8, max_timeout_seconds: Annotated[int, ~annotated_types.Gt(gt=0)] = 20, max_output_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 64000, max_code_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 32000, artifacts_enabled: bool = True, artifacts_default_subdir: str = 'generated', artifacts_allowed_extensions: list[str] = <factory>, artifacts_max_files: Annotated[int, ~annotated_types.Gt(gt=0)] = 5, artifacts_max_file_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 5000000, artifacts_max_total_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 20000000, artifacts_allow_in_jail: bool = False, artifacts_jail_shared_dir: str | None = None, pass_parent_env: bool = False, env_allowlist: list[str] = <factory>, rlimit: PythonExecRLimitConfig = PythonExecRLimitConfig(enabled=False, cpu_seconds=2, memory_mb=256, fsize_mb=16, nproc=64, nofile=256), cgroup: PythonExecCgroupConfig = PythonExecCgroupConfig(enabled=False, driver='systemd', cpu_quota_percent=100, memory_max_mb=256), jail: PythonExecJailConfig = PythonExecJailConfig(enabled=False, command_prefix=[]))¶
- class minibot.adapters.config.schema.PythonExecRLimitConfig(*, enabled: bool = False, cpu_seconds: Annotated[int, Gt(gt=0)] | None = 2, memory_mb: Annotated[int, Gt(gt=0)] | None = 256, fsize_mb: Annotated[int, Gt(gt=0)] | None = 16, nproc: Annotated[int, Gt(gt=0)] | None = 64, nofile: Annotated[int, Gt(gt=0)] | None = 256)¶
- class minibot.adapters.config.schema.PythonExecCgroupConfig(*, enabled: bool = False, driver: Literal['systemd'] = 'systemd', cpu_quota_percent: Annotated[int, Gt(gt=0)] | None = 100, memory_max_mb: Annotated[int, Gt(gt=0)] | None = 256)¶
- class minibot.adapters.config.schema.PythonExecJailConfig(*, enabled: bool = False, command_prefix: list[str] = <factory>)¶
- class minibot.adapters.config.schema.BashToolConfig(*, enabled: bool = False, default_timeout_seconds: Annotated[int, ~annotated_types.Gt(gt=0)] = 15, max_timeout_seconds: Annotated[int, ~annotated_types.Gt(gt=0)] = 120, max_output_bytes: Annotated[int, ~pydantic.functional_validators.BeforeValidator(func=~minibot.adapters.config.schema._coerce_byte_size, json_schema_input_type=PydanticUndefined), ~annotated_types.Gt(gt=0)] = 128000, pass_parent_env: bool = True, env_allowlist: list[str] = <factory>)¶
- class minibot.adapters.config.schema.ApplyPatchToolConfig(*, enabled: bool = False, restrict_to_workspace: bool = True, workspace_root: str = '.', allow_outside_workspace: bool = False, preserve_trailing_newline: bool = True, max_patch_bytes: Annotated[int, BeforeValidator(func=_coerce_byte_size, json_schema_input_type=PydanticUndefined), Gt(gt=0)] = 262144)¶
- class minibot.adapters.config.schema.FileStorageToolConfig(*, enabled: bool = False, root_dir: str = './data/files', max_write_bytes: Annotated[int, BeforeValidator(func=_coerce_byte_size, json_schema_input_type=PydanticUndefined), Gt(gt=0)] = 64000, allow_outside_root: bool = False, save_incoming_uploads: bool = False, uploads_subdir: str = 'uploads', incoming_temp_subdir: str = 'uploads/temp')¶
- class minibot.adapters.config.schema.GrepToolConfig(*, enabled: bool = False, max_matches: Annotated[int, Gt(gt=0)] = 200, max_file_size_bytes: Annotated[int, BeforeValidator(func=_coerce_byte_size, json_schema_input_type=PydanticUndefined), Gt(gt=0)] = 1000000)¶
- class minibot.adapters.config.schema.BrowserToolConfig(*, output_dir: str = './data/files/browser')¶
- class minibot.adapters.config.schema.AudioTranscriptionToolConfig(*, enabled: bool = False, model: str = 'small', device: Literal['auto', 'cpu', 'cuda'] = 'auto', compute_type: str = 'int8', beam_size: Annotated[int, Gt(gt=0)] = 5, vad_filter: bool = True, auto_transcribe_short_incoming: bool = True, auto_transcribe_max_duration_seconds: Annotated[int, Gt(gt=0)] = 45)¶
- class minibot.adapters.config.schema.MCPToolConfig(*, enabled: bool = False, name_prefix: str = 'mcp', timeout_seconds: Annotated[int, ~annotated_types.Gt(gt=0)] = 10, servers: list[MCPServerConfig] = <factory>)¶
- class minibot.adapters.config.schema.MCPServerConfig(*, name: str, transport: Literal['stdio', 'http']='stdio', command: str | None = None, args: list[str] = <factory>, env: dict[str, str]=<factory>, cwd: str | None = None, url: str | None = None, headers: dict[str, str]=<factory>, enabled_tools: list[str] = <factory>, disabled_tools: list[str] = <factory>)¶
- class minibot.adapters.config.schema.SkillsToolConfig(*, enabled: bool = True, paths: list[str] = <factory>, preload_catalog: bool = False)¶
- class minibot.adapters.config.schema.TaskToolConfig(*, enabled: bool = False)¶