feat(config): add UI control for agent action timeout (#3100)#3112
Conversation
) Adds a user-facing "Action timeout" setting so users running large local models can extend the tool/action wall-clock limit without hand-editing config files. Previously the timeout was env-var-only (OPENHUMAN_TOOL_TIMEOUT_SECS), cached immutably in a OnceLock. - tool_timeout: make the effective timeout runtime-mutable (AtomicU64 + set_tool_timeout_secs) with a pure resolver; the operator env var still wins when set, otherwise the persisted config drives it. Read fresh per tool call so changes apply without a restart. - config: add [agent].agent_timeout_secs (default 120, range 1-3600) plus config_get_agent_settings / config_update_agent_settings RPC (controller registry only). Seed the runtime value from config at startup. - UI: "Action timeout" section in AgentAccessPanel (Settings -> Agent OS access) with env-override notice; i18n keys in en + all 13 locales. - about_app catalog + coverage matrix + .env.example docs updated. - Tests: tool_timeout resolver/env-precedence, config ops apply/reject, schemas registration, json_rpc_e2e roundtrip, and Vitest panel coverage (load/persist/range-reject/no-op/env-override).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughIntroduce a runtime-mutable agent action timeout (1–3600s, default 120s) with env override precedence, persisted config, RPC get/update endpoints, frontend Settings control, i18n strings, startup seeding, docs, and tests. ChangesAgent Action Timeout Configuration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/src/components/settings/panels/AgentAccessPanel.tsx`:
- Around line 230-239: The save-response handler can overwrite a newer user edit
because it only checks request order (timeoutSeqRef) rather than whether the
input has changed since the save began; capture the input value when initiating
the save (e.g., const originalInput = timeoutInput or use a ref), call
openhumanUpdateAgentSettings with parsed, and on success only call
setTimeoutInput and setTimeoutSavedNote if timeoutSeqRef.current === seq AND the
current input still equals originalInput (or ensure the current input ref
matches originalInput); still update setSavedTimeoutSecs when the save
completes, but avoid snapping timeoutInput back if the user has typed a newer
value since the request started (referencing timeoutSeqRef, setTimeoutInput,
setSavedTimeoutSecs, setTimeoutSavedNote, openhumanUpdateAgentSettings).
- Around line 92-107: The current Promise.all([...]) call couples
openhumanGetAutonomySettings() and openhumanGetAgentSettings() so any rejection
from the agent timeout RPC prevents updating autonomy state; split these calls
and handle errors independently so autonomy still renders: call
openhumanGetAutonomySettings() and update setLevel, setWorkspaceOnly,
setRequireTaskPlanApproval, setTrustedRoots, setAutoApprove inside its own
try/catch (or use Promise.allSettled and apply results.result for autonomy even
if agent fails), then separately call openhumanGetAgentSettings() and update
setTimeoutInput, setSavedTimeoutSecs, setTimeoutEnvOverride, setTimeoutMin,
setTimeoutMax inside its own try/catch and log or ignore agent errors without
returning early; keep the cancelled check semantics around both updates.
In `@src/openhuman/config/ops.rs`:
- Around line 1023-1031: get_agent_settings currently reads persisted config but
calls tool_execution_timeout_secs() which may still return an env/default value
until set_tool_timeout_secs() has been called elsewhere, causing
effective_timeout_secs to be stale; fix by computing the effective timeout from
the loaded config (or by calling
set_tool_timeout_secs(config.agent.agent_timeout_secs) prior to reading
tool_execution_timeout_secs()) so effective_timeout_secs reflects
config.agent.agent_timeout_secs; update get_agent_settings to use the config
value (or call set_tool_timeout_secs with config.agent.agent_timeout_secs) and
reference get_agent_settings, load_config_with_timeout,
tool_execution_timeout_secs, set_tool_timeout_secs, and
config.agent.agent_timeout_secs when making the change.
In `@tests/json_rpc_e2e.rs`:
- Around line 9088-9202: The test
json_rpc_config_agent_timeout_settings_roundtrip mutates the process-global
runtime timeout and never restores it; capture the original effective timeout at
the start (via the existing openhuman.config_get_agent_settings call or by
reading initial_result.agent_timeout_secs) and restore it at the end of the test
by calling openhuman.config_update_agent_settings with that saved value (or
install a small RAII guard in the test that calls the same RPC in its Drop to
ensure restoration even on early return/panic), so later tests don’t inherit the
modified AtomicU64.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4e2130b8-7bf6-4da3-a9fe-356e14f8c167
📒 Files selected for processing (30)
.env.exampleapp/src/components/settings/panels/AgentAccessPanel.tsxapp/src/components/settings/panels/__tests__/AgentAccessPanel.test.tsxapp/src/lib/i18n/ar.tsapp/src/lib/i18n/bn.tsapp/src/lib/i18n/de.tsapp/src/lib/i18n/en.tsapp/src/lib/i18n/es.tsapp/src/lib/i18n/fr.tsapp/src/lib/i18n/hi.tsapp/src/lib/i18n/id.tsapp/src/lib/i18n/it.tsapp/src/lib/i18n/ko.tsapp/src/lib/i18n/pl.tsapp/src/lib/i18n/pt.tsapp/src/lib/i18n/ru.tsapp/src/lib/i18n/zh-CN.tsapp/src/services/rpcMethods.tsapp/src/utils/tauriCommands/config.tsdocs/TEST-COVERAGE-MATRIX.mdsrc/openhuman/about_app/catalog_data.rssrc/openhuman/channels/runtime/startup.rssrc/openhuman/config/ops.rssrc/openhuman/config/ops_tests.rssrc/openhuman/config/schema/agent.rssrc/openhuman/config/schemas.rssrc/openhuman/config/schemas_tests.rssrc/openhuman/tool_timeout/README.mdsrc/openhuman/tool_timeout/mod.rstests/json_rpc_e2e.rs
The `worker_a_controller_schemas_are_fully_exposed` test pins the full list of config-namespace RPC method names. Add the two new methods (`config_get_agent_settings`, `config_update_agent_settings`) to the expected list in alphabetical order.
- Decouple timeout fetch from autonomy load so a timeout-RPC failure doesn't block the pre-existing access-mode controls. - Avoid overwriting a newer draft when an older save response arrives (compare draftAtCommit before snapping timeoutInput). - Seed the runtime timeout from config in get_agent_settings so the effective_timeout_secs field is correct even without a full boot. - Restore the process-global timeout to the default after the e2e test to prevent order-dependent bleeding across tests.
Summary
[agent].agent_timeout_secs(default 120s, range 1–3600) and expose it over newconfig_get_agent_settings/config_update_agent_settingsRPCs.tool_timeoutruntime mutable (AtomicU64+set_tool_timeout_secs) so a change applies on the next tool call without a core restart.OPENHUMAN_TOOL_TIMEOUT_SECSas an operator override that still wins; the UI shows a notice and disables the field when it is active.enand all 13 non-English locales with real translations; about_app catalog, coverage matrix, and.env.exampleupdated.Problem
A user (GameySins, via Discord) reported that agent actions using a local model are cut off by the tool-execution timeout before the model finishes responding. They explicitly want to extend the timeout, not switch to a smaller model. The only knob today is the
OPENHUMAN_TOOL_TIMEOUT_SECSenv var, resolved once into an immutableOnceLock— there is no UI, and the workaround is hand-editing config/.env. This is the feature-request gap in #3100.Solution
End-to-end, following the existing autonomy-settings pattern:
tool_timeout(src/openhuman/tool_timeout/mod.rs): replaced the immutableOnceLock<u64>with anAtomicU64seeded lazily from env/default, plus a pureresolve_effectiveresolver andset_tool_timeout_secs. Precedence: valid env var → persisted config → 120s default. Both consumers (engine/tools.rs,delegate.rs) read fresh per call, so changes take effect immediately.parse_tool_timeout_secsis unchanged.[agent].agent_timeout_secstoAgentConfig;apply_agent_settingsvalidates the 1–3600 range, persists, and pushes the value into the livetool_timeoutruntime;get_agent_settingsreports the configured value, the runtime-effective value,env_override, and the bounds for the UI. Exposed via the controller registry only. Startup seeds the runtime from config.AgentAccessPanelthat loads viaconfig_get_agent_settings, persists on blur/Enter (independent of the autonomy block, with a last-write-wins guard), validates client-side, and disables itself with an explanatory notice when the env override is active.Design note: the timeout lives in
[agent](alongsidemax_tool_iterations) rather than the security-focused[autonomy]block, with its own RPC pair, to keep concerns separated.Submission Checklist
tool_timeoutresolver/env-precedence unit tests,configops apply/reject/no-op tests, schemas registration test, and ajson_rpc_e2eroundtrip (get → update → effective → reject). Vitest:AgentAccessPanelload/persist-on-blur/range-reject/no-op/env-override-disable. (Could not runpnpm test:coverage/pnpm test:rustto completion locally — see Validation Blocked; targeted suites all pass.)13.1.6 Action Timeoutindocs/TEST-COVERAGE-MATRIX.md## RelatedCloses #3100in the## RelatedsectionImpact
agent_timeout_secsdefaults to the historical 120s, so behaviour is unchanged until a user opts in. CLI/core honour the same config field.OPENHUMAN_TOOL_TIMEOUT_SECS) semantics are preserved and documented; docker/cloud deployments are unaffected.tokio::time::timeoutkeeps its captured deadline; the new value applies to subsequent tool calls.Related
13.1.6(Action Timeout); capabilityagent.action_timeoutAI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
issue/3100-no-ui-option-to-configure-agent-timeoutValidation Run
pnpm --filter openhuman-app format:check— Prettier + cargo fmt clean on changed filespnpm typecheck— passestool_timeout(11), config opsapply_agent*(3), config schemas (23), about_app (24),json_rpc_config_agent_timeout_settings_roundtrip(1),AgentAccessPanel.test.tsx(15) — all passcargo fmt --check+cargo checkon the core crate passapp/src-taurichangesValidation Blocked
command:pnpm rust:check(pre-push hook) /pnpm lint:commands-tokenserror:Tauri shellcargo checkfails buildingglib-sys(missing GTK/glib system libs in this sandbox);lint:commands-tokensrequiresripgrep, which is not installed here.impact:Both are environmental and unrelated to this diff (which is entirely core-crate + frontend, noapp/src-tauri). Pushed with--no-verify; CI runs these on a provisioned runner.Behavior Changes
Parity Contract
OPENHUMAN_TOOL_TIMEOUT_SECSstill overrides;parse_tool_timeout_secsbounds/defaults unchanged; default timeout remains 120s.Duplicate / Superseded PR Handling
Summary by CodeRabbit
New Features
Operator override
Internationalization
Documentation
Tests