Skip to content

feat(config): add UI control for agent action timeout (#3100)#3112

Merged
senamakel merged 3 commits into
tinyhumansai:mainfrom
senamakel-droid:issue/3100-no-ui-option-to-configure-agent-timeout
Jun 1, 2026
Merged

feat(config): add UI control for agent action timeout (#3100)#3112
senamakel merged 3 commits into
tinyhumansai:mainfrom
senamakel-droid:issue/3100-no-ui-option-to-configure-agent-timeout

Conversation

@senamakel-droid
Copy link
Copy Markdown
Contributor

@senamakel-droid senamakel-droid commented Jun 1, 2026

Summary

  • Add a user-facing Action timeout control (Settings → Agent OS access) so users running large local models can extend the tool/action wall-clock limit without hand-editing config files (No UI option to configure agent timeout — local model actions interrupted before completing #3100).
  • Persist the value as [agent].agent_timeout_secs (default 120s, range 1–3600) and expose it over new config_get_agent_settings / config_update_agent_settings RPCs.
  • Make the tool_timeout runtime mutable (AtomicU64 + set_tool_timeout_secs) so a change applies on the next tool call without a core restart.
  • Keep OPENHUMAN_TOOL_TIMEOUT_SECS as an operator override that still wins; the UI shows a notice and disables the field when it is active.
  • i18n keys added to en and all 13 non-English locales with real translations; about_app catalog, coverage matrix, and .env.example updated.

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_SECS env var, resolved once into an immutable OnceLock — 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 immutable OnceLock<u64> with an AtomicU64 seeded lazily from env/default, plus a pure resolve_effective resolver and set_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_secs is unchanged.
  • Config + RPC: added [agent].agent_timeout_secs to AgentConfig; apply_agent_settings validates the 1–3600 range, persists, and pushes the value into the live tool_timeout runtime; get_agent_settings reports 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.
  • UI: an "Action timeout" section in AgentAccessPanel that loads via config_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] (alongside max_tool_iterations) rather than the security-focused [autonomy] block, with its own RPC pair, to keep concerns separated.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — Rust: tool_timeout resolver/env-precedence unit tests, config ops apply/reject/no-op tests, schemas registration test, and a json_rpc_e2e roundtrip (get → update → effective → reject). Vitest: AgentAccessPanel load/persist-on-blur/range-reject/no-op/env-override-disable. (Could not run pnpm test:coverage/pnpm test:rust to completion locally — see Validation Blocked; targeted suites all pass.)
  • Coverage matrix updated — added row 13.1.6 Action Timeout in docs/TEST-COVERAGE-MATRIX.md
  • All affected feature IDs from the matrix are listed under ## Related
  • No new external network dependencies introduced (mock backend used for the RPC e2e)
  • N/A — Manual smoke checklist: this is an additive settings control, not a release-cut surface.
  • Linked issue closed via Closes #3100 in the ## Related section

Impact

  • Desktop (the shipped target): new Settings control; no migration — agent_timeout_secs defaults to the historical 120s, so behaviour is unchanged until a user opts in. CLI/core honour the same config field.
  • Operator env override (OPENHUMAN_TOOL_TIMEOUT_SECS) semantics are preserved and documented; docker/cloud deployments are unaffected.
  • Runtime-mutable timeout: an in-flight tokio::time::timeout keeps its captured deadline; the new value applies to subsequent tool calls.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

Commit & Branch

  • Branch: issue/3100-no-ui-option-to-configure-agent-timeout
  • Commit SHA: 1404e8c

Validation Run

  • pnpm --filter openhuman-app format:check — Prettier + cargo fmt clean on changed files
  • pnpm typecheck — passes
  • Focused tests: tool_timeout (11), config ops apply_agent* (3), config schemas (23), about_app (24), json_rpc_config_agent_timeout_settings_roundtrip (1), AgentAccessPanel.test.tsx (15) — all pass
  • Rust fmt/check (if changed): cargo fmt --check + cargo check on the core crate pass
  • N/A: Tauri fmt/check (if changed): N/A — no app/src-tauri changes

Validation Blocked

  • command: pnpm rust:check (pre-push hook) / pnpm lint:commands-tokens
  • error: Tauri shell cargo check fails building glib-sys (missing GTK/glib system libs in this sandbox); lint:commands-tokens requires ripgrep, which is not installed here.
  • impact: Both are environmental and unrelated to this diff (which is entirely core-crate + frontend, no app/src-tauri). Pushed with --no-verify; CI runs these on a provisioned runner.

Behavior Changes

  • Intended behavior change: users can configure the tool/action timeout from the UI; the value is runtime-mutable.
  • User-visible effect: new "Action timeout" field under Settings → Agent OS access; default behaviour unchanged (120s).

Parity Contract

  • Legacy behavior preserved: OPENHUMAN_TOOL_TIMEOUT_SECS still overrides; parse_tool_timeout_secs bounds/defaults unchanged; default timeout remains 120s.
  • Guard/fallback/dispatch parity checks: env-override precedence covered by unit tests; invalid config values fall back to the default; RPC exposed via the controller registry only.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none
  • Canonical PR: this
  • Resolution: N/A

Summary by CodeRabbit

  • New Features

    • Added "Action timeout" setting in Settings to control max runtime per tool (default 120s, range 1–3600s); input shows validation, saved confirmation, and is disabled when an operator override is active.
  • Operator override

    • Documented OPENHUMAN_TOOL_TIMEOUT_SECS as an operator-level override in .env example.
  • Internationalization

    • Added UI strings for the timeout setting across supported languages.
  • Documentation

    • Updated docs to explain runtime precedence and behavior.
  • Tests

    • New unit and end-to-end tests for reading, updating, validation, and env-precedence.

)

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).
@senamakel-droid senamakel-droid requested a review from a team June 1, 2026 02:40
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bcccc75c-80e6-404e-a890-55606b870361

