Skip to content

feat(app): UI control for max_actions_per_hour (#2486)#2500

Merged
senamakel merged 24 commits into
tinyhumansai:mainfrom
EvanCarson:feat/ui-max-actions-per-hour
May 23, 2026
Merged

feat(app): UI control for max_actions_per_hour (#2486)#2500
senamakel merged 24 commits into
tinyhumansai:mainfrom
EvanCarson:feat/ui-max-actions-per-hour

Conversation

@EvanCarson
Copy link
Copy Markdown
Contributor

@EvanCarson EvanCarson commented May 22, 2026

Summary

Scopes #2486 to a single autonomy knob: making max_actions_per_hour editable from the UI instead of requiring hand-edits to ~/.openhuman/users/<id>/config.toml.

  • Adds openhuman.config_get_autonomy_settings / openhuman.config_update_autonomy_settings JSON-RPC methods. Mirrors the existing config_*_meet_settings pattern (patch struct + apply fn + load_and_apply wrapper + handler + controller registration).
  • Surfaces the control via a new AutonomyPanel at /settings/autonomy, linked from Settings → Developer Options → Agent autonomy. Number input (1–10000) with presets (20/100/500/1000), client + server validation, inline save confirmation, error recovery to last-committed value.
  • Persists to the user's config.toml. Takes effect on the next desktop chat. Cron jobs and channel listeners keep their existing limit until you restart OpenHuman (they cache the policy at startup — surfaced in the panel's helper text so users aren't surprised).

The new panel is shaped so follow-up PRs can extend AutonomySettingsPatch with other knobs from #2486 (allowed_commands, auto_approve, block_high_risk_commands, max_cost_per_day_cents) without restructuring.

Out of scope

  • Hot-reload of in-flight cron / channel policies. Would require an event-bus-driven PolicyChanged event + subscribers in every site holding an Arc<SecurityPolicy>. Documented in the helper text and PR body.
  • Pre-existing openhuman.security_policy_info bug (returns SecurityPolicy::default() instead of the loaded config). This PR sidesteps it by reading from the new dedicated RPC; separate follow-up.
  • Other autonomy fields from OpenHuman 不执行命令和无反馈的分析 #2486 — explicitly deferred to follow-up PRs.

Test plan

  • cargo test --lib -- autonomy — 13/13 pass (4 new in apply_*, 1 in load_and_apply_*, 2 in handler-level tests, plus 6 pre-existing autonomy/policy tests).
  • cargo test --test json_rpc_e2e json_rpc_config_autonomy_settings_roundtrip — 1/1 (default-get + update + persist-get + invalid-rejected over real HTTP JSON-RPC).
  • pnpm debug unit src/utils/tauriCommands/config.test.ts — 18/18 (14 pre-existing + 4 new).
  • pnpm debug unit src/components/settings/panels/__tests__/AutonomyPanel.test.tsx — 5/5 (load / save-disabled / save-confirms / out-of-range / error-reverts).
  • pnpm exec vitest run app/src/lib/i18n/__tests__/coverage.test.ts — 46/46 (autonomy keys added to all 12 locale-5 chunks).
  • (N/A) WDIO E2E (app/test/e2e/specs/settings-advanced-config.spec.ts — new case 'persists autonomy max_actions_per_hour through core RPC') — blocked by pre-existing TypeScript duplicate-key errors in de-3.ts/de-5.ts that fail tsc --noEmit before the E2E build runs (also fails on main). Spec is added and follows the adjacent 'persists composio trigger triage settings' pattern; will run once the i18n dedup is fixed in a separate PR.
  • (N/A) Manual smoke (pnpm dev:app) — not runnable in CI (Tauri desktop). Steps for the human reviewer: open Settings → Developer Options → Agent autonomy, change value to 300, save, reopen panel to verify persistence, then trigger >20 tool calls in a new chat to confirm the new ceiling takes effect.

CI status

Two checks fail on this PR. Both are pre-existing failures on main (confirmed against upstream ed3e453b) and not introduced by this branch:

  • Type Check TypeScript — fails on duplicate object literal property keys in app/src/lib/i18n/chunks/de-3.ts (lines 107/126 and 108/127, subconscious.providerUnavailableTitle and subconscious.providerSettings) and app/src/lib/i18n/chunks/de-5.ts (lines 211/526, 217/531, etc., settings.developerMenu.mcpServer.* and settings.mcpServer.*). These existed before this branch — verifiable by checking the same check on the current main head.
  • e2e / E2E (Linux / Appium Chromium) — same root cause; the E2E job runs tsc first and exits on the i18n duplicate-key errors before reaching any E2E spec.

These are not in scope for this PR. Happy to file a separate cleanup PR to deduplicate the i18n chunks if helpful.

Notes for reviewers

  • --no-verify was used on push: the husky pre-push hook runs pnpm format which shells out to cargo fmtcargo is not in the hook's PATH on this environment. cargo fmt --check and pnpm format:check both pass when run directly. Not introduced by this branch.
  • The implementation commits are atomic TDD pairs (test commit + impl commit, sometimes combined). Follow them top-to-bottom for the build-up: Rust ops → schemas → handlers → JSON-RPC E2E → TS constants → wrappers → panel → routing → UI tests → E2E case → formatting + i18n fixups.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added an "Agent autonomy" panel in Developer Options with presets, validated numeric input for max actions-per-hour, Save with inline success/error messages, and back/breadcrumb navigation; changes persist.
  • Documentation

    • Added autonomy menu translation strings for multiple languages.
  • Tests

    • Added unit, integration, and end-to-end tests for the autonomy UI, RPC calls, validation, and persistence.

Review Change Stack

@EvanCarson EvanCarson requested a review from a team May 22, 2026 17:51
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

Adds an Agent Autonomy settings leaf: UI panel, route, developer-menu entry, i18n strings, TypeScript RPC wrappers and Tauri commands, Rust config ops and JSON‑RPC handlers with 1–10000 validation, plus unit, integration, and E2E tests covering the full stack.

Changes

Autonomy Settings Feature

Layer / File(s) Summary
Settings Navigation and Route Definition
app/src/components/settings/hooks/useSettingsNavigation.ts, app/src/pages/Settings.tsx
SettingsRoute union adds 'autonomy'; URL resolution and breadcrumb generation updated to handle /settings/autonomy; Settings imports and registers AutonomyPanel route.
AutonomyPanel React Component with Unit Tests
app/src/components/settings/panels/AutonomyPanel.tsx, app/src/components/settings/panels/__tests__/AutonomyPanel.test.tsx
Async component loads current max_actions_per_hour, maintains committed/draft, validates integer MIN–MAX, offers presets, conditionally enables Save, persists via Tauri RPC wrapper, reverts on failure, and displays inline validation/status; comprehensive unit tests cover load, state transitions, save flow, validation, and error handling.
Developer Menu Entry and Settings Page Wiring
app/src/components/settings/panels/DeveloperOptionsPanel.tsx
Adds autonomy entry to Developer Options menu with i18n title/description keys and SVG icon.
Multi-Language i18n Translations
app/src/lib/i18n/en.ts, app/src/lib/i18n/chunks/{ar,bn,de,en,es,fr,hi,id,it,ko,pt,ru,zh-CN}-5.ts
Adds settings.developerMenu.autonomy.title and settings.developerMenu.autonomy.desc translations across language chunks and the main English bundle.
TypeScript RPC Constants and Tauri Command Wrappers
app/src/services/rpcMethods.ts, app/src/utils/tauriCommands/config.ts, app/src/utils/tauriCommands/config.test.ts
CORE_RPC_METHODS adds autonomy RPC identifiers; openhumanGetAutonomySettings and openhumanUpdateAutonomySettings wrappers gate to Tauri and forward to core RPC; tests verify Tauri guard and correct forwarding with max_actions_per_hour shapes.
Settings UI End-to-End Test
app/test/e2e/specs/settings-advanced-config.spec.ts
E2E spec navigates to /settings/autonomy, edits #autonomy-max-actions, saves, waits for “Saved.” confirmation, and polls core RPC until persisted value matches target.
Rust Config Operations: Patch, Apply, and Validation Tests
src/openhuman/config/ops.rs, src/openhuman/config/ops_tests.rs
Adds AutonomySettingsPatch; apply_autonomy_settings validates range (1–10000), updates/persists config.autonomy.max_actions_per_hour, and returns RPC outcome; load_and_apply_autonomy_settings wraps load+apply; unit tests cover persistence, no-op, and validation rejection cases.
Rust JSON-RPC Schema, Handler Registration, and Handler Tests
src/openhuman/config/schemas.rs, src/openhuman/config/schemas_tests.rs
Adds AutonomySettingsUpdate params; registers update_autonomy_settings and get_autonomy_settings; implements handlers that build patches and call config ops; tests verify read and invalid update behavior.
Rust JSON-RPC E2E Roundtrip Integration Test
tests/json_rpc_e2e.rs
Integration test asserts default max_actions_per_hour (20), updates to 250 and verifies persistence, and confirms validation rejection for out-of-range values with expected message text.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • graycyrus

Poem

🐰 I nibble keys and click presets bright,
Counting actions through day and night,
I fetch, I save, I validate with care,
Revert if broken, show a success flare,
Autonomy set — the tests all cheer!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(app): UI control for max_actions_per_hour' accurately describes the main change—adding a user interface for controlling the max_actions_per_hour setting in the application.
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.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 the feature Net-new user-facing capability or product behavior. label May 22, 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.

🧹 Nitpick comments (3)
docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md (2)

186-199: ⚡ Quick win

Add language specifier to fenced code block.

The file list should have a language specifier. Use text for plain lists.

📝 Proposed fix
-```
+```text
 src/openhuman/config/ops.rs              (+ ~30 lines, mirror meet pattern)
🤖 Prompt for 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.

In `@docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md` around
lines 186 - 199, The fenced code block that lists changed files is missing a
language specifier; update the opening fence from ``` to ```text for the block
that begins with the line "src/openhuman/config/ops.rs              (+ ~30
lines, mirror meet pattern)" so the file list is rendered as plain text and keep
the closing ``` unchanged.

31-54: ⚡ Quick win

Add language specifier to fenced code block.

The architecture diagram should specify a language for proper syntax highlighting and rendering. Use text or ascii for ASCII art diagrams.

📝 Proposed fix
-```
+```text
 UI (React)
   DeveloperOptionsPanel — new "Agent autonomy" subsection
🤖 Prompt for 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.

In `@docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md` around
lines 31 - 54, The fenced diagram block in
docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md lacks a
language specifier causing incorrect rendering; update the opening
triple-backtick for the ASCII diagram (the block starting with "UI (React)" /
the architecture diagram) to include a language like text or ascii (e.g.,
```text) so the diagram renders with proper syntax highlighting.
docs/superpowers/plans/2026-05-22-max-actions-per-hour-ui.md (1)

