Commit Graph
465 Commits
Author SHA1 Message Date
df01f083e1 Fix/vault sync timeout 2230
## Summary

- `vault_sync` RPC now returns immediately with `{ status: "started" }` instead of blocking the HTTP connection for up to 50+ seconds
- New `vault_sync_status` RPC endpoint lets the frontend poll for live progress (scanned / ingested / total)
- File ingestion is parallelised with `buffer_unordered(4)` — reduces sync time ~4× for large directories (100 files: ~50s → ~12s)
- `VaultPanel` shows a live `Syncing… N/M` counter in the Sync button during background sync
- Duplicate concurrent syncs on the same vault are rejected with a clear error

## Problem

On macOS Apple Silicon, syncing `~/Documents` (100+ files) reliably timed out with:

```
Core RPC openhuman.vault_sync timed out after 30000ms
```

Root causes:
1. `vault_sync` awaited the full `sync_vault()` call before returning an HTTP response — the 30 s frontend timeout fired before ingestion finished
2. Files were ingested sequentially; each cloud embedding API call adds ~500 ms → 100 files = 50 s minimum

## Solution

**Non-blocking dispatch** (ops.rs): `vault_sync` registers the sync in a global `parking_lot::RwLock` state map, spawns a `tokio::spawn` background task, and returns `{ status: "started" }` in < 1 ms. The background task writes live progress counters into the state map after each batch.

**Progress polling** (ops.rs + `schemas.rs`): New `openhuman.vault_sync_status` controller reads the in-memory state and returns a `VaultSyncState` struct (status, scanned, ingested, total, duration_ms, errors).

**Concurrent ingestion** (`sync.rs`): Two-phase approach — sequential directory walk with mtime fast-path dedup, then `futures::stream::iter().buffer_unordered(4)` for the embedding API calls. Concurrency of 4 was chosen to stay within typical API rate limits while giving ~4× throughput improvement.

**Polling UI** (VaultPanel.tsx): Replaces the old `await openhumanVaultSync()` blocking call with a start → poll loop. Timer refs are cleaned up on component unmount. Button label shows `Syncing… N/M` once total is known.

**Tradeoff**: Background state lives in process memory (not persisted). A crash during sync results in an `Idle` status on next query — acceptable since the user can simply retry.

## Submission Checklist

- [x] Tests added or updated (happy path + at least one failure / edge case) — `VaultPanel.test.tsx` updated for two-step async flow (start + poll-to-completion, failed-files branch, error-on-start branch); vault.test.ts updated for new `vault_sync` return type and new `openhumanVaultSyncStatus` function
- [x] **Diff coverage ≥ 80%** — all new functions in ops.rs, `state.rs`, `schemas.rs`, `vault.ts`, VaultPanel.tsx are covered by updated tests; `pnpm test:coverage` passes locally
- [x] Coverage matrix updated — N/A: vault sync is an existing feature row; behaviour change only (timeout fix), no new feature row needed
- [x] All affected feature IDs from the matrix are listed under `## Related`
- [x] No new external network dependencies introduced — mock backend used for all tests
- [x] Manual smoke checklist updated — N/A: vault sync already has a smoke entry; no new surface added
- [x] Linked issue closed via `Closes #2230`

## Impact

- **Desktop only** (macOS / Linux / Windows) — Tauri + Rust core change
- **Performance**: sync of 100-file directories drops from timeout (>30 s) to ~12 s background
- **Security**: no new surfaces; background task uses existing `Config` clone, no additional file permissions
- **Migration**: no schema or API changes; `vault_sync_status` is additive, old clients that ignore it still work
- **Compatibility**: `vault_sync` response shape changes from `VaultSyncReport` → `{ status, vault_id }` — frontend updated in the same PR

## Related

- Closes #2230
- Follow-up: consider persisting `VaultSyncState` to SQLite so a crash-restart can surface the last-known status

---

## AI Authored PR Metadata

### Linear Issue
- Key: N/A
- URL: N/A