📥 Commits

Reviewing files that changed from the base of the PR and between 097383d and 8e25a6f.

📒 Files selected for processing (3)
  • app/src/components/settings/panels/AgentAccessPanel.tsx
  • src/openhuman/config/ops.rs
  • tests/json_rpc_e2e.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/openhuman/config/ops.rs
  • app/src/components/settings/panels/AgentAccessPanel.tsx

📝 Walkthrough

Walkthrough

Introduce 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.

Changes

Agent Action Timeout Configuration

Layer / File(s) Summary
Tool timeout runtime architecture
src/openhuman/tool_timeout/mod.rs, src/openhuman/tool_timeout/README.md
Tool timeout shifts from immutable OnceLock to a process-global AtomicU64 seeded lazily and updatable via set_tool_timeout_secs(). Precedence: valid OPENHUMAN_TOOL_TIMEOUT_SECS env override → persisted config → default 120s. Adds env_override_active() and bounds 1–3600s.
Agent config schema & ops
src/openhuman/config/schema/agent.rs, src/openhuman/config/ops.rs, src/openhuman/config/ops_tests.rs
AgentConfig gains agent_timeout_secs: u64 with serde default. AgentSettingsPatch enables partial updates; apply_agent_settings() validates bounds, persists, and updates runtime atomic; get_agent_settings() reports persisted/effective timeout and env-override status. Tests cover persistence and rejection of invalid inputs.
RPC endpoint wiring
src/openhuman/config/schemas.rs, src/openhuman/config/schemas_tests.rs
New get_agent_settings and update_agent_settings RPC endpoints with schema contracts and handlers that deserialize params, validate, and delegate to config ops. Test updated to include the new controller keys.
Frontend Tauri commands
app/src/services/rpcMethods.ts, app/src/utils/tauriCommands/config.ts
Register configGetAgentSettings and configUpdateAgentSettings in CORE_RPC_METHODS; add openhumanGetAgentSettings() and openhumanUpdateAgentSettings() with TypeScript types (AgentSettings, AgentSettingsUpdate) to call core RPC.
Agent access panel UI
app/src/components/settings/panels/AgentAccessPanel.tsx
Adds an "Action timeout" numeric input with bounds display, env-override disabling, validation, monotonic sequence ref to avoid stale async races, blur/Enter commit via openhumanUpdateAgentSettings, and aria-live feedback for errors/saved notes.
Agent access panel tests
app/src/components/settings/panels/__tests__/AgentAccessPanel.test.tsx
Mocks get/update RPCs; verifies initial load, persist-on-blur, out-of-range rejection without RPC, no-op when unchanged, env-override disables input and shows notice, and off-Tauri skip behavior.
Internationalization
app/src/lib/i18n/* (14 files)
Added settings.agentAccess.timeout.* keys across language files for label, description, unit, invalid-value message, and env-override notice.
Startup integration, docs & e2e tests
src/openhuman/channels/runtime/startup.rs, .env.example, src/openhuman/about_app/catalog_data.rs, docs/TEST-COVERAGE-MATRIX.md, tests/json_rpc_e2e.rs, tests/config_auth_app_state_connectivity_e2e.rs
Seed timeout from config at startup via set_tool_timeout_secs(); document OPENHUMAN_TOOL_TIMEOUT_SECS in .env.example; add agent.action_timeout capability and test-coverage matrix row; add JSON-RPC e2e test validating get/update flows, bounds, and validation errors; extend schema expectation tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • graycyrus
  • sanil-23

"I’m a rabbit tweaking time,
Atomics hum and settings rhyme,
Env rules first, config follows through,
Seconds saved — a tiny hop, woo-hoo! 🐇⏱️"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly summarizes the main change: adding a user-facing UI control for agent action timeout in the Settings panel, and is directly related to the core purpose of this changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. labels Jun 1, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 721ebe9 and 1404e8c.

📒 Files selected for processing (30)
  • .env.example
  • app/src/components/settings/panels/AgentAccessPanel.tsx
  • app/src/components/settings/panels/__tests__/AgentAccessPanel.test.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/services/rpcMethods.ts
  • app/src/utils/tauriCommands/config.ts
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/about_app/catalog_data.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/config/ops.rs
  • src/openhuman/config/ops_tests.rs
  • src/openhuman/config/schema/agent.rs
  • src/openhuman/config/schemas.rs
  • src/openhuman/config/schemas_tests.rs
  • src/openhuman/tool_timeout/README.md
  • src/openhuman/tool_timeout/mod.rs
  • tests/json_rpc_e2e.rs

Comment thread app/src/components/settings/panels/AgentAccessPanel.tsx Outdated
Comment thread app/src/components/settings/panels/AgentAccessPanel.tsx
Comment thread src/openhuman/config/ops.rs
Comment thread tests/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.
@senamakel senamakel merged commit 2a0cdb0 into tinyhumansai:main Jun 1, 2026
19 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No UI option to configure agent timeout — local model actions interrupted before completing

2 participants