1029-1050: 💤 Low value

Consider streamlining the i18n discussion.

The exploration of multiple approaches (lines 1029-1042) before settling on the final solution adds cognitive load. Since the decision is already made (register i18n keys in en.json), you could simplify by removing the rejected alternatives and leading directly with the chosen approach.

However, the current version does document the thought process, which may be valuable for future maintainers encountering similar decisions.

🤖 Prompt for 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.

In `@docs/superpowers/plans/2026-05-22-max-actions-per-hour-ui.md` around lines
1029 - 1050, Remove the exploratory alternatives and keep only the decided i18n
approach: register the keys used by the renderer instead of fallbacks. Add
"settings.developerMenu.autonomy.title" and
"settings.developerMenu.autonomy.desc" to the en.json locale (matching the
existing nested structure), so t(item.titleKey) / t(item.descriptionKey)
resolve; alternatively, if you prefer not to add i18n keys, set the menu item's
titleKey and descriptionKey to undefined and supply literal title and
description fields (the code references titleKey, descriptionKey and calls
t(item.titleKey) in the render block).
🤖 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.

Nitpick comments:
In `@docs/superpowers/plans/2026-05-22-max-actions-per-hour-ui.md`:
- Around line 1029-1050: Remove the exploratory alternatives and keep only the
decided i18n approach: register the keys used by the renderer instead of
fallbacks. Add "settings.developerMenu.autonomy.title" and
"settings.developerMenu.autonomy.desc" to the en.json locale (matching the
existing nested structure), so t(item.titleKey) / t(item.descriptionKey)
resolve; alternatively, if you prefer not to add i18n keys, set the menu item's
titleKey and descriptionKey to undefined and supply literal title and
description fields (the code references titleKey, descriptionKey and calls
t(item.titleKey) in the render block).