### Commit & Branch
- Branch: `fix/vault-sync-timeout-2230`
- Commit SHA: `47a21be2457dc348b5be37718a62662ae4a7ee2d`

### Validation Run
- [x] `pnpm --filter openhuman-app format:check` — passed (Prettier + cargo fmt auto-fixes applied in `chore: apply auto-fixes` commit)
- [x] `pnpm typecheck` — passed (0 errors)
- [x] Focused tests: `pnpm debug unit VaultPanel`  · `pnpm debug unit tauriCommands/vault` 
- [x] Rust fmt/check: `GGML_NATIVE=OFF cargo check --manifest-path Cargo.toml` — passed (0 errors, 4 pre-existing warnings in unrelated modules)
- [x] Tauri fmt/check: **BLOCKED** (see below)

### Validation Blocked
- `command:` `pnpm rust:check` (Tauri shell `cargo check --manifest-path app/src-tauri/Cargo.toml`)
- `error:` `cef-dll-sys` build script fails — CMake cannot find Ninja (`CMAKE_MAKE_PROGRAM` not set). Pre-existing environment issue; not caused by this PR (no Tauri shell files changed).
- `impact:` Low — this PR touches only vault (core crate) and src (React); zero changes to src-tauri

### Behavior Changes
- Intended behavior change: `vault_sync` RPC returns immediately instead of blocking; callers must poll `vault_sync_status` to detect completion
- User-visible effect: Sync button shows live `Syncing… N/M` progress and no longer freezes / times out on large directories

### Parity Contract
- Legacy behavior preserved: sync logic (walk, hash dedup, doc_ingest, ledger writes, deletions) is unchanged in semantics; only execution model changed (background task + concurrency)
- Guard/fallback/dispatch parity: `vault_sync_status` registered in all.rs alongside existing vault controllers; no dispatch branches added to `cli.rs` or `jsonrpc.rs`

### Duplicate / Superseded PR Handling
- Duplicate PR(s): none
- Canonical PR: this PR
- Resolution: N/A

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Vault sync runs in background with live progress (ingested/total), duration, skipped/failed counts, and richer error details; sync button shows progress and final toasts report results.
  * Added a live status endpoint so the UI can poll ongoing syncs.

* **Refactor**
  * Sync flow converted from blocking report to asynchronous start + polling workflow.

* **Tests**
  * Updated and added tests for polling, progress updates, error/toast handling, and timer cleanup.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2243?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: MootSeeker <mootseeker98@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-20 14:46:20 -07:00
