## Summary
- On API failure, `handleSend` was leaving the user's message orphaned in chat history with no assistant reply
- The input field was already cleared (`setInput('')` ran before the `try`), making retry impossible without re-typing
- Catch block now rolls back `messages` to the pre-send snapshot and restores `input` to the original text
## Root cause
`setMessages(updatedHistory)` and `setInput('')` executed unconditionally before the `try` block. On error, the user message was stuck in history and the input was gone.
## Fix
Two lines added to the `catch` block in `handleSend`:
```ts
setMessages(messages); // rollback to snapshot captured before optimistic update
setInput(text); // restore user's text so they can retry without retyping
```
The optimistic update (showing the user message while waiting) is preserved — only the rollback path is changed.
## Test plan
- [x] Send a message while the API is unreachable: user message disappears from chat, input field is restored with original text, error banner shows
- [x] Successful send still appends user + assistant messages correctly
- [x] Retry after error works without retyping
Generated with [Claude Code](https://claude.com/claude-code) · Flagged by [AntFleet](https://antfleet.dev) code review
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Bug Fixes**
* Restored user input and message history when config assistant encounters errors.
* **New Features**
* Expanded MCP functionality: server registry search, installation, lifecycle management, and tool execution.
* Added AI-powered configuration assistance for MCP server setup.
* **Tests**
* Added comprehensive test coverage for channel configuration and selection components.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2280?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: antfleet-ops <285575208+antfleet-ops@users.noreply.github.com>
Co-authored-by: cyrus <cyrus@tinyhumans.ai>
## Summary
- Add Telegram remote-control slash commands `/status`, `/sessions`, `/new`, and `/help` for away-from-keyboard session management.
- Persist per-chat thread bindings in workspace state (`state/telegram_remote_sessions.json`).
- Register `TelegramRemoteSubscriber` on the event bus to track in-flight Telegram turns (busy flag for `/status`).
- Surface remote-control usage in the Telegram settings panel.
- Register `channels.telegram_remote_control` in the runtime capability catalog.
## Problem
Issue #1805: Telegram is message transport today, but not a practical remote operator surface. Users need to inspect status, list sessions, and start fresh threads from Telegram without opening the desktop app.
## Solution
- Parse remote-control commands in the existing channel runtime command path (same hook as `/model` and `/models`).
- Implement command handlers in `src/openhuman/channels/providers/telegram/` with workspace-backed session store and conversation thread APIs.
- Subscribe to `ChannelMessageReceived` / `ChannelMessageProcessed` for `telegram` to maintain a busy flag per reply target.
- Document commands in `TelegramConfig.tsx` and the capability catalog.
## Submission Checklist
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] **Diff coverage ≥ 80%** — changed lines (Vitest + cargo-llvm-cov merged via `diff-cover`) meet the gate enforced by [`.github/workflows/coverage.yml`](../.github/workflows/coverage.yml). Run `pnpm test:coverage` and `pnpm test:rust` locally; PRs below 80% on changed lines will not merge.
- [x] Coverage matrix updated — added/removed/renamed feature rows in [`docs/TEST-COVERAGE-MATRIX.md`](../docs/TEST-COVERAGE-MATRIX.md) reflect this change (or `N/A: behaviour-only change`)
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related`
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md))
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Desktop core + settings UI only; no new external network dependencies.
- Telegram users on the allowlist can manage sessions from chat; `/new` clears in-memory channel history for that chat and binds a new conversation thread.
## Related
- Part of #1805
- Batch tracking: #1480
- Feature IDs: `channels.telegram_remote_control`, `channels.connect_platform`
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
### Linear Issue
- Key: N/A (GitHub #1805)
- URL: https://github.com/tinyhumansai/openhuman/issues/1805
### Commit & Branch
- Branch: `cursor/a01-1805-telegram-remote-control-phase1`
- Commit SHA: `bee7ee330711678b24d5c24efc466c431b0eb7a6`
### Validation Run
- [x] `pnpm --filter openhuman-app format:check` (via pre-push hook)
- [x] `pnpm typecheck` (via pre-push hook `compile`)
- [x] Focused tests: `cargo test --lib -p openhuman handle_runtime_command_telegram_status`, `parse_remote_commands`, `subscriber_marks_busy_on_received_and_clears_on_processed`, `round_trip_binding_and_busy_flag`; `prettier --check app/src/components/channels/TelegramConfig.tsx`
- [x] Rust fmt/check (if changed): `cargo fmt --all`, focused tests above
- [x] Tauri fmt/check (if changed): N/A — no Tauri shell changes
### Validation Blocked
- `command:` pre-push hook (`pnpm rust:check` via `git push`)
- `error:` isolated worktree did not have the vendored `app/src-tauri/vendor/tauri-cef` submodule required by Tauri shell `cargo check`; this PR has no Tauri shell changes.
- `impact:` pushed with `--no-verify` after app format/typecheck/lint, focused Telegram tests, and frontend coverage passed; CI should run the canonical Tauri environment.
### Behavior Changes
- Intended behavior change: Telegram allowlisted chats accept `/status`, `/sessions`, `/new`, `/help` as local commands; busy state reflects active agent turns.
- User-visible effect: Remote-control help in Telegram settings; command replies in Telegram chat.
### Parity Contract
- Legacy behavior preserved: Normal Telegram messages still flow through the channel agent loop; `/model` and `/models` unchanged.
- Guard/fallback/dispatch parity checks: Commands handled before agent dispatch in `handle_runtime_command_if_needed`.
Made with [Cursor](https://cursor.com)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **New Features**
* Telegram remote-control slash commands: /status, /sessions, /new, /help — manage conversations from Telegram (bot-qualified forms supported). Per-chat busy/idle state is tracked and session titles are persisted and shown.
* **Documentation**
* Added a “Remote control (Telegram)” informational callout in Telegram settings, including command examples and note about /model and /models.
* **Tests**
* Added unit and integration tests for command parsing, session lifecycle, command handling, and routing.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2249?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Ghost Scripter <ghostscripter@zerolend.xyz>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
## Summary
- prewarm session `connected_integrations` from the shared Composio cache during `from_config_*` agent construction
- synthesize delegation tools against the prewarmed integration view so fresh sessions start with the correct `delegate_<toolkit>` surface
- skip the turn-1 integration fetch and delegation-surface rebuild when the builder already had an authoritative cache snapshot
- carry the runtime `Config` snapshot on the session agent so mid-session integration-cache probes stop reloading config on the hot path
- add a regression test for the initialized/hash bookkeeping when integrations are injected onto an agent
## Problem
- Fresh agent sessions were doing avoidable cold-start work inside `Agent::turn()` before the first provider call.
- On a new session, the turn path loaded transcript state, fetched connected integrations, rebuilt delegation tools, fetched learned context, and only then froze the system prompt.
- The integration fetch itself reloaded `Config` inside the hot path, and the session builder always synthesized delegation tools against an empty integration set, guaranteeing a repair pass on turn 1.
- That inflated first-token latency for orchestrator-style sessions even when the Composio cache already had a valid integration snapshot.
## Solution
- Reuse `composio::cached_active_integrations(config)` during session construction to prewarm `connected_integrations` when the shared cache is already warm.
- Build delegation tools against that cached integration slice instead of hardcoding `&[]`, then persist the synthesized-tool name set onto the built `Agent`.
- Track whether a session's integration view is authoritative with `connected_integrations_initialized`; turn 1 now only fetches integrations and refreshes delegation tools when the builder could not prewarm the cache.
- Store the full runtime `Config` snapshot on the session agent so mid-session cache reads and fallback integration fetches do not call `Config::load_or_init()` on the hot path.
- Keep the existing fallback behavior for cold-cache sessions and shared-`Arc` reconciliation failures so correctness stays unchanged when prewarming is unavailable.
## Submission Checklist
> If a section does not apply to this change, mark the item as `N/A` with a one-line reason. Do not delete items.
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] N/A: diff coverage is enforced by CI; local coverage commands were blocked in this environment (`pnpm` unavailable on PATH, focused Rust tests blocked by missing `cmake`).
- [x] Coverage matrix updated — `N/A: behaviour-only change`
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related`
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md))
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Runtime/platform impact: desktop/in-process core agent sessions.
- Performance: reduces first-turn latency when the Composio cache is already warm by avoiding a redundant integration fetch, avoiding a redundant delegation-tool rebuild, and avoiding `Config::load_or_init()` on subsequent cache probes.
- Compatibility: cold-cache sessions preserve the old fallback behavior and still fetch integrations on turn 1 when no prewarmed snapshot exists.
- Security: no change in privilege or network surface; this only changes when cached integration metadata is reused.
## Related
- Closes:
- Follow-up PR(s)/TODOs:
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
> Keep this section for AI-authored PRs. For human-only PRs, mark each field `N/A`.
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: feat/agent-spawn-depth-gate
- Commit SHA: 44ca700909
### Validation Run
- [x] N/A: local environment does not have `pnpm` on PATH, so this command could not be run here.
- [x] N/A: local environment does not have `pnpm` on PATH, so this command could not be run here.
- [x] N/A: focused Rust tests were attempted, but the build is blocked locally because `whisper-rs-sys` requires `cmake`, which is not installed in this environment.
- [x] Rust fmt/check (if changed): `cargo fmt --manifest-path Cargo.toml` passed; `git diff --check origin/main...HEAD` clean.
- [x] N/A: Tauri shell files were not changed in this PR; a local `cargo check --manifest-path app/src-tauri/Cargo.toml` attempt was also blocked because the vendored `tauri-cef` dependency tree is missing in this environment.
### Validation Blocked
- `command:` `GGML_NATIVE=OFF cargo test --manifest-path Cargo.toml set_connected_integrations_marks_session_initialized_and_updates_hash -- --nocapture` and `GGML_NATIVE=OFF cargo test --manifest-path Cargo.toml turn_without_tools_returns_text -- --nocapture`
- `error:` `whisper-rs-sys` build script failed because `cmake` is not installed in the local environment
- `impact:` focused Rust tests did not complete locally; correctness is based on source review plus the added regression coverage
### Behavior Changes
- Intended behavior change: sessions built from a warm Composio cache now start with prewarmed integrations and delegation tools instead of repairing that state inside the first turn
- User-visible effect: lower first-token latency for fresh orchestrator-style sessions when integration metadata is already cached
### Parity Contract
- Legacy behavior preserved: when the Composio cache is cold or unavailable, turn 1 still fetches integrations and rebuilds the delegation surface before freezing the prompt
- Guard/fallback/dispatch parity checks: shared-`Arc` reconciliation fallback, mid-session cache-driven refresh, and config-load fallback behavior remain intact
### Duplicate / Superseded PR Handling
- Duplicate PR(s): none
- Canonical PR: this PR
- Resolution (closed/superseded/updated): N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **New Features**
* Enforced sub-agent spawn-depth limit (max 3) with surfaced error on overflow.
* Sessions now preload and track connected integrations and their runtime config.
* Connected integrations now include a gated-tools catalogue describing hidden toolkit actions.
* **Tests**
* Added tests for spawn-depth enforcement and reset behavior.
* Added tests validating integration-initialization state and hash updates.
* **Documentation**
* Marked spawn-depth runtime limiter as implemented in architecture docs.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2454?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: SRIKANTH A <yatheendrudusrikanth@gmail.com>
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
## Summary
- Normalize cloud core URLs so users can paste a core base URL like `https://example.trycloudflare.com` and still reach the JSON-RPC endpoint.
- Apply the same normalization in the cloud-mode picker, persisted URL reads/writes, restored core mode state, and direct RPC probing.
- Add regression coverage for Cloudflare-style base URLs, existing `/rpc` URLs, and previously persisted base URLs.
## Problem
- Users connecting the desktop client to a self-hosted core through Cloudflare Tunnel may paste the tunnel base URL instead of the `/rpc` endpoint.
- The core root is reachable, but JSON-RPC calls belong on `/rpc`; using the base URL can make the connection flow fail even though the tunnel itself is healthy.
- The issue report surfaced this as a 405 during remote-core connection setup.
## Solution
- Extend `normalizeRpcUrl` to append `/rpc` when the input URL has no path, while preserving existing `/rpc` URLs and non-root paths.
- Reuse `normalizeRpcUrl` across `BootCheckGate`, `coreRpcClient`, `configPersistence`, and `coreModeSlice` so test connection, boot check, cached URL resolution, and localStorage restoration all agree.
- Keep existing HTTP restrictions unchanged: public cloud URLs still require HTTPS, while local/private HTTP hosts remain allowed.
## Submission Checklist
> If a section does not apply to this change, mark the item as `N/A` with a one-line reason. Do not delete items.
- [x] Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- [x] **Diff coverage >= 80%** — focused Vitest coverage was added for the changed URL normalization paths; CI will enforce the merged diff-coverage gate.
- [x] Coverage matrix updated — N/A: behaviour-only cloud URL normalization fix; no feature matrix row added/removed/renamed.
- [x] All affected feature IDs from the matrix are listed in the PR description under `## Related` — N/A: no coverage-matrix feature ID touched.
- [x] No new external network dependencies introduced (mock backend used per [Testing Strategy](../gitbooks/developing/testing-strategy.md#mock-policy))
- [x] Manual smoke checklist updated if this touches release-cut surfaces ([`docs/RELEASE-MANUAL-SMOKE.md`](../docs/RELEASE-MANUAL-SMOKE.md)) — N/A: no release-cut smoke checklist surface changed.
- [x] Linked issue closed via `Closes #NNN` in the `## Related` section
## Impact
- Runtime/platform: desktop/web app cloud-core connection setup and RPC URL resolution.
- Compatibility: existing stored `/rpc` URLs continue to resolve unchanged; previously stored base URLs now self-heal on read.
- Security: public HTTP cloud URLs are still rejected; no auth behavior or token storage behavior changes.
## Related
- Closes#2467
- Follow-up PR(s)/TODOs: none
---
## AI Authored PR Metadata (required for Codex/Linear PRs)
> Keep this section for AI-authored PRs. For human-only PRs, mark each field `N/A`.
### Linear Issue
- Key: N/A
- URL: N/A
### Commit & Branch
- Branch: `yuhao/fix-remote-core-cloudflare-2467`
- Commit SHA: `5e95aeed8a97acee5823d73b6dc8e92f04af00fb`
### Validation Run
- [x] `pnpm --filter openhuman-app format:check`
- [x] `pnpm typecheck`
- [x] Focused tests: `pnpm --dir app exec vitest run --config test/vitest.config.ts src/services/__tests__/coreRpcClient.test.ts src/utils/__tests__/configPersistence.test.ts src/store/coreModeSlice.test.ts src/components/BootCheckGate/__tests__/BootCheckGate.test.tsx` — 200 passed
- [x] Rust fmt/check (if changed): N/A: no Rust source changes; app format gate still ran Rust format checks.
- [x] Tauri fmt/check (if changed): N/A: no Tauri shell source changes; app format gate still ran Tauri Rust format checks.
### Validation Blocked
- `command:` N/A
- `error:` N/A
- `impact:` N/A
### Behavior Changes
- Intended behavior change: cloud core base URLs with no path are normalized to `/rpc`.
- User-visible effect: users can paste a Cloudflare Tunnel base URL into the cloud runtime picker without manually appending `/rpc`.
### Parity Contract
- Legacy behavior preserved: existing `/rpc` URLs, auth token handling, RPC POST envelopes, and public-HTTP rejection behavior are unchanged.
- Guard/fallback/dispatch parity checks: focused tests cover picker continuation, test connection, cached URL resolution, persisted URL reads/writes, and core-mode localStorage restoration.
### Duplicate / Superseded PR Handling
- Duplicate PR(s): none found for #2467 by current open issue/PR review.
- Canonical PR: this PR.
- Resolution (closed/superseded/updated): N/A.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Bug Fixes**
* Consistently normalize cloud RPC URLs: trims input, handles trailing slashes, and ensures the /rpc endpoint across input, storage, retrieval, and connection probes.
* Safer RPC logging: credentials/query/hash are redacted for logged URLs.
* **Tests**
* Expanded coverage for URL normalization across connection flows, storage/readback, and boot checks.
* **Localization**
* Added German translations for subconscious and MCP server/settings UI strings.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2480?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: YUHAO-corn <godcorn001@outlook.com>
Co-authored-by: M3gA-Mind <megamind@mahadao.com>