In `@docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md`:
- Around line 186-199: The fenced code block that lists changed files is missing
a language specifier; update the opening fence from ``` to ```text for the block
that begins with the line "src/openhuman/config/ops.rs              (+ ~30
lines, mirror meet pattern)" so the file list is rendered as plain text and keep
the closing ``` unchanged.
- Around line 31-54: The fenced diagram block in
docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md lacks a
language specifier causing incorrect rendering; update the opening
triple-backtick for the ASCII diagram (the block starting with "UI (React)" /
the architecture diagram) to include a language like text or ascii (e.g.,
```text) so the diagram renders with proper syntax highlighting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2319c03a-926a-422e-a176-a96eac8becba

📥 Commits

Reviewing files that changed from the base of the PR and between ed3e453 and 9b46086.

📒 Files selected for processing (29)
  • app/src/components/settings/hooks/useSettingsNavigation.ts
  • app/src/components/settings/panels/AutonomyPanel.tsx
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/components/settings/panels/__tests__/AutonomyPanel.test.tsx
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/bn-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/en-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/fr-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/it-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • app/src/services/rpcMethods.ts
  • app/src/utils/tauriCommands/config.test.ts
  • app/src/utils/tauriCommands/config.ts
  • app/test/e2e/specs/settings-advanced-config.spec.ts
  • docs/superpowers/plans/2026-05-22-max-actions-per-hour-ui.md
  • docs/superpowers/specs/2026-05-22-max-actions-per-hour-ui-design.md
  • src/openhuman/config/ops.rs
  • src/openhuman/config/ops_tests.rs
  • src/openhuman/config/schemas.rs
  • src/openhuman/config/schemas_tests.rs
  • tests/json_rpc_e2e.rs

