CodeGhost21andGitHub a8664f066f test(coverage): batch 1–4 — Rust unit tests toward 80% for critical modules (#530) (#581)
* test(coverage): phase 1 — webhooks/types, workspace/ops, webhooks/schemas

Lines: webhooks/types 0% → 100%; workspace/ops 0% → 96.98%;
webhooks/schemas 35.40% → 79.18%.

- webhooks/types.rs: serde round-trip tests for WebhookRequest /
  WebhookResponseData / TunnelRegistration (including the
  default_webhook_target_kind fallback) / WebhookActivityEntry /
  WebhookDebugLogEntry / the three debug result wrappers / and
  WebhookDebugEvent, exercising every `#[serde(default)]` and
  camel-case rename.
- workspace/ops.rs: ensure_workspace_file covers create / leave / force
  / write-error branches; BOOTSTRAP_FILES contract test locks in SOUL
  and IDENTITY presence; init_workspace covers fresh-install, idempotent
  second-call, and forced-overwrite paths against a temp OPENHUMAN_WORKSPACE
  (serialised via the shared TEST_ENV_LOCK).
- webhooks/schemas.rs: catalog integrity (length / namespace /
  uniqueness / schema↔handler parity), per-function required-field
  assertions for all 11 RPC methods plus the unknown fallback, and
  deserialize_params / json_output / to_json coverage.

Also fixes a pre-existing test bug in composio/ops.rs discovered while
running llvm-cov: fetch_connected_integrations_via_mock_aggregates_tools
was not mocking /composio/toolkits, so list_toolkits failed and the
expected aggregation never happened. Adds the missing route so the
test now observes the 2-integration result it asserts.

* test(coverage): phase 2 — webhooks/bus, webhooks/ops

Lines: webhooks/bus 0% → 100%; webhooks/ops 14.34% → 97.96%.

- webhooks/bus.rs: base64_encode / error_body helpers; Default vs new
  equivalence; EventHandler name and domain filter; handle() on a
  non-webhook variant (early return) and on a WebhookIncomingRequest
  without a registered socket manager (graceful fallthrough).
- webhooks/ops.rs: require_token for missing / whitespace / valid
  stored sessions; the four stub RPC ops (list_registrations, list_logs
  including ignored-limit, clear_logs, register/unregister_echo) lock
  in their current payload + log shape; build_echo_response decodes
  back to the expected echo body and sets the echo-target header;
  trimmed-input validation for create_tunnel (empty/whitespace name)
  and the id-bearing ops (get/update/delete); and full mock-backend
  round-trips for list_tunnels, create_tunnel (trim + drop-whitespace
  description), get_tunnel, update_tunnel, delete_tunnel, and
  get_bandwidth, plus a guard asserting authed HTTP calls fail fast
  without a session token.

* test(coverage): phase 3 — voice/postprocess, voice/text_input

Lines: voice/postprocess 58.94% → 92.06%; voice/text_input 18.83% → 51.18%.

voice/postprocess.rs
- Convert existing short-circuit tests to #[tokio::test] so the async
  function is awaited directly instead of via a freshly-constructed
  runtime per case.
- Add `enabled_but_llm_not_ready_returns_raw_text` for the "cleanup is
  on but the local LLM hasn't reached ready/degraded yet" branch.
- Add five LLM-ready tests that spin up a mock Ollama behind the
  OPENHUMAN_OLLAMA_BASE_URL override: happy-path cleanup + trim,
  whitespace-only response fallback, HTTP 500 fallback, conversation
  context embedded in the prompt, and whitespace-only context
  ignored. Assertions are permissive about "LLM called → cleaned" vs
  "LLM short-circuited → raw" because ~30 sibling tests touch the
  shared `local_ai::global()` singleton without LOCAL_AI_TEST_MUTEX
  and can race our `state = "ready"` setup. Either branch is
  documented as acceptable; the function must always return a
  deterministic String and never panic. Full end-to-end correctness
  of the cleanup output is pinned by the deterministic short-circuit
  tests above.

voice/text_input.rs
- Add `\\t` / `\\n`-only input case and verify the OpenWhispr timing
  constants (PASTE_DELAY 120ms, CLIPBOARD_RESTORE_DELAY 450ms) so
  nobody silently shortens them and breaks paste reliability.
- macOS: escape_applescript_string backslash/quote/idempotence cases
  and restore_focus_to_app error path against a bogus app name.
- Ceiling note: the clipboard/enigo body of insert_text is not
  testable in a headless environment (Clipboard::new / Enigo::new
  fail without a display). Pushing past ~51% here requires
  dependency-injecting those traits — a production refactor, not a
  test addition.

* test(coverage): batch 4.1 — skills/bus, text_input/{types,ops}

Lines: skills/bus 0% → 100%; text_input/types 0% → 100%;
text_input/ops 0% → 57.67% (accessibility-gated ceiling).

- skills/bus.rs: idempotent no-op for the legacy
  register_skill_cleanup_subscriber() hook.
- text_input/types.rs: FieldBounds ↔ accessibility::ElementBounds
  round-trip, ReadFieldParams default/omitted-key serde, and
  round-trips for every request/result struct (InsertText,
  ShowGhostText, DismissGhostText, AcceptGhostText).
- text_input/ops.rs: empty-text guard assertions for insert_text,
  show_ghost, and accept_ghost; dismiss_ghost idempotent-success
  contract; plus a deterministic-shape check that the accessibility
  failure path wraps the error into InsertTextResult rather than
  panicking. Anything past the guard reaches `accessibility::*`,
  which requires a live focused field on an OS display and is
  therefore not reachable in a headless unit-test environment —
  lifting the ceiling past ~58% requires dependency-injecting the
  accessibility surface, a production refactor.

* test(coverage): batch 4.2 — service/bus, migration/ops, referral/ops

Lines: service/bus 0% → 85.25%; migration/ops 0% → 89.71%;
referral/ops 0% → 94.63%.

- service/bus.rs: RestartSubscriber name and domain metadata, plus
  two handle() branches that are safe to exercise — non-restart
  event (early return) and duplicate-suppression (gate already set).
  Deliberately does NOT cover the success path of a real
  SystemRestartRequested — it spawns a tokio task that calls
  std::process::exit(0) and would terminate the test runner.
  register_restart_subscriber idempotency test confirms the
  OnceLock guard skips re-registration.
- migration/ops.rs: dry-run against an empty temp workspace returns
  the canonical "migration completed" log; missing source-workspace
  path exercises the Err-propagation branch.
- referral/ops.rs: require_token for missing / whitespace / valid
  sessions; get_stats + claim_referral guard fast-fail without a
  session; claim_referral round-trip against a mock backend
  asserting (a) the referral code is trimmed, (b) a whitespace-only
  deviceFingerprint is dropped from the outgoing body, and (c) a
  non-empty fingerprint is trimmed and forwarded.

* test(coverage): batch 4.3 — security/ops, service/{bus,ops}, update/{ops,scheduler}

Adds unit tests covering:
- security/ops: security_policy_info payload shape + default values
- service/ops: daemon_host_get/set happy path and error branches
- service/bus: fix register_restart_subscriber test to use #[tokio::test]
  so it has a runtime under `cargo llvm-cov`
- update/ops: validate_asset_name and validate_download_url edge cases,
  update_apply short-circuit guards
- update/scheduler: min-interval invariant, disabled-run short-circuit,
  tick resilience when the event bus is uninitialised

All 3583 lib tests pass under `cargo llvm-cov`. Refs #530.

* style: cargo fmt cleanup in coverage test modules

Auto-fixes from `cargo fmt` on test code added in batches 4.1–4.3.
No behavioral changes.

* test(coverage): batch 5.1 — cron/{ops,schemas}

- cron/ops.rs: 74.73% → 91.20% (+add_once_at, pause/resume, async cron_list/update/remove/runs, enabled/disabled and empty-id branches)
- cron/schemas.rs: 29.11% → 77.00% (all schemas() branches, registry helpers, read_required/read_optional_u64/type_name)

30 new deterministic tests. Refs #530.

* test(coverage): batch 5.2 — memory/{rpc_models,schemas}

- memory/rpc_models.rs: 70.91% (targets resolved_limit priority across QueryNamespace/RecallContext/RecallMemories, deny_unknown_fields enforcement, ApiError/ApiMeta/ApiEnvelope round-trips)
- memory/schemas.rs: 45.67% (all 31 controller schemas present, registry parity with handlers, parse_params success + error paths, unknown function placeholder)

19 new deterministic tests. Refs #530.

* test(coverage): batch 5.3 — socket/manager webhook router paths

- socket/manager.rs: 67.54% (adds set_webhook_router populates/overwrites paths and emit-after-disconnect guard)

3 new deterministic tests. Refs #530.

* test(coverage): batch 5.4 — config/{schemas, schema/observability}

- config/schemas.rs: 52.37% (adds required_string / optional_string / optional_bool field builder coverage, exercises deserialize_params across ModelSettings / MemorySettings / WorkspaceOnboarding / SetBrowserAllowAll / OnboardingCompleted params, pins DEFAULT_ONBOARDING_FLAG_NAME constant)
- config/schema/observability.rs: 66.67% (default-values invariant, serde defaults for optional fields, explicit analytics flag, round-trip)

16 new deterministic tests. Refs #530.

* test(coverage): batch 5.5 — local_ai/{core,gif_decision}

- local_ai/core.rs: 33.33% (pins model_artifact_path structure: models/local-ai dir, `.ollama` suffix, colon→dash normalisation for Windows-safe filenames; Arc sharing across global() calls)
- local_ai/gif_decision.rs: 44.04% (trim whitespace in parse, length/word-count boundary cases, tenor_search empty-query guard, local_ai_should_send_gif empty-message early return)

10 new deterministic tests. Refs #530.

* test(coverage): batch 5.6 — local_ai/sentiment, migration/schemas, referral/schemas

- local_ai/sentiment.rs: 68.03% (negative-confidence clamp to zero, unknown valence fallback, all documented emotion/valence labels accepted, neutral() constructor invariants, empty-message early return)
- migration/schemas.rs: 36.73% (controller registry parity, openclaw input shape, MigrateOpenClawParams defaults + round-trip, unknown function placeholder, to_json wrapping)
- referral/schemas.rs: 37.18% (controller registry parity, claim input required/optional mapping, ReferralClaimParams camelCase alias + missing-code rejection, json_output + to_json helpers)

25 new deterministic tests. Refs #530.

* test(coverage): batch 5.7 — tools/traits, local_ai/device

- tools/traits.rs: 76.77% (Tool default-method values for permission/scope/category, PermissionLevel total order + default + Display + serde round-trip, ToolCategory default + Display + snake_case serde, ToolScope variant distinctness)
- local_ai/device.rs: 63.16% (total_ram_gb truncation for sub-GB and partial-GB, detect_gpu branches for Apple-brand / ARM-on-mac / Intel-Mac, DeviceProfile serde round-trip)

17 new deterministic tests. Refs #530.

* test(coverage): address PR review — tighten assertions, fix flaky test, add env-var RAII guard

Inline review fixes:
- migration/ops.rs: migrate_openclaw_returns_error_for_missing_source_workspace now requires Err() (the underlying helper bails when the source dir doesn't exist) and asserts a non-empty error message.
- text_input/ops.rs: replace tautological `!inserted || inserted` in insert_text_surfaces_accessibility_failure_as_inserted_false with the real contract: require Ok(..) and pin `inserted`↔`error` mutual exclusion. Headless runs legitimately see inserted=false, so the assertion still holds while catching regressions in either branch.
- update/scheduler.rs: remove tick_runs_without_panicking_when_event_bus_is_uninitialised — it hit real api.github.com HTTPS and was flaky under offline CI / rate limits. Replace with a comment documenting the decision and the integration-test path for exercising tick().

Nitpick fixes:
- security/ops.rs: extend security_policy_info_matches_default_policy_values with assertions for autonomy and allowed_commands so the full default shape is pinned.
- voice/postprocess.rs: tighten ready_llm_with_whitespace_only_context_never_embeds_header from `assert_eq!(result.trim(), "raw text")` to exact equality (cleanup_transcription trims internally). The pre-existing doc comment on with_ready_llm plus the in-module block comment at lines 255-268 already document the LOCAL_AI_TEST_MUTEX contract and the deliberate non-use in permissive tests — no new docs needed.
- webhooks/ops.rs: list_tunnels_hits_webhooks_core_endpoint_and_returns_payload now asserts the inbound Authorization header equals `Bearer test-session-token`; get_tunnel_encodes_id_in_path uses an id full of reserved URL chars so the test actually verifies percent-encoding rather than just trimming.
- workspace/ops.rs: introduce a WorkspaceEnvGuard RAII helper; replace all six unsafe set_var/remove_var pairs in the init_workspace tests so OPENHUMAN_WORKSPACE is cleared on panic too. Contract is documented inline: guard requires the caller to hold ENV_LOCK.

Refs #530.

* test(coverage): tighten sentry_dsn round-trip assertion to exact value

round_trip_preserves_all_fields previously only checked
`back.sentry_dsn.is_some()`, which would still pass if serde dropped or
corrupted the DSN string. Compare the full decoded value instead so any
regression in the Option<String> path is caught.

Refs #530.
2026-04-15 16:31:51 -07:00
2026-03-26 17:04:46 -07:00
2026-04-15 20:45:19 +00:00
2026-02-20 13:03:15 +04:00
2026-02-20 13:03:15 +04:00

OpenHuman

The age of super intelligence is here. OpenHuman is your Personal AI super intelligence. Private, Simple and extremely powerful.

DiscordRedditX/TwitterDocs

Early Beta Platforms: desktop only Latest Release

The Tet

"The Tet. What a brilliant machine" — Morgan Freeman as he reminisces about alien superintelligence in the movie Oblivion

Early Beta — Under active development. Expect rough edges.

To install or get started, either download from the website over at tinyhumans.ai/openhuman or run

# For MacOS/Linux
curl -fsSL https://raw.githubusercontent.com/tinyhumansai/openhuman/main/scripts/install.sh | bash

# For Windows
irm https://raw.githubusercontent.com/tinyhumansai/openhuman/main/scripts/install.ps1 | iex

What is OpenHuman?

OpenHuman is an open-source agentic assistant that is designed to integrate with you in your daily life. Here's what makes OpenHuman special:

  • Simple, UI-first — A clean desktop experience and short onboarding paths so you can go from install to a working agent in a few clicks, without a config-first setup. You don't need a terminal to run OpenHuman.

  • One subscription, many providers — You only need one account to get access to many agentic APIs (AI Models, Search, Webhooks/Tunnels and other 3rd party APIs etc..), simplifying the experience to get a powerful agent going.

  • Rich Skills — Plug into Gmail, Slack, Notion, and the rest of your stack via rich, feature-backed skills. Connections are typically one click through setup wizards instead of wiring APIs by hand. Workflow data is kept on device, encrypted locally, and treated as yours: encryption and sensitive context stay on your machine. Webhooks give instant feedback into the agent when external systems or skills emit events, so the loop stays tight without constant polling.

  • Local knowledge base — Built from your data and your activity. How you work across tools, sessions, and connected services—so the agent gets rich, workflow-aware context, not a one-off chat transcript. Everything is stored on your machine and compounding over time without becoming a cloud dossier. Channels, skills and ongoing conversations feed the same loop so day-to-day context does not reset every session.

  • Local AI model — The Rust core exposes local AI paths (and the desktop bundle can ship local/bundled runners where applicable) for the workloads above—vision snippets, speech helpers, summarization, tooling—so sensitive steps can stay off the cloud when you choose.

  • Deep desktop integrations — OpenHuman is a native desktop assistant, not a web-only chat: memory-aware keyboard autocomplete, voice (STT listening and TTS replies), screen intelligence that understands what is on screen and feeds your local context, plus windowing and OS-level permissions—so the agent meets you on the machine, not trapped in a browser tab.

Architecture: docs/ARCHITECTURE.md. Contributor orientation: CONTRIBUTING.md.

OpenHuman vs other agents

High-level comparison (products evolve—verify against each vendor). OpenHuman is built to minimize vendor sprawl, keep workflow knowledge on-device, and ship deep desktop features—not only chat.

Claude Code/Cowork OpenClaw Hermes Agent OpenHuman
Open-source: Is the codebase open to review? 🚫 Proprietary client MIT License MIT License GNU License
Simple: Is it simple to get started? Simple Desktop App + CLI ⚠️ Terminal first and often complex ⚠️ Terminal first and often complex Simple, Clean UI/UX. Get started within minutes
Cost: How expensive is to run? ⚠️ Subscription + add-on tool/API costs ⚠️ Tied to models & hosting you choose ⚠️ Tied to models & hosting you choose Cost optimized with the option to run many things locally for free
Memory & Knowledge Base (KB): Does the agent know you and your world? Built-in memory; mostly chat/session scoped ⚠️ Has a local memory but often needs plugins for richer behavior Self-learning / task loops (typical) 🚀 Local KB + Self-learning from your activity & data (GMail, Notion etc... via skills) & prompts
API spagetti: How complex is it to hook mulitple features together? 🚫 Claude bill + often extra keys for MCP/tools 🚫 BYOK / multi-vendor common 🚫 Multiple providers common One account get access to many bundled platform APIs
Extensibility: Can you add rich features into it? MCP (different model than sandboxed skills) Plugin Architecture (SKILL.md) Plugin Architecture (SKILL.md) 🚀 Rich Skills with ability to have realtime updates, local DB & more
Desktop integrations: Can it integrate into your desktop completely? ⚠️ Desktop app & access to folders ⚠️ Often lighter native surface ⚠️ Often lighter native surface STT, TTS, screen intelligence, memory-aware autocomplete and a whole lot more

Contributors Hall of Fame

Show some love and end up in the hall of fame

OpenHuman contributors
S
Description
No description provided
Readme GPL-3.0
214 MiB
Languages
Rust 59.1%
TypeScript 37.9%
JavaScript 1.6%
Shell 1.2%
CSS 0.1%