| name | ha-settings |
| description | Manage Hope Agent application settings through conversation. Use when the user wants to view or change any app configuration: theme, language, proxy, temperature, notifications, tool timeout, context compaction, automatic session titles, web search, GitHub issue reporting, memory, embedding, multimodal embedding, dreaming (offline memory consolidation), recap, behavior awareness, smart-mode approvals, plan mode, ask-user-question timeout, tool-result disk spill threshold, embedded server, ACP control plane, MCP subsystem (kill switch / concurrency / backoff), per-skill env vars, or any other setting visible in the Settings UI. Trigger phrases: 'change settings', 'configure proxy', 'set theme to dark', 'turn off notifications', 'adjust temperature', 'show my settings', 'bind the server to all interfaces', 'enable smart mode', 'tune dreaming', 'disable mcp', 'show my channels'. Trigger even when the user doesn't explicitly say 'settings' — any intent to adjust app behavior qualifies. |
| always | true |
Settings — Application Configuration Management
Use get_settings and update_settings to read and modify settings. Never edit config files directly. Coverage matches the desktop Settings UI one-to-one for everything that doesn't carry secrets. The GUI-only zones — Providers / API Keys, IM Channel accounts (channels), MCP server configs (mcp_servers), the active model selection (active_model / fallback_models), the embedding model selection for both memory and knowledge-base vector search (memory_embedding / knowledge_embedding — model choice carries a background reembed side effect, like active_model), the knowledge-base chunking parameters (knowledge_chunk — changing chunk size/overlap re-chunks and re-embeds every space, same heavy reindex side effect; tuned under Settings → Knowledge → Advanced), the Speech-to-Text subsystem (stt_providers / active_stt_model / stt_fallback_models), and the Hooks system (hooks) — are configured only in the Settings UI (memory vector search under Settings → Memory; knowledge vector search under Settings → Knowledge) so credentials stay out of conversation logs and the model can't grant itself command execution.
Risk Levels & Dual-Confirmation
Every response from get_settings / update_settings includes a riskLevel field. Follow this workflow strictly:
| Risk | Required before calling update_settings |
|---|
low | One-line summary of what you'll change is enough |
medium | Show current value → new value, then proceed if the user has asked for it |
high | MUST explicitly ask the user to confirm (e.g. "Are you sure you want to change X from A to B? This affects …"). Wait for explicit yes before writing. |
get_settings({ category: "all" }) returns a riskLevels map grouping every category.
If the response includes sideEffect, surface it to the user (e.g. "this requires an app restart").
Workflow
- Understand intent — what does the user want to view or change?
- Read current —
get_settings(category). Note riskLevel and sideEffect.
- Confirm — low: brief summary. medium: diff. high: explicit yes/no prompt.
- Apply —
update_settings(category, values) with partial JSON.
- Report — show the updated values and any side-effect note (e.g. restart needed).
Tool Usage
get_settings
{ "category": "theme" }
{ "category": "all" }
update_settings
{ "category": "theme", "values": { "theme": "dark" } }
values uses partial merge — only include fields you want to change.
Full Category Reference
LOW risk — cosmetic / preference, trivially reversible
| Category | Fields |
|---|
user | name, avatar, gender, birthday, role, timezone, language, aiExperience, responseStyle, customInfo, autoSendPending, autoExpandThinking, serverMode, remoteServerUrl, remoteApiKey, weatherEnabled, weatherCity, weatherLatitude, weatherLongitude |
theme | theme (auto/light/dark) |
language | language (auto/zh/en/…) |
ui_effects | uiEffectsEnabled |
prevent_sleep | preventSleep (bool, default false). When true, the primary process keeps the host awake by holding an OS sleep assertion (macOS caffeinate -i / Linux logind inhibitor / Windows ES_SYSTEM_REQUIRED) so long-running tasks, downloads, and background work aren't interrupted by idle sleep. The display may still turn off; takes effect immediately, no restart needed. |
notification | enabled |
startup_notification | enabled (default true), windowSecs (lookback for "active" chats, default 259200 = 72h), globalMax (cap on the number of chats actually notified per boot — applied after silencing / cooldown filters so they can't starve fresh chats; default 30), cooldownSecs (per-chat silence after a notice, default 1800 = 30 min), crashLoopThreshold (suppress entirely when , default 3). Drives the short "back online" notice fanned out to recently-active IM chats after every fresh process boot (see ). Each send task waits up to 30s for its IM account worker to flip to running (covers OAuth-y handshakes) before bailing — a timeout does burn cooldown, so the next boot retries. Per-account silencing lives on and must be edited in the Channels GUI (this skill cannot reach it). |
MEDIUM risk — behavioral changes (cost, context, output quality)
| Category | Fields |
|---|
compact | Master: enabled, cacheTtlSecs (default 300, max 900). Trim ratios: softTrimRatio (default 0.50), hardClearRatio (default 0.70). Reactive microcompact: reactiveMicrocompactEnabled (default true), reactiveTriggerRatio (default 0.75, range 0.50–0.95). Tool-result trimming: toolPolicies (HashMap mapping tool name → eager/protect), maxToolResultContextShare (default 0.3, range 0.1–0.6), keepLastAssistants (default 4), minPrunableToolChars (default 20000), softTrimMaxChars / softTrimHeadChars / softTrimTailChars (default 6000/2000/2000), hardClearEnabled, hardClearPlaceholder. Tier 3 summary: summarizationModel (provider:model override), summarizationThreshold (default 0.85), preserveRecentTurns (default 4, max 12), summarizationTimeoutSecs (default 60), summaryMaxTokens (default 4096), maxHistoryShare (default 0.5), maxCompactionSummaryChars (default 16000, range 4000–64000), identifierPolicy (strict/off/custom), identifierInstructions, customInstructions. Recovery: recoveryEnabled, recoveryMaxFiles (default 5), recoveryMaxFileBytes (default 16384). |
session_title | enabled, providerId, modelId (null provider/model = use the chat model). When enabled, new sessions keep the first-message fallback title immediately, then run one LLM call after the first assistant reply to generate a concise title. Manual renames are never overwritten. |
memory_extract | autoExtract, extractProviderId, extractModelId, flushBeforeCompact, (default 8000), (default 300), (default 10), (default 1800), |
HIGH risk — require explicit user confirmation
| Category | Fields | Why high risk |
|---|
proxy | mode, url | Affects ALL outgoing HTTP |
embedding | provider, model, dimensions | May invalidate existing vector indexes |
shortcuts | bindings (array) | Global OS keybindings, can collide |
skills | extraSkillsDirs, disabledSkills, skillEnvCheck, allowRemoteInstall | Disabling skills removes tools; allowRemoteInstall opens the HTTP /api/skills/{name}/install route that spawns brew/npm -g/go install/uv tool install — effectively RCE over the API Key |
server | bindAddr (e.g. 127.0.0.1:8420 vs 0.0.0.0:8420), apiKey, publicBaseUrl. Read responses redact apiKey to "[REDACTED]" so the bearer token isn't echoed back on every overview; writes still flow through. | Network exposure, requires app restart |
acp_control | enabled, backends (each: id, name, binary, acpArgs, enabled, defaultModel, env), maxConcurrentSessions, defaultTimeoutSecs, runtimeTtlSecs, autoDiscover. Read responses redact non-empty backends[*].env to "[REDACTED]" because env frequently carries ANTHROPIC_API_KEY / OPENAI_API_KEY overrides. | Controls external agent delegation |
Read-only (cannot be modified via this tool)
| Category | Description |
|---|
active_model | Current primary model — use Settings UI |
fallback_models | Fallback chain — use Settings UI |
channels | IM Channel accounts (Telegram / WeChat / Feishu / QQ / Discord). Read returns the account list with credentials and settings fields redacted ("[REDACTED]"); structural metadata (id, channelId, label, enabled, agentId, autoApproveTools, security) is exposed so the model can reference accounts without seeing bot tokens. Writes must go through Settings → Channels so the registry can drop/re-establish listeners under user supervision and credentials stay out of conversation logs. |
mcp_servers | MCP server configs. Read returns the server list with env, headers, oauth fields redacted. Writes must go through Settings → MCP Servers UI which enforces "trust acknowledgement" for stdio servers and routes credentials through platform::write_secure_file (0600). |
hooks | Hooks system (Claude Code compatible). Read returns { disableAllHooks, hooks } with http handler headers values redacted. Read-only here on purpose — hooks run arbitrary commands / HTTP / LLM prompts / sub-agents on lifecycle events, so a writable category would let the model persist its own command execution (privilege escalation). Edit in Settings → Hooks or the scope files (user: config.json; project: <working_dir>/.hope-agent/hooks.json, repo-shared; local: hooks.local.json, git-ignored; managed: /etc/hope-agent/hooks.json). All scopes are UNIONed. |
stt_providers | Speech-to-Text providers (cloud + local servers). Read returns the provider list with apiKey, authProfiles[*].apiKey redacted and the entire extra map replaced with (covers Volcengine / , iFlytek , Azure region key, etc.). Writes must go through Settings → Speech-to-Text so credentials stay out of conversation logs. |
Model / Provider / API Key / IM Channel accounts / MCP server configs / STT providers / per-session configs require the Settings UI.
Special: teams Semantics
Unlike every other category, teams does not live in AppConfig — it targets rows in the team_templates SQLite table. The update_settings payload is CRUD-shaped:
{
"category": "teams",
"values": {
"action": "save",
"template": {
"templateId": "fullstack-py-react",
"name": "Full-Stack (Py + React)",
"description": "Frontend (React expert) + Backend (Python expert) + Tester",
"members": [
{
"name": "Frontend",
"role": "worker",
"agentId": "react-expert",
"color": "#3B82F6",
"description": "You are the frontend specialist. Build React components with TS.",
"modelOverride":
read returns the full TeamTemplate[] — no values needed.
templateId must be non-empty and unique. Each member's agentId must point to an existing Agent (check list_agents in the Agents panel).
- Deleting a template does not touch any teams that were created from it;
teams.template_id is a historical reference only.
- EventBus broadcasts
template_saved / template_deleted so the UI refreshes live.
Special: skill_env Update Modes
Because per-skill env vars are a nested map, update_settings("skill_env", …) accepts three patch forms:
{ "skillEnv": { "my-skill": { "API_KEY": "xyz" } } }
{ "set": { "my-skill": { "API_KEY": "xyz", "OLD_VAR": null } } }
{ "remove": ["my-skill"] }
Prefer form 2 for targeted edits so you don't overwrite unrelated skills.
Rollback — Every Change Is Reversible
Every write to config.json / user.json — from this tool, the UI, or any other path — automatically snapshots the pre-change file under ~/.hope-agent/backups/autosave/. Last 50 snapshots retained.
list_settings_backups
{ "limit": 10 }
{ "kind": "config" }
Returns {id, timestamp, kind, category, source} newest first.
restore_settings_backup
{ "id": "2026-04-17T10-30-45-123__config__theme__skill" }
- Always HIGH risk — must confirm with the user before calling. Show them the entry's
timestamp, kind, and category.
- Creates a fresh snapshot of the current state first, so the rollback itself is reversible — you can "undo the undo" by restoring the newly-created entry.
- Restoring a
config entry reloads the in-memory cache immediately; server / shortcuts style side effects still apply and may need a restart.
When to proactively offer rollback
- User says "undo that", "revert", "go back", "you broke X" after a recent change.
- User complains about a specific behavior right after you changed a related setting.
- User asks "what did you change?" — list the last few entries to remind them.
Important Notes
- Read before write — always
get_settings first so you can show a diff.
- Confirm before write — especially HIGH risk. Include the risk level in your confirmation prompt.
- Field names are camelCase (e.g.
softRatio, toolTimeout, approvalTimeoutEnabled, askUserQuestionTimeoutEnabled, askUserQuestionTimeoutSecs).
- Security restrictions — cannot modify Providers or API Keys through this tool; guide the user to the Settings UI.
- Surface side effects — if the response has
sideEffect (e.g. "requires restart"), tell the user.
- Secrets in logs — never echo
apiKey, remoteApiKey, or skill_env values back in chat unless the user explicitly asks. Note that get_settings for server / web_search / image_generate / acp_control already redacts the credential fields to "[REDACTED]" — if you see that marker, the field is set but the value is hidden from the model intentionally.
- Rollback is built-in — if a change goes wrong, offer
restore_settings_backup instead of trying to reconstruct the old values manually.