Chen Qian and others added 19 commits May 22, 2026 11:36
Scopes issue tinyhumansai#2486 to a single autonomy knob: add a new
config_get_autonomy_settings / config_update_autonomy_settings RPC pair,
surface it as an "Agent autonomy" subsection in DeveloperOptionsPanel,
persist to user config.toml. Mirrors the existing config_*_settings
pattern; effect applies to next session.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13-task TDD plan covering Rust ops + RPC schemas + handlers, JSON-RPC
roundtrip, TS wrappers + tests, new AutonomyPanel + route, UI tests, and
E2E case in settings-advanced-config.spec.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the patch struct and apply function for the autonomy settings
domain, following the established MeetSettingsPatch / apply_meet_settings
pattern. Validates max_actions_per_hour is between 1 and 10000 before
persisting. Includes 4 TDD tests covering persist, no-op, and two
validation rejection cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add AutonomySettingsUpdate DTO and ControllerSchema entries for
update_autonomy_settings / get_autonomy_settings in the config
domain schema registry. Handlers and controller registration follow
in Task 4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implement handle_update_autonomy_settings and handle_get_autonomy_settings
in config/schemas.rs, register both in all_registered_controllers, and
add two handler-level tests covering the happy path and validation rejection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds json_rpc_config_autonomy_settings_roundtrip E2E test: verifies the
default value (20), a successful update to 250 persisted across gets, and
that out-of-range values (99999) are rejected with a validation error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the new settings panel at app/src/components/settings/panels/AutonomyPanel.tsx
that lets users view and update the max_actions_per_hour autonomy limit via
the openhumanGetAutonomySettings / openhumanUpdateAutonomySettings RPC wrappers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds settings.developerMenu.autonomy.title and
settings.developerMenu.autonomy.desc to all 11 non-English locale-5
chunk files with English placeholder values, restoring coverage test
parity after the keys were added to en-5.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous wording said "running sessions keep their current limit"
which was only half correct. The cron scheduler and channel listeners
(Telegram/Slack/Discord) also cache the SecurityPolicy at startup and
continue using the old limit until core restart. Updated helper text
makes this explicit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These were local planning artifacts that shouldn't have been committed.
The files remain on disk via .git/info/exclude.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@EvanCarson EvanCarson force-pushed the feat/ui-max-actions-per-hour branch from 97fc9ca to 59c8e5d Compare May 22, 2026 18:37
@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 22, 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: 1

🧹 Nitpick comments (3)
app/src/components/settings/panels/__tests__/AutonomyPanel.test.tsx (1)