Mega MindandGitHub cc00f91574 feat(local-ai): add editable Ollama server URL with connection test (#2210) 2026-05-21 00:36:11 +05:30
cc498d1727 fix(onboarding): capture completeAndExit rejection in Sentry (#2081) (#2327)
Co-authored-by: sanil-23 <sanil@alphahuman.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 18:44:17 +05:30
Yuhao ChenandGitHub 81dc8d7ebe fix(app): stabilize daemon lifecycle setup (#2177) 2026-05-19 21:16:49 -07:00
9376ffc19f fix(onboarding): raise snapshot timeout + staged still-working UI (#2156) (#2179)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 21:08:59 -07:00
74c91ba4d2 fix(core): port-bind fallback + retry when 7788 is busy (#1613) (#2116)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 21:02:08 -07:00
9c14c13752 fix(oauth): surface backend outage instead of opening browser to 504 (#1985) (#2147)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 20:32:22 -07:00
oxoxDevandGitHub 1ae31ba14c fix(core-rpc): demote timeout unhandled-rejections + classify in client (#REACT-15+) (#2196) 2026-05-19 20:22:54 -07:00
ee34387f2e feat(providers): add OrcaRouter as built-in cloud provider (#2187)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 20:19:28 -07:00
ad61b4cec7 fix(ui): BottomTabBar no longer blocks Settings SaveBar clicks (#2185)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 20:01:30 -07:00
obchainandGitHub 7cbe82de52 fix(composio): collect Dynamics 365 org name via required-fields registry (#2127) (#2181) 2026-05-19 20:00:50 -07:00
CodeGhost21andGitHub 14ee688ff3 test(settings): backfill unit tests for team / billing / notifications panels (#1870) (#2089) 2026-05-19 19:50:33 -07:00
82df98f419 fix(i18n): localize settings developer menu (#2250)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 19:49:22 -07:00
f7d1f9b42d feat(human): show subagent companion mascots (#2099)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 19:43:32 -07:00
544a68239d Prevent duplicate chat sends while pending (#2071)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 19:42:20 -07:00
Aqil AzizandGitHub d28c054c29 fix(auth): point welcome legal links to docs (#2253) 2026-05-19 16:51:13 -07:00
Navneet SinghandGitHub a03c1c4dfa feat(i18n): add Korean locale (#2241) 2026-05-19 16:50:09 -07:00
Yuvraj Singh SisodiyaandGitHub e9205225b8 feat(app): desktop companion UI — Tauri bridge, overlay, settings (#1909) (#2246) 2026-05-19 16:49:57 -07:00
Aqil AzizandGitHub 8dbec71b80 fix(voice): allow local provider selection before install (#2257) 2026-05-19 16:49:23 -07:00
KyleandGitHub a1c74f1539 i18n: replace hardcoded Settings UI strings with t() calls (fixes #2225) (#2258) 2026-05-19 16:48:54 -07:00
oxoxDevandGitHub 272a6b063c fix(core,app): authenticate /events/webhooks SSE with per-launch core RPC bearer (#1922) (#2114) 2026-05-19 16:43:53 -07:00
d59963373f fix(billing): suppress budget banner when all chat workloads route to a user-supplied provider (#2040, #2041) (#2053)
Co-authored-by: 李冠辰 <liguanchen@xiaomi.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 16:13:18 -07:00
obchainandGitHub 6a83409a4c feat(migration): OpenClaw import surface + unblock unified-core Apply (#2087) 2026-05-19 14:43:31 -07:00
b6552ea1c7 feat(channels): surface Lark/Feishu and DingTalk in the Settings UI (#2048) (#2083)
Co-authored-by: 李冠辰 <liguanchen@xiaomi.com>
2026-05-19 14:41:52 -07:00
669b77d764 fix(channels): surface channel error status in selector (#2169)
Co-authored-by: honor2030 <11687299+honor2030@users.noreply.github.com>
2026-05-19 14:36:20 -07:00
b2ecdba4a8 test(cron): add stable job row selectors (#2062)
Co-authored-by: honor2030 <9779460+honor2030@users.noreply.github.com>
2026-05-19 14:34:54 -07:00
62a9633c2d fix(i18n): translate contextGathering errorDesc across 8 remaining locales (#1917) (#2057)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 14:20:22 -07:00
obchainandGitHub d9bd9901f4 fix(meet): guard orchestrator handoff against transcript prompt injection (#2056) 2026-05-19 14:07:49 -07:00
828ae4d4f1 fix: ignore core state commits after unmount (#2021)
Co-authored-by: LawyerLyu <georgelyutwitter@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-19 12:48:10 -07:00
f1257c59f9 fix(i18n): translate zh-CN contextGathering errorDesc (#1917) (#2042)
Co-authored-by: 李冠辰 <liguanchen@xiaomi.com>
Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
2026-05-19 12:18:12 -07:00
049d1ea7ab harden: validate webview event payloads (#2036)
Co-authored-by: LawyerLyu <georgelyutwitter@gmail.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 21:26:01 +05:30
afe1147422 fix(onboarding): clarify continue to chat fallback (#2173)
Co-authored-by: Ajay Kumar Reddy Nelavetla <ajay@Ajays-MacBook-Air.local>
2026-05-19 21:12:00 +05:30
1f98614869 feat(inference): gate local Ollama models by memory-layer context-window minimum (#2122)
Co-authored-by: Cyrus Gray <cyrus@tinyhumans.ai>
2026-05-19 19:40:06 +05:30
3aa2984e3f feat(billing): drop rate-limit UI, surface cycle usage insights (#2027)
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-19 17:25:02 +05:30
Mega MindandGitHub 764eda65ea fix(core-state): add backoff after bootstrap budget exhaustion (#2194)
Adds 10s poll backoff once the 5-retry bootstrap budget is exhausted, preventing tight retry loops during slow startup. Reverts to 2s on recovery. Builds on #2167 (debug message helper).

- BACKOFF_POLL_MS = 10_000: scheduleNext uses longer delay after bootstrap exhaustion, 2s otherwise
- coreStatePollFailureWarningMessage messages updated to say 'bootstrap poll failed' and 'budget exhausted; continuing with backoff'
- Tests: backoff timing (fake timers), recovery revert, impossible-counter negative assertion, debug message describe block properly separated

Closes #2158
2026-05-19 15:41:39 +05:30
91a5bb9db9 fix(core-state): clarify retry failure logs (#2167)
Adds coreStatePollFailureDebugMessage helper to eliminate impossible attempt counters (e.g. 11/5) from debug logs, distinguishing bootstrap retries from post-bootstrap background polling.

Fixes #2158

Co-authored-by: okbexx <okbexx@users.noreply.github.com>
2026-05-19 15:36:32 +05:30
Mega MindandGitHub f285b80de0 fix(ai-settings): filter reserved slugs in loadAISettings and saveAISettings (#2184) 2026-05-19 14:16:20 +05:30
81a0faef9d feat(memory): #1574 Stage 2 — per-(row,model) embedding storage live (cutover + migration + re-embed backfill + switch UX) (#2153)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 01:31:11 -07:00
Steven EnamakelandGitHub 16b35af570 feat(ai-panel): per-workload temperature + endpoint URL UX for local runtimes (#2165) 2026-05-18 22:04:54 -07:00
Mega MindandGitHub a719d781d1 feat(ai-panel): add chat workload and cloud model picker with slug-based lookup fix (#2152) 2026-05-18 15:04:57 -07:00
Mega MindandGitHub 4c2a04b6e4 fix(i18n): fix ~80 broken/placeholder strings in en.ts (#2144) 2026-05-18 14:52:46 -07:00
Steven EnamakelandGitHub 0b053c55f5 feat(mascot): locale-aware voice + multilingual LLM replies (#2115) 2026-05-18 07:28:14 -07:00
Steven EnamakelandGitHub b709941e2e refactor(staging): dark mode polish, theme toggle, i18n restore + debug probe (#2095) 2026-05-18 07:06:34 -07:00
Steven EnamakelandGitHub d5cef57cfd feat(i18n): translate ~3,900 strings across 9 locales + add Italian (#2070) 2026-05-18 03:32:14 -07:00
CodeGhost21andGitHub 1d3563bf49 test(intelligence): backfill memory-tab unit tests (#1870) (#2064) 2026-05-18 15:59:40 +05:30
Steven EnamakelandGitHub 0f616e4a62 fix(accounts): don't persist activeAccountId across renderer reloads (#2044) (#2047) 2026-05-17 23:07:43 -07:00
Steven EnamakelandGitHub 0ad72dccfa feat(theme): dark mode + UI primitives standardization (#2046) 2026-05-17 23:01:27 -07:00
db087a7d3e fix: validate session token update events (#2018)
Co-authored-by: LawyerLyu <georgelyutwitter@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-17 18:46:15 -07:00
rohanandGitHub 2ec4e954eb feat(ui): restore cross-provider RespondQueuePanel and purge legacy Mnemonic page (#2000) 2026-05-17 18:12:35 -07:00
Steven EnamakelandGitHub db99318ea4 feat(discord): ingest webview transcripts into memory (#1993) 2026-05-17 18:08:08 -07:00