20 KiB
🔧 Configuration Guide
1. LLM Credentials (.env)
Note
Create
openspace/.envfrom../.env.exampleand set at least one LLM API key.
Resolution priority (first match wins):
| Priority | Source | Example |
|---|---|---|
| Tier 1 | OPENSPACE_LLM_* env vars |
OPENSPACE_LLM_API_KEY=sk-xxx |
| Tier 2 | Provider-native env vars | OPENROUTER_API_KEY=sk-or-xxx |
| Tier 3 | Host agent config | ~/.nanobot/config.json / ~/.openclaw/openclaw.json |
Important
Tier 2 blocks Tier 3 — if
.envhas a provider key, host agent config is skipped.
# Provider-native — litellm reads automatically
OPENROUTER_API_KEY=sk-or-v1-xxx
# Or: OpenSpace-native — higher priority, same effect
OPENSPACE_LLM_API_KEY=sk-or-v1-xxx
2. Environment Variables
Set via .env, MCP config env block, or system environment.
Set OPENSPACE_SKIP_DOTENV=1 in the process environment before startup to
ignore local .env files; it cannot be enabled from .env itself.
| Variable | Description | Default |
|---|---|---|
OPENSPACE_MODEL |
LLM model | openrouter/anthropic/claude-sonnet-4.5 |
OPENSPACE_SKIP_DOTENV |
Disable automatic openspace/.env and CWD .env loading |
false |
OPENSPACE_LLM_API_KEY |
LLM API key (Tier 1 override) | — |
OPENSPACE_LLM_API_BASE |
LLM API base URL | — |
OLLAMA_API_BASE |
Local Ollama endpoint for ollama/* models |
http://127.0.0.1:11434 |
OLLAMA_API_KEY |
Placeholder key for Ollama-compatible clients | ollama |
OPENSPACE_LLM_EXTRA_HEADERS |
Extra LLM headers (JSON) | — |
OPENSPACE_LLM_CONFIG |
Arbitrary litellm kwargs (JSON) | — |
OPENSPACE_CLOUD_MODE |
Cloud mode, either off or live |
off |
OPENSPACE_CLOUD_BASE_URL |
Cloud service root URL; do not include /api, /api/v1, or /api/v2 |
https://open-space.cloud |
OPENSPACE_CLOUD_API_KEY |
Cloud agent API key (X-API-Key) |
— |
OPENSPACE_CLOUD_TELEMETRY_MODE |
Cloud telemetry mode, either off or outbox |
off |
OPENSPACE_MAX_ITERATIONS |
Max agent iterations per task | 20 |
OPENSPACE_BACKEND_SCOPE |
Enabled backends (comma-separated) | shell,mcp,meta |
OPENSPACE_HOST_SKILL_DIRS |
Agent skill directories (comma-separated) | — |
OPENSPACE_CAPTURE_SKILL_DIR |
Directory where CAPTURED evolution writes newly authored skills; falls back to the first host skill dir, then <workspace>/.openspace/skills |
— |
OPENSPACE_WORKSPACE |
Project root for logs/workspace | — |
OPENSPACE_SHELL_CONDA_ENV |
Conda env for shell backend | — |
Provision cloud credentials with openspace-cloud-auth bootstrap-agent-key --email you@example.com --agent-name openspace-local-agent. The command writes OPENSPACE_CLOUD_MODE=live, OPENSPACE_CLOUD_BASE_URL, and OPENSPACE_CLOUD_API_KEY locally without printing the raw key.
| OPENSPACE_SHELL_WORKING_DIR | Working dir for shell backend | — |
| OPENSPACE_CONFIG_PATH | Custom grounding config JSON | — |
| OPENSPACE_MCP_SERVERS_JSON | MCP server definitions (JSON) | — |
| ANTHROPIC_API_KEY | Optional Anthropic key for web_search server-side search | — |
| TAVILY_API_KEY / BRAVE_SEARCH_API_KEY / SERPAPI_API_KEY | Optional fallback search provider keys | — |
| OPENSPACE_WEB_FETCH_MODEL | Optional model override for applying prompts to fetched pages | — |
| OPENSPACE_ENABLE_RECORDING | Record execution traces | true |
| OPENSPACE_MAX_OUTPUT_TOKENS_RECOVERY_LIMIT | Number of no-tool max-output recovery nudges before stopping a turn | 3 |
| OPENSPACE_FORCE_TOOL_ON_MAX_OUTPUT_RECOVERY | Force tool_choice=required on max-output recovery calls when tools are available | false |
| OPENSPACE_DISABLE_REASONING_ON_REQUIRED_TOOL_CHOICE | Suppress provider reasoning controls only on required-tool calls | false |
| OPENSPACE_OPENROUTER_DISABLE_REASONING_ON_REQUIRED_TOOL_CHOICE | OpenRouter-specific version of required-tool reasoning suppression | false |
| OPENSPACE_BENCH_FINALIZE_NUDGE_ENABLED | Enable a benchmark-only best-artifact finalization nudge during long single-task runs | false |
| OPENSPACE_BENCH_FINALIZE_NUDGE_AFTER_SEC | Seconds before the benchmark finalization nudge may be injected; 0 disables time-based triggering | 0 |
| OPENSPACE_BENCH_FINALIZE_NUDGE_AFTER_ITERATION | Model iteration before the benchmark finalization nudge may be injected; 0 disables iteration-based triggering | 0 |
| OPENSPACE_BENCH_FINALIZE_NUDGE_MAX | Maximum benchmark finalization nudges per turn | 1 |
| OPENSPACE_BENCH_FINALIZE_STOP_AFTER_ITERATIONS | Stop a benchmark turn this many iterations after a finalization nudge so external verifiers can score the best artifact; 0 disables | 0 |
| OPENSPACE_BENCH_FINALIZE_STOP_AFTER_SEC | Stop a benchmark turn this many seconds after a finalization nudge; 0 disables | 0 |
| OPENSPACE_BENCH_STRICT_NO_TOOL_FINAL | After a benchmark finalization nudge, require a later tool action before accepting a no-tool final response; retry with the configured fallback model when available | false |
| OPENSPACE_BENCH_NO_TOOL_FINAL_MAX_NUDGES | Number of tool-backed finalization nudges before switching to fallback model or stopping as unresolved | 2 |
| OPENSPACE_EVOLUTION_STORAGE_ROOT | Root used to resolve .openspace/openspace.db, .openspace/evidence.db, staging, and backups | workspace |
| OPENSPACE_SKILL_STORE_DB_PATH | Explicit SkillStore SQLite path; also anchors the evolution storage root when no storage root is set | — |
| OPENSPACE_EVOLUTION_EVIDENCE_DB_PATH | Explicit evidence SQLite path; takes precedence over storage-root resolution for evidence | — |
| OPENSPACE_EVOLUTION_EVIDENCE_ENABLED | Enable durable evolution evidence collection | true |
| OPENSPACE_EVOLUTION_TRIGGERS_ENABLED | Enable durable TriggerJob creation from evidence checkpoints; set false to keep evidence ingest but pause trigger jobs | true |
| OPENSPACE_EVOLUTION_ENGINE_ENABLED | Enable TriggerJob processing through decision, admission, staged authoring, validation, and commit | true |
| OPENSPACE_EVOLUTION_MODE | Evolution mode: audit_only audits only, fix_only commits explicit direct FIX only, autonomous allows all validated admitted actions | autonomous |
| OPENSPACE_EVOLUTION_ALLOW_SINGLE_OBSERVATION_CAPTURE | Allow a validated CAPTURED proposal, and DERIVED proposal with clear divergence, to persist as a provisional skill from its origin observation. When disabled, automatic proposals remain audit-only candidates; recurrence never promotes them | true |
| OPENSPACE_EVOLUTION_CAPTURE_SEMANTIC_VALIDATION_ENABLED | Run one independent semantic review per staged CAPTURED proposal; approval requires exact validation-ref binding, no unsupported executable claims, reusable scope, and no incomplete high-impact safeguard | true |
| OPENSPACE_EVOLUTION_CAPTURE_SEMANTIC_VALIDATION_MAX_TOKENS | Maximum output tokens for the independent CAPTURED semantic review | 2048 |
| OPENSPACE_SKILL_TRUST_PROMOTION_MIN_INDEPENDENT_SUCCESSES | Independent successful observations required to promote a provisional skill to trusted; a CAPTURED origin counts only when its source-validation contract passes admission | 2 |
| OPENSPACE_EVOLUTION_FINAL_DRAIN_LIMIT | Number of open post-execution evolution jobs to retry before a short-lived runtime exits; 0 disables the extra drain | 0 |
3. Task Runtime Context Defaults
These are OpenSpaceConfig / JSON config fields rather than environment
variables. They are useful for benchmark adapters that need a narrower
task-solving surface while keeping normal interactive OpenSpace defaults
unchanged.
| Field | Description | Default |
|---|---|---|
active_tool_names |
Optional hard allowlist of tool names exposed to the agent for a turn | — |
capture_skill_dir |
Directory where post-execution CAPTURED skills should be staged and committed for this runtime | — |
execution_analyzer_max_tokens |
Optional ExecutionAnalyzer-only output budget; OPENSPACE_EXECUTION_ANALYZER_MAX_TOKENS provides the equivalent environment override |
inherit LLM default |
skill_evolver_max_tokens |
Optional SkillEvolver-only output budget; OPENSPACE_SKILL_EVOLVER_MAX_TOKENS provides the equivalent environment override |
inherit LLM default |
policy_deferred_tool_names |
Optional tool names kept behind tool_search; use [] to avoid deferred-tool discovery |
— |
skills_disabled |
Hide Skill Protocol tools and skill prompt guidance from the task-solving agent | false |
memory_mode |
Optional memory mode override for the task context | — |
OPENSPACE_EVOLUTION_FINAL_DRAIN_ROUNDS |
Maximum final-drain rounds to run | 1 |
OPENSPACE_EVOLUTION_FINAL_DRAIN_TIMEOUT_S |
Per-round timeout for the final evolution drain; 0 disables the timeout wrapper |
0 |
OPENSPACE_EVOLUTION_STARTUP_RETRYABLE_DRAIN_LIMIT |
Number of persisted failed_retryable evolution jobs to explicitly retry during startup after stale-job recovery; 0 disables startup retryable drain |
0 |
OPENSPACE_EVOLUTION_STARTUP_RETRYABLE_DRAIN_ROUNDS |
Maximum startup retryable-drain rounds to run | 1 |
OPENSPACE_EVOLUTION_STARTUP_RETRYABLE_DRAIN_TIMEOUT_S |
Per-round timeout for startup retryable drain; 0 disables the timeout wrapper |
0 |
OPENSPACE_EVOLUTION_STARTUP_RETRYABLE_DRAIN_STATUSES |
Comma-separated TriggerJob statuses eligible for startup drain, useful for controlled replay runs that should continue copied pending jobs |
failed_retryable |
OPENSPACE_EVOLUTION_RECOVERY_STALE_JOB_TIMEOUT_S |
Age in seconds before startup recovery resets a running TriggerJob to retryable/failed; lower it when intentionally replaying a freshly interrupted evidence DB |
1800 |
OPENSPACE_EVOLUTION_BEHAVIOR_EVAL_REQUIRE_REPLAY_RUNNER |
Require an external replay runner before behavior eval can approve replay-backed skill changes. Keep enabled for strict autonomous evolution; set false in harnesses that only have deterministic/routing eval available |
true |
OPENSPACE_POST_EXECUTION_TIMEOUT_S |
Hard timeout for inline/background post-execution analysis and evolution drain; 0 disables the timeout. If a claimed evolution job is cancelled by this timeout, it is marked retryable instead of being left running |
0 |
OPENSPACE_EVOLUTION_ALLOWED_READ_ROOTS |
Extra evidence file-read roots, separated by the platform path separator | — |
OPENSPACE_DEFAULT_MAX_RESULT_SIZE_CHARS |
Per-tool result size threshold before persisting large outputs to disk | 50000 |
OPENSPACE_MAX_TOOL_RESULTS_PER_MESSAGE_CHARS |
Aggregate tool-result text budget kept in the model conversation before replacing large old results with persisted-output previews | 200000 |
OPENSPACE_TOOL_RESULT_PREVIEW_CHARS |
Preview size included in persisted-output wrappers | 2000 |
OPENSPACE_LOG_LEVEL |
Log level | INFO |
3. User Settings (settings.json)
Use user/project settings for runtime preferences that should persist across runs. These are separate from openspace/config/*.json, which configures backend implementation details.
Load order, later entries override earlier ones:
| Source | Path | Use for |
|---|---|---|
| User settings | ~/.openspace/settings.json or $OPENSPACE_CONFIG_HOME/settings.json |
Personal defaults |
| Project settings | <project>/.openspace/settings.json |
Team/project defaults that may be committed |
| Local settings | <project>/.openspace/settings.local.json |
Machine-local overrides, gitignored |
| Environment | OPENSPACE_* |
CI, temporary overrides, deployment |
| Runtime | CLI/TUI updates | Current session state |
Settings are grouped by stability:
| Group | Keys |
|---|---|
| Stable engine | model, alwaysThinkingEnabled, autoCompactEnabled, autoMemoryEnabled, autoDream.*, memory.*, permissions.*, todoFeatureEnabled, fileCheckpointingEnabled, language |
| Stable UI | theme, editorMode, verbose, preferredNotifChannel, showTurnDuration, terminalProgressBarEnabled |
| Experimental | teammateMode, outputStyle, attachments.todoReminderEnabled |
Example:
{
"model": "openrouter/qwen/qwen3.6-plus",
"alwaysThinkingEnabled": true,
"autoCompactEnabled": true,
"permissions": {
"defaultMode": "default",
"allow": ["Bash(git status:*)"]
},
"autoDream": {
"enabled": true,
"minHours": 12,
"minSessions": 3
},
"memory": {
"mode": "daily_log"
},
"theme": "dark",
"attachments": {
"todoReminderEnabled": true
}
}
Notes:
- Use
autoDream.enabled; the oldautoDreamEnabledalias is not part of the runtime settings schema. - Only
attachments.todoReminderEnabledis currently public. Future attachment gates will be added only when the runtime feature is actually wired. - OpenSpace does not currently expose
flagSettingsorpolicySettings; enterprise policy sources will be modeled only when there is a real backend. - There is no published SchemaStore URL yet, so do not add
$schema: "https://json.schemastore.org/openspace-settings.json".
You can inspect or update settings with slash commands:
/settings
/settings model openrouter/qwen/qwen3.6-plus
/settings autoDream.enabled true
/settings permissions.defaultMode plan
4. MCP Servers (config_mcp.json)
Register external MCP servers that OpenSpace connects to as a client (e.g. GitHub, Slack, databases):
cp openspace/config/config_mcp.json.example openspace/config/config_mcp.json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
}
}
}
For an HTTP MCP server with free, keyless web search and page fetching, see the runnable Parallel Search example. Merge its server entry into your configuration to keep existing MCP servers.
5. Execution Mode
The shell backend supports only local execution. This keeps Bash sandbox
decisions, foreground/background tasks, TaskGet, and TaskStop in one
process-level runtime. The GUI backend still supports local and server modes.
| Backend | Supported Modes | Notes |
|---|---|---|
shell |
"local" only |
asyncio.subprocess in-process with runtime task lifecycle |
gui |
"local" or "server" |
Server mode uses the private local_server transport |
Tip
Do not set
shell.modeto"server". The HTTP local server does not expose the shell spawn/status/tail/kill contract required by the runtime.
6. Config Files (openspace/config/)
Layered system — later files override earlier ones:
| File | Purpose |
|---|---|
config_grounding.json |
Backend settings, smart tool retrieval, tool quality, skill discovery |
config_agents.json |
Agent definitions, backend scope, max iterations |
config_mcp.json |
MCP servers OpenSpace connects to as a client |
config_security.json |
Security policies, blocked commands, sandboxing |
config_dev.json |
Dev overrides — copy from config_dev.json.example (highest priority) |
config_communication.json |
Communication gateway settings for WhatsApp and Feishu. Use agent for per-message OpenSpace execution and sessions for queue/history limits. LLM model stays in openspace/.env. |
Agent config (config_agents.json)
{ "agents": [{ "name": "GroundingAgent", "backend_scope": ["shell", "mcp", "web"], "max_iterations": 30 }] }
| Field | Description | Default |
|---|---|---|
backend_scope |
Enabled backends | ["gui", "shell", "mcp", "meta", "web"] |
max_iterations |
Max execution cycles | 20 |
Backend & tool config (config_grounding.json)
| Section | Key Fields | Description |
|---|---|---|
shell |
mode, timeout, conda_env, working_dir |
"local" only, command timeout (default: 60s) |
web.search |
search_model, search_api_key, search_base_url, max_searches_per_call, fallback_search_provider |
Web search settings; uses provider server-side search when configured, then provider fallback |
web.fetch |
summarize_model, max_content_length, request_timeout, user_agent, preapproved_domains |
Web fetch settings; fetches URLs locally and applies a secondary model when needed |
gui |
mode, timeout, driver_type, screenshot_on_error, enable_visual_analysis, visual_analysis_mode, visual_analysis_timeout, visual_analysis_model |
Local/server mode, automation driver, GUI visual analysis fallback policy |
mcp |
timeout, sandbox, eager_sessions |
Request timeout (30s), E2B sandbox, lazy/eager server init |
tool_search |
search_mode, max_tools, enable_llm_filter |
"hybrid" (semantic + LLM), max tools to return (40), embedding cache |
tool_quality |
enabled, enable_persistence, enable_quality_ranking |
Quality tracking for ranking and reporting |
skills |
enabled, skill_dirs, listing_enabled, discovery_enabled, discovery_max_results, post_tool_query_builder_* |
Skill exposure uses lightweight listing/discovery plus explicit Skill invocation. |
Security config (config_security.json)
| Field | Description | Default |
|---|---|---|
allow_shell_commands |
Enable shell execution | true |
blocked_commands |
Platform-specific blacklists (common/linux/darwin/windows) | rm -rf, shutdown, dd, etc. |
sandbox_enabled |
Enable sandboxing for all operations | false |
| Per-backend overrides | Shell, MCP, GUI, Web each have independent security policies | Inherit global |
7. Communication Gateway
The tracked communication config is safe-by-default: loopback-only, channels disabled, and deny-by-default access control. Copy the example config, fill in credentials and allowed_users, then explicitly enable the channels you want. The gateway model is not configured here; it inherits OPENSPACE_MODEL from openspace/.env.
config_communication.json accepts only the canonical top-level agent and sessions sections for execution and queue/history settings. The old openspace and runtime root keys are rejected instead of being mapped silently.
cp openspace/config/config_communication.json.example openspace/config/config_communication.json
Install the Feishu SDK extra when you need Feishu support:
pip install -e '.[communication]'
Start the gateway:
openspace-gateway --config openspace/config/config_communication.json
Check health:
openspace-gateway health --config openspace/config/config_communication.json
Notes:
- The tracked
config_communication.jsonnow stays local-only and deny-by-default. Keep credentials out of git and populate them from a private working copy or environment variables. - Set
server.hostto0.0.0.0only when Feishu needs to reach the webhook from outside the machine, and pair that with a populated allowlist plus webhook verification secrets. - Feishu now supports both
webhookandwebsocketmodes.websocketmatches nanobot's long-connection setup and does not require a public webhook URL. - WhatsApp requires Node.js and npm. The bundled bridge installs its dependencies on first start when
auto_install_dependenciesis enabled. - Set
feishu.bot_open_idif you want strict group mention gating and automatic bot identity discovery is unavailable in your deployment. - Group chats are gated by
group_policy.reply_or_mentionis the default and only accepts messages that mention the bot or reply to a prior assistant message. allowed_usersis enforced whenallow_all_usersisfalse. The secure default is deny-by-default until you populate the allowlist.- Attachment caching is limited by
sessions.max_attachment_bytesandsessions.max_session_attachment_bytesto bound disk usage per file and per session.