71-78: ⚡ Quick win

Add a regression case for non-integer input shapes

Range validation is covered, but there isn’t a test for decimal/scientific-form input remaining invalid. Adding one would prevent silent parsing regressions.

🤖 Prompt for 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.

In `@app/src/components/settings/panels/__tests__/AutonomyPanel.test.tsx` around
lines 71 - 78, Add a regression test to AutonomyPanel.test.tsx that checks
non-integer input shapes remain invalid: after rendering <AutonomyPanel />
(using renderWithProviders) and mocking mockGet to return a valid integer,
change the input (found via screen.findByDisplayValue) to decimal and
scientific-form strings (e.g., '1.5' and '1e3') using fireEvent.change, assert
the same inline validation message (e.g., /Must be an integer between 1 and
10,000/i) appears via screen.findByText, and verify the Save button
(screen.getByRole('button', { name: /^Save$/ })) is disabled for those inputs;
reuse existing helpers and mocks (mockGet, renderWithProviders, screen,
fireEvent) and mirror the existing range test structure for clarity.
app/src/lib/i18n/en.ts (1)

1962-1962: ⚡ Quick win

Remove trailing period for consistency.

Description strings in this i18n file follow a convention of omitting trailing periods (see lines 64, 66, 68, 82–83, 1924, 1928, 1932, 1936).

✨ Proposed fix
-  'settings.developerMenu.autonomy.desc': 'Tool action rate limits and safety thresholds.',
+  'settings.developerMenu.autonomy.desc': 'Tool action rate limits and safety thresholds',
🤖 Prompt for 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.

