Configuration
OpenPocket loads config from JSON, merges defaults, normalizes compatibility keys, and writes resolved runtime structure.
In multi-agent mode, each agent instance still has its own full config.json.
File Resolution
Resolution order:
- CLI
--config <path>if provided - CLI
--agent <id>if provided - default root config at
OPENPOCKET_HOME/config.json - if missing, default config is auto-created
OPENPOCKET_HOME defaults to ~/.openpocket.
Rules:
--configand--agentare mutually exclusive- omitting both selects the onboarded
defaultagent openpocket create agent <id>registers a managed agent underOPENPOCKET_HOME/agents/<id>/config.json
Config Scope Levels
Default agent
The onboarded root agent uses:
OPENPOCKET_HOME/config.jsonOPENPOCKET_HOME/workspace/OPENPOCKET_HOME/state/
Managed agents
Managed agents use:
OPENPOCKET_HOME/agents/<agentId>/config.jsonOPENPOCKET_HOME/agents/<agentId>/workspace/OPENPOCKET_HOME/agents/<agentId>/state/
Manager metadata
Install-level metadata lives under:
OPENPOCKET_HOME/manager/registry.jsonOPENPOCKET_HOME/manager/model-template.jsonOPENPOCKET_HOME/manager/ports.json
These manager files are not agent configs. They coordinate agent discovery, the initial model template, and shared port allocation.
Load Order
At startup, config handling does:
- parse JSON from the selected config path
- convert compatibility
snake_casekeys tocamelCase - deep-merge with the default config object
- normalize model profiles and typed fields
- resolve paths (
~and relative paths -> absolute) - ensure required directories
- bootstrap workspace files when missing
This happens independently for each selected agent config.
Create-Agent Cloning Rules
openpocket create agent <id> clones from the source config, but it does not copy the entire runtime state.
What is rewritten for the new agent:
workspaceDirstateDirsessionStorage.storePathscreenshots.directorycron.jobsFiledashboard.porthumanAuth.localRelayStateFileconfigPath
What is reset/cleared:
agent.deviceIdtarget.adbEndpointhumanAuth.relayBaseUrlhumanAuth.publicBaseUrl- all channel credentials/config except
channels.defaults
What is copied from the manager template rather than from the current source config:
defaultModelmodels
This means managed agents start from the initial onboard model template, then become independent afterwards.
API Keys
Per model profile:
- use
models.<name>.apiKeyif non-empty - else env var from
models.<name>.apiKeyEnv - else for OpenAI codex models, try Codex CLI credentials (
$CODEX_HOME/auth.jsonor~/.codex/auth.json; macOS keychainCodex Authfirst) - else treat key as missing and fail task early
For human-auth relay:
- standalone/local relay uses
humanAuth.apiKeyorhumanAuth.apiKeyEnv - shared relay hub launched by
openpocket human-auth-relay startdoes not use separate per-agent relay state or per-agent hub API keys - in managed mode, agent-local request state still stays under the agent's own
state/
Aliyun UI Agent mobile backend
OpenPocket now includes a first-class aliyun-ui-agent/mobile model profile.
Key points:
- the profile sets
models.<name>.backendtoaliyun_ui_agent_mobile - runtime routes this backend through the dedicated Aliyun GUI-agent client instead of the default OpenAI-compatible tool-calling path
- image input is delivered as a short-lived screenshot URL from the local relay stack, so the selected agent must have
humanAuth.useLocalRelay=true - if Aliyun must fetch screenshots from the public internet, use either:
- the shared relay hub from
openpocket human-auth-relay start - or per-agent ngrok via
humanAuth.tunnel.provider=ngrok
- the shared relay hub from
Minimal example:
{
"defaultModel": "aliyun-ui-agent/mobile",
"models": {
"aliyun-ui-agent/mobile": {
"baseUrl": "https://dashscope.aliyuncs.com/api/v2/apps/gui-owl/gui_agent_server",
"model": "pre-gui_owl_7b",
"apiKey": "",
"apiKeyEnv": "DASHSCOPE_API_KEY",
"maxTokens": 4096,
"reasoningEffort": null,
"temperature": null,
"backend": "aliyun_ui_agent_mobile"
}
}
}Backward Compatibility Keys
Loader maps old keys automatically, including:
- top-level:
project_name,workspace_dir,state_dir,default_model,script_executor,coding_tools,memory_tools - top-level aliases:
heartbeat_config,cron_config,dashboard_config,gateway_logging,human_auth - nested:
avd_name,android_sdk_root,bot_token,max_steps,system_prompt_mode,context_budget_chars,save_step_screenshots,allowed_commands,base_url,api_key,reasoning_effort, etc.
After onboard, saved config uses camelCase keys.
Validation and Clamps
Normalization enforces:
defaultModelmust exist inmodelsagent.lang->enagent.systemPromptModeinfull|minimal|none(invalid ->full)agent.contextBudgetChars >= 10000agent.progressReportInterval >= 1screenshots.maxCount >= 20scriptExecutor.timeoutSec >= 1scriptExecutor.maxOutputChars >= 1000codingTools.timeoutSec >= 1codingTools.maxOutputChars >= 1000memoryTools.maxResultsin1..30memoryTools.minScorein0..1memoryTools.maxSnippetCharsin200..8000heartbeat.everySec >= 5heartbeat.stuckTaskWarnSec >= 30cron.tickSec >= 2dashboard.portin1..65535gatewayLogging.levelinerror|warn|info|debug(invalid ->info)gatewayLogging.maxPayloadCharsclamped to40..1000humanAuth.localRelayPortin1..65535humanAuth.requestTimeoutSec >= 30humanAuth.pollIntervalMs >= 500humanAuth.tunnel.providerinnone|ngrokhumanAuth.tunnel.ngrok.startupTimeoutSec >= 3- model
baseUrlnormalization:- Google AI Studio endpoints auto-normalize bare host to
/v1beta - Anthropic
/v1base URL auto-normalizes to root endpoint
- Google AI Studio endpoints auto-normalize bare host to
If defaultModel does not exist in models, startup throws.
Related Runtime Constraints
- one agent binds one selected target at a time
- targets cannot be shared between agents
- each running gateway acquires a per-agent gateway lock and a per-target runtime lock
- manager dashboard and shared relay hub ports are allocated centrally via
manager/ports.json
Defaults
See Config Defaults for the exact default JSON and managed-agent path overrides.