In `@app/src/lib/i18n/en.ts` at line 1962, The i18n entry
'settings.developerMenu.autonomy.desc' currently ends with a trailing period;
update its value to remove the final period so it matches the surrounding
description convention (e.g., change "Tool action rate limits and safety
thresholds." to "Tool action rate limits and safety thresholds") by editing the
string value for the key 'settings.developerMenu.autonomy.desc' in the en.ts
file.
app/test/e2e/specs/settings-advanced-config.spec.ts (1)

103-121: ⚡ Quick win

Avoid no-op passes by deriving the target value from current state.

At Line 103 you read current autonomy settings, but Line 111 always writes 250. If the saved value is already 250, this can pass without proving an update path worked.

Proposed test hardening
   const before = await callOpenhumanRpc('openhuman.config_get_autonomy_settings', {});
   expect(before.ok).toBe(true);
+  const current = before.result?.result?.max_actions_per_hour ?? 20;
+  const target = current === 250 ? 251 : 250;

   await navigateViaHash('/settings/autonomy');
   await waitForText('Agent autonomy', 15_000);

   const input = await browser.$('`#autonomy-max-actions`');
   await input.waitForExist({ timeout: 10_000 });
-  await input.setValue('250');
+  await input.setValue(String(target));
   await clickText('Save', 10_000);
   await waitForText('Saved.', 10_000);

   await browser.waitUntil(
     async () => {
       const after = await callOpenhumanRpc('openhuman.config_get_autonomy_settings', {});
-      return after.ok && after.result?.result?.max_actions_per_hour === 250;
+      return after.ok && after.result?.result?.max_actions_per_hour === target;
     },
     { timeout: 15_000, interval: 500, timeoutMsg: 'autonomy setting did not persist' }
   );

As per coding guidelines, “Ensure each spec is runnable in isolation” and “Keep tests deterministic… avoid hidden global state.”

🤖 Prompt for 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.

In `@app/test/e2e/specs/settings-advanced-config.spec.ts` around lines 103 - 121,
The test currently reads the autonomy settings via
callOpenhumanRpc('openhuman.config_get_autonomy_settings') (variable before) but
always writes 250, which can be a no-op; change the test to derive a new target
value from before.result?.result?.max_actions_per_hour (e.g., const current =
before.result?.result?.max_actions_per_hour ?? 250; const newValue = current ===
250 ? 249 : current + 1), then set that newValue into the
'`#autonomy-max-actions`' input, clickText('Save'), and update the
browser.waitUntil check to assert max_actions_per_hour === newValue so the test
verifies an actual change.
🤖 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/AutonomyPanel.tsx`:
- Around line 53-56: The current logic uses Number.parseInt(draft, 10) which
truncates inputs like "1.9" and "1e2"; change parsing/validation so
non-integer-looking strings are rejected: convert with Number(draft) (assign to
parsed) and require Number.isInteger(parsed) AND that draft.trim() matches a
strict integer regex (e.g. /^[+-]?\d+$/) before allowing save; keep the
isChanged (committed) and status.kind !== 'saving' checks as-is.

---

Nitpick comments:
In `@app/src/components/settings/panels/__tests__/AutonomyPanel.test.tsx`:
- Around line 71-78: Add a regression test to AutonomyPanel.test.tsx that checks
non-integer input shapes remain invalid: after rendering <AutonomyPanel />
(using renderWithProviders) and mocking mockGet to return a valid integer,
change the input (found via screen.findByDisplayValue) to decimal and
scientific-form strings (e.g., '1.5' and '1e3') using fireEvent.change, assert
the same inline validation message (e.g., /Must be an integer between 1 and
10,000/i) appears via screen.findByText, and verify the Save button
(screen.getByRole('button', { name: /^Save$/ })) is disabled for those inputs;
reuse existing helpers and mocks (mockGet, renderWithProviders, screen,
fireEvent) and mirror the existing range test structure for clarity.

In `@app/src/lib/i18n/en.ts`:
- Line 1962: The i18n entry 'settings.developerMenu.autonomy.desc' currently
ends with a trailing period; update its value to remove the final period so it
matches the surrounding description convention (e.g., change "Tool action rate
limits and safety thresholds." to "Tool action rate limits and safety
thresholds") by editing the string value for the key
'settings.developerMenu.autonomy.desc' in the en.ts file.

In `@app/test/e2e/specs/settings-advanced-config.spec.ts`:
- Around line 103-121: The test currently reads the autonomy settings via
callOpenhumanRpc('openhuman.config_get_autonomy_settings') (variable before) but
always writes 250, which can be a no-op; change the test to derive a new target
value from before.result?.result?.max_actions_per_hour (e.g., const current =
before.result?.result?.max_actions_per_hour ?? 250; const newValue = current ===
250 ? 249 : current + 1), then set that newValue into the
'`#autonomy-max-actions`' input, clickText('Save'), and update the
browser.waitUntil check to assert max_actions_per_hour === newValue so the test
verifies an actual change.
🪄 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: 726b19fd-7722-47ce-804a-19f57310ebaa

📥 Commits

Reviewing files that changed from the base of the PR and between 9b46086 and 59c8e5d.

📒 Files selected for processing (27)
  • app/src/components/settings/hooks/useSettingsNavigation.ts
  • app/src/components/settings/panels/AutonomyPanel.tsx
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/components/settings/panels/__tests__/AutonomyPanel.test.tsx
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/bn-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/en-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/fr-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/it-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • app/src/services/rpcMethods.ts
  • app/src/utils/tauriCommands/config.test.ts
  • app/src/utils/tauriCommands/config.ts
  • app/test/e2e/specs/settings-advanced-config.spec.ts
  • src/openhuman/config/ops.rs
  • src/openhuman/config/ops_tests.rs
  • src/openhuman/config/schemas.rs
  • src/openhuman/config/schemas_tests.rs
  • tests/json_rpc_e2e.rs
✅ Files skipped from review due to trivial changes (4)
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts

Comment thread app/src/components/settings/panels/AutonomyPanel.tsx Outdated
- Strict integer validation: reject '1.5', '1e2', '-5', '0.0' (now uses
  regex + Number() + Number.isInteger instead of parseInt, which would
  truncate decimals to a valid-looking int).
- Add regression test.each cases for non-integer input shapes.
- E2E spec: derive target value from current state so the test exercises
  a real mutation instead of potentially no-op'ing on 250.
- Drop trailing period from autonomy.desc to match en.ts sibling-key
  convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 22, 2026
Chen Qian added 2 commits May 22, 2026 12:39
The Rust Tauri Coverage job hit a flake in
core_process::tests::ensure_running_falls_back_for_unknown_listener_on_port
(file unmodified by this branch; same test passes in non-coverage
sibling job).
…-per-hour

# Conflicts:
#	app/src/lib/i18n/chunks/id-5.ts
Chen Qian and others added 2 commits May 22, 2026 22:11
Replaces English placeholders with proper translations for ar/bn/de/es/
fr/hi/id/it/ko/pt/ru/zh-CN. Also adds the keys to ko-5.ts (Korean isn't
in the coverage test's enforced LOCALES list, but the chunk files exist
and shouldn't be left with missing keys).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-per-hour

# Conflicts:
#	tests/json_rpc_e2e.rs
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.

🧹 Nitpick comments (1)
app/test/e2e/specs/settings-advanced-config.spec.ts (1)

173-175: ⚡ Quick win

Fail fast when the target input selector is missing.

setReactInput silently no-ops when a selector stops matching, which delays root-cause discovery until a later timeout.

Suggested patch
-          if (!el) return;
+          if (!el) {
+            throw new Error(`setReactInput: selector not found: ${sel}`);
+          }
🤖 Prompt for 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.

In `@app/test/e2e/specs/settings-advanced-config.spec.ts` around lines 173 - 175,
The setReactInput helper currently silently returns when the target element is
missing; change the behavior to fail fast by throwing a clear error when the
selector does not match. In the setReactInput function (the block that queries
document.querySelector<HTML...>(sel) and currently does "if (!el) return;"),
replace the silent return with throwing an Error that includes the selector
string (sel) and context (e.g., "setReactInput: element not found for selector")
so tests immediately fail and show the missing selector.
🤖 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.

Nitpick comments:
In `@app/test/e2e/specs/settings-advanced-config.spec.ts`:
- Around line 173-175: The setReactInput helper currently silently returns when
the target element is missing; change the behavior to fail fast by throwing a
clear error when the selector does not match. In the setReactInput function (the
block that queries document.querySelector<HTML...>(sel) and currently does "if
(!el) return;"), replace the silent return with throwing an Error that includes
the selector string (sel) and context (e.g., "setReactInput: element not found
for selector") so tests immediately fail and show the missing selector.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 74396ec6-6b2d-4c40-b94a-46c8c599b608

📥 Commits

Reviewing files that changed from the base of the PR and between 99886da and 88054e5.

📒 Files selected for processing (21)
  • app/src/components/settings/panels/AutonomyPanel.tsx
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/bn-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/en-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/fr-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/it-5.ts
  • app/src/lib/i18n/chunks/ko-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts
  • app/src/lib/i18n/en.ts
  • app/src/utils/tauriCommands/config.ts
  • app/test/e2e/specs/settings-advanced-config.spec.ts
  • src/openhuman/config/ops.rs
  • src/openhuman/config/ops_tests.rs
  • src/openhuman/config/schemas.rs
💤 Files with no reviewable changes (3)
  • src/openhuman/config/schemas.rs
  • src/openhuman/config/ops_tests.rs
  • src/openhuman/config/ops.rs
✅ Files skipped from review due to trivial changes (7)
  • app/src/lib/i18n/chunks/ko-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/es-5.ts

@senamakel senamakel merged commit 48548a2 into tinyhumansai:main May 23, 2026
29 checks passed
senamakel added a commit to YOMXXX/openhuman that referenced this pull request May 23, 2026
…sai#2500 landed

PR tinyhumansai#2500 merged into main introduced an `AutonomyPanel` plus matching
`update_autonomy_settings` RPC, `AutonomySettingsPatch` type, and
`apply_autonomy_settings` ops that overlap with this PR's
`ActionBudgetPanel`. The post-merge tree had:

- two `openhumanUpdateAutonomySettings` TS functions (TS2323),
- two `AutonomySettingsPatch` structs and two `apply_autonomy_settings`
  / `load_and_apply_autonomy_settings` fns in core (E0428/E0119),
- two `AutonomySettingsUpdate` deserialize structs, two schema arms,
  two registered controllers, and two `handle_update_autonomy_settings`
  handlers in `config/schemas.rs`.

Keep main's versions (they add `max_actions_per_hour` range validation
and ship a sibling `get_autonomy_settings` RPC) and drop the PR's
duplicates. Both UI panels (`AutonomyPanel`, `ActionBudgetPanel`) now
share the same backend.

Note: `AutonomyPanel` and `ActionBudgetPanel` still both render in
DeveloperOptions for the same setting — flagging for human decision
in a follow-up PR comment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants