docs(gitbooks v5): restructure features, simplify subconscious, README polish, default auto-fetch to 20 min (#1386)

This commit is contained in:
Steven Enamakel
2026-05-08 23:12:59 -07:00
committed by GitHub
parent 0a920159f3
commit 72048814ff
54 changed files with 241 additions and 1817 deletions
+12
View File
@@ -1,5 +1,17 @@
#!/usr/bin/env sh
# Bail out immediately on Ctrl+C / SIGTERM. Without this trap, an interrupt
# only kills the current pnpm subprocess; the script then captures its 130
# exit, mistakes it for a normal failure, and runs the next pnpm step.
abort() {
echo
echo "Pre-push aborted."
trap - INT TERM
kill -- -$$ 2>/dev/null
exit 130
}
trap abort INT TERM
# Windows Git Bash can miss Node/Pnpm in PATH when hooks run.
# Recover from common PATH drift by hydrating from where.exe.
has_node() {
+21 -19
View File
@@ -25,7 +25,7 @@
<a href="https://github.com/tinyhumansai/openhuman/releases/latest"><img src="https://img.shields.io/github/v/release/tinyhumansai/openhuman?label=latest" alt="Latest Release" /></a>
</p>
> **Early Beta** Under active development. Expect rough edges.
> **Early Beta**: Under active development. Expect rough edges.
To install or get started, either download from the website over at [tinyhumans.ai/openhuman](https://tinyhumans.ai/openhuman) or run
@@ -41,33 +41,35 @@ irm https://raw.githubusercontent.com/tinyhumansai/openhuman/main/scripts/instal
OpenHuman is an open-source agentic assistant designed to integrate with you in your daily life. Each bullet links to the deeper writeup in the [docs](https://tinyhumans.gitbook.io/openhuman/).
- **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. No terminal required.
- **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. No terminal required.
- **One subscription, many providers** — One account gets you access to many agentic APIs (AI models, search, webhooks/tunnels, third-party APIs).
- **[118+ third-party integrations with auto-fetch](https://tinyhumans.gitbook.io/openhuman/features/integrations)**: plug into Gmail, Notion, GitHub, Slack, Stripe, Calendar, Drive, Linear, Jira and the rest of your stack with **one-click OAuth**. Every connection is exposed to the agent as a typed tool, and every twenty minutes the core walks each active connection and pulls fresh data into the [memory tree](https://tinyhumans.gitbook.io/openhuman/features/integrations/auto-fetch). No prompts, no polling loops you have to write, so the agent already has tomorrow's context this morning.
- **[118+ third-party integrations](https://tinyhumans.gitbook.io/openhuman/features/integrations)** — Plug into Gmail, Notion, GitHub, Slack, Stripe, Calendar, Drive, Linear, Jira and the rest of your stack with **one-click OAuth**. Every connection is exposed to the agent as a typed tool.
- **[Memory Tree](https://tinyhumans.gitbook.io/openhuman/features/memory-tree) + [Obsidian Wiki](https://tinyhumans.gitbook.io/openhuman/features/obsidian-wiki)**: a local-first knowledge base built from your data and your activity. Everything you connect is canonicalized into ≤3k-token Markdown chunks, scored, and folded into hierarchical summary trees stored in **SQLite on your machine**. The same chunks land as `.md` files in an Obsidian-compatible vault you can open, browse and edit, inspired by Karpathy's [obsidian-wiki workflow](https://x.com/karpathy/status/2039805659525644595).
- **[Memory Tree](https://tinyhumans.gitbook.io/openhuman/features/memory-tree) + [Obsidian Wiki](https://tinyhumans.gitbook.io/openhuman/features/obsidian-wiki)** — A local-first knowledge base built from your data and your activity. Everything you connect is canonicalized into ≤3k-token Markdown chunks, scored, and folded into hierarchical summary trees stored in **SQLite on your machine**. The same chunks land as `.md` files in an Obsidian-compatible vault you can open, browse and edit — inspired by Karpathy's [obsidian-wiki workflow](https://x.com/karpathy/status/2039805659525644595).
- **Batteries included**: web search, a web-fetch [scraper](https://tinyhumans.gitbook.io/openhuman/features/native-tools), a full coder toolset (filesystem, git, lint, test, grep), and [native voice](https://tinyhumans.gitbook.io/openhuman/features/voice) (STT in, ElevenLabs TTS out, mascot lip-sync, live Google Meet agent) are wired in by default. [Model routing](https://tinyhumans.gitbook.io/openhuman/features/model-routing) sends each task to the right LLM (reasoning, fast, or vision) under one subscription. No "install a plugin to read files" friction. [Optional local AI via Ollama](https://tinyhumans.gitbook.io/openhuman/features/model-routing/local-ai) for on-device workloads.
- **[Auto-fetch from your stack](https://tinyhumans.gitbook.io/openhuman/features/auto-fetch)** — Every five minutes the core walks each active connection and pulls fresh data into the memory tree. No prompts, no polling loops you have to write — the agent already has tomorrow's context this morning.
- **[Smart token compression (TokenJuice)](https://tinyhumans.gitbook.io/openhuman/features/token-compression)**: every tool call, scrape result, email body, and search payload is run through a token compression layer before it touches any LLM Model. HTML is converted to Markdown, long URLs are shortened, etc... You get the same information but at a fraction of the tokens. Reducing costs by upto 80%.
- **[Smart token compression (TokenJuice)](https://tinyhumans.gitbook.io/openhuman/features/token-compression)** — Verbose tool output (git, npm, cargo, docker, large emails) is compacted by a rule overlay before it ever enters LLM context. Sweeping through thousands of emails stays cheap because the model never sees the noise.
- **[Automatic model routing](https://tinyhumans.gitbook.io/openhuman/features/model-routing)** — Tasks pick their model. `hint:reasoning` lands on a strong reasoning model, `hint:fast` on a fast one, vision goes to a vision model — all under one subscription, with zero per-provider key juggling.
- **[Native voice (ElevenLabs)](https://tinyhumans.gitbook.io/openhuman/features/voice)** — STT in, ElevenLabs TTS out, with mascot lip-sync. Includes a live Google Meet agent that listens, takes notes and can speak back in your meetings.
- **[Native search, scraper and coder](https://tinyhumans.gitbook.io/openhuman/features/native-tools)** — Built-in web search, web-fetch scraper, and a full filesystem / git / lint / test / grep toolset wired into the agent out of the box. No "install a plugin to read files" friction.
- **[Optional local AI (via Ollama)](https://tinyhumans.gitbook.io/openhuman/features/local-ai)** — Off by default. Opt in per-workload to keep memory embeddings, summary-tree building, and background reflection loops on your machine. Chat / vision / voice stay cloud — the local path is scoped to the workloads where on-device actually pays.
- **[Messaging channels](https://tinyhumans.gitbook.io/openhuman/features/integrations#messaging-channels)** and **[privacy & security](https://tinyhumans.gitbook.io/openhuman/features/privacy-and-security)** — Inbound/outbound across the channels you already use, with workflow data that stays on device, encrypted locally, treated as yours.
- **[Messaging channels](https://tinyhumans.gitbook.io/openhuman/features/integrations#messaging-channels)** and **[privacy & security](https://tinyhumans.gitbook.io/openhuman/features/privacy-and-security)**: inbound/outbound across the channels you already use, with workflow data that stays on device, encrypted locally, treated as yours.
For contributors: [Architecture](https://tinyhumans.gitbook.io/openhuman/developing/architecture) · [Getting Set Up](https://tinyhumans.gitbook.io/openhuman/developing/getting-set-up) · [Cloud Deploy](https://tinyhumans.gitbook.io/openhuman/developing/cloud-deploy) · [`CONTRIBUTING.md`](./CONTRIBUTING.md).
## Context in minutes, not weeks
OpenHuman is the first agent harness that gets to know in minutes. Insipired by [Karpathy's LLM Knowledgebase](https://x.com/karpathy/status/2039805659525644595). Connect → sync → ingest → done.
<p align="center">
<img src="./gitbooks/.gitbook/assets/image.png" alt="The Tet" />
</p>
Most agents start cold. Hermes learns by watching you work; OpenClaw waits for plugins to ferry context in. Either way, you spend days or weeks before the agent knows enough about your stack to be genuinely useful.
OpenHuman skips the wait. Connect your accounts, let [auto-fetch](https://tinyhumans.gitbook.io/openhuman/features/integrations/auto-fetch) pull from every integration on a 20-minute loop, and the [Memory Tree](https://tinyhumans.gitbook.io/openhuman/features/memory-tree) canonicalizes everything into ≤3k-token Markdown chunks scored and folded into hierarchical summary trees: a Karpathy-style [Obsidian wiki](https://tinyhumans.gitbook.io/openhuman/features/obsidian-wiki) on disk, queryable SQLite under the hood. One sync pass and the agent has read your inbox, your calendar, your repos, your docs. No training period. No "give it a few weeks."
## OpenHuman vs Other Agent Harnesses
High-level comparison (products evolveverify against each vendor). OpenHuman is built to **minimize vendor sprawl**, keep **workflow knowledge on-device**, and give the agent a **persistent memory** of your data not only chat.
High-level comparison (products evolve, so verify against each vendor). OpenHuman is built to **minimize vendor sprawl**, keep **workflow knowledge on-device**, and give the agent a **persistent memory** of your data, not only chat.
| | Claude Cowork | OpenClaw | Hermes Agent | OpenHuman |
| ------------------- | ----------------- | ----------------- | ----------------- | ---------------------------------- |
@@ -76,7 +78,7 @@ High-level comparison (products evolve—verify against each vendor). OpenHuman
| **Cost** | ⚠️ Sub + add-ons | ⚠️ BYO models | ⚠️ BYO models | ✅ One sub + TokenJuice |
| **Memory** | ✅ Chat-scoped | ⚠️ Plugin-reliant | ✅ Self-learning | 🚀 Memory Tree + Obsidian vault |
| **Integrations** | ⚠️ Few connectors | ⚠️ BYO | ⚠️ BYO | 🚀 118+ via OAuth |
| **Auto-fetch** | 🚫 None | 🚫 None | 🚫 None | ✅ 5-min sync into memory |
| **Auto-fetch** | 🚫 None | 🚫 None | 🚫 None | ✅ 20-min sync into memory |
| **API sprawl** | 🚫 Extra keys | 🚫 BYOK | 🚫 Multi-vendor | ✅ One account |
| **Model routing** | 🚫 Single model | ⚠️ Manual | ⚠️ Manual | ✅ Built-in |
| **Native tools** | ✅ Code-only | ✅ Code-only | ✅ Code-only | ✅ Code + search + scraper + voice |
Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

+3 -3
View File
@@ -19,9 +19,9 @@ OpenHuman solves this with a stack that's calmly, deliberately different:
**An** [**Obsidian-style wiki**](features/obsidian-wiki/) **on top of it.** The same chunks the agent reasons over land as `.md` files in a vault you can open in [Obsidian](https://obsidian.md), browse, edit, and link by hand. Inspired by [Karpathy's obsidian-wiki workflow](https://x.com/karpathy/status/2039805659525644595). You can't trust a memory you can't read.
[**118+ third-party integrations**](features/integrations.md)**, with** [**auto-fetch**](features/auto-fetch.md)**.** One-click OAuth into Gmail, GitHub, Slack, Notion, Stripe, Calendar, Drive, Linear, Jira and more. Every five minutes, OpenHuman pulls fresh data from every active connection and folds it into the Memory Tree without you asking.
[**118+ third-party integrations**](features/integrations/README.md)**, with** [**auto-fetch**](features/integrations/auto-fetch.md)**.** One-click OAuth into Gmail, GitHub, Slack, Notion, Stripe, Calendar, Drive, Linear, Jira and more. Every twenty minutes, OpenHuman pulls fresh data from every active connection and folds it into the Memory Tree without you asking.
**An agent built for big data.** [Smart token compression (TokenJuice)](features/token-compression.md) compacts verbose tool output before it ever enters the model's context, so sweeping through your last six months of email costs single-digit dollars. [Automatic model routing](features/model-routing.md) sends each task to the right model, `hint:reasoning` to a frontier model, `hint:fast` to a cheap one, vision to vision, all under one subscription. Built-in [native tools](features/native-tools.md) cover web search, scraping, and a full filesystem/git/lint/test/grep coder loop.
**An agent built for big data.** [Smart token compression (TokenJuice)](features/token-compression.md) compacts verbose tool output before it ever enters the model's context, so sweeping through your last six months of email costs single-digit dollars. [Automatic model routing](features/model-routing/README.md) sends each task to the right model, `hint:reasoning` to a frontier model, `hint:fast` to a cheap one, vision to vision, all under one subscription. Built-in [native tools](features/native-tools.md) cover web search, scraping, and a full filesystem/git/lint/test/grep coder loop.
[**Native voice (ElevenLabs)**](features/voice.md)**.** STT in, ElevenLabs TTS out, mascot lip-sync, and a live Google Meet agent that joins meetings, transcribes them into your Memory Tree, and can speak back into the call.
@@ -35,7 +35,7 @@ OpenHuman is not AGI. But it is a meaningful architectural step closer, with bet
OpenHuman connects to your tools, pulls from them continuously, and turns the firehose into something structured any AI can act on.
- It **fetches automatically** from every active integration every five minutes, so the agent already has tomorrow's context this morning.
- It **fetches automatically** from every active integration every twenty minutes, so the agent already has tomorrow's context this morning.
- It **compresses** millions of tokens of organizational noise into a deterministic Memory Tree of chunks, scores, entities, and summaries.
- It **surfaces signals** that matter: decisions, action items, risks, sentiment shifts, and buried context you would otherwise miss.
- It **routes intelligently**, picking the right model for each task and compacting tool output through TokenJuice so cost stays minimal even at scale.
+4 -10
View File
@@ -11,24 +11,18 @@
* [Obsidian-Style Memory](features/obsidian-wiki/README.md)
* [Memory Tree](features/obsidian-wiki/memory-tree.md)
* [Memory Tree Pipeline](features/obsidian-wiki/memory-tree-pipeline.md)
* [Auto-fetch from Integrations](features/auto-fetch.md)
* [Third-party Integrations (118+)](features/integrations.md)
* [Third-party Integrations (118+)](features/integrations/README.md)
* [Auto-fetch from Integrations](features/integrations/auto-fetch.md)
* [Smart Token Compression](features/token-compression.md)
* [Automatic Model Routing](features/model-routing.md)
* [Automatic Model Routing](features/model-routing/README.md)
* [Local AI (optional)](features/model-routing/local-ai.md)
* [Native Voice (ElevenLabs)](features/voice.md)
* [Native Tools (search, scraper, coder)](features/native-tools.md)
* [Local AI (optional)](features/local-ai.md)
* [Subconscious Loop](features/subconscious.md)
* [Privacy & Security](features/privacy-and-security.md)
* [Platform & Availability](features/platform.md)
* [Architecture](features/architecture.md)
## Settings Reference
* [Account & Security](settings-reference/account-and-security.md)
* [Automation & Channels](settings-reference/automation-and-channels.md)
* [AI & Skills](settings-reference/ai-and-skills.md)
## Developing
* [Overview](developing/README.md)
+52 -28
View File
@@ -1,48 +1,72 @@
---
description: >-
Contributor-facing documentation for OpenHuman — how to build, test, ship, and
extend the app and core.
description: Build, run, test, and ship OpenHuman from source.
icon: code-branch
---
# Overview
# Developing OpenHuman
OpenHuman is open source under GNU GPL3 and lives at [github.com/tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman). This section is for contributors and people running OpenHuman from source.
OpenHuman is open source under GPLv3 at [github.com/tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman). This section is for contributors and anyone running OpenHuman from source.
If you just want to use the app, head to [Getting Started](../overview/getting-started.md). If you're here to read the architecture, hack on a feature, or land a PR, you're in the right place.
---
## Where things live
| Path | What's there |
| ----------- | ------------------------------------------------------------------------------------------------------------------ |
| `app/` | Yarn workspace `openhuman-app` Vite + React frontend (`app/src/`) and the Tauri desktop host (`app/src-tauri/`). |
| `src/` | Rust crate `openhuman_core` and the `openhuman` CLI binary — domains, MCP routing, JSON-RPC. |
| `docs/` | Remaining deep developer reference (memory pipeline diagrams, telegram-login, sentry, agent flows, etc.). |
| `gitbooks/` | Public-facing documentation — this site. |
| Path | What's there |
| ----------- | ----------------------------------------------------------------------------------------------------------- |
| `app/` | pnpm workspace `openhuman-app`. Vite + React frontend (`app/src/`) and the Tauri desktop host (`app/src-tauri/`). |
| `src/` | Rust crate `openhuman_core` and the `openhuman` CLI binary. Domains, JSON-RPC, MCP routing. |
| `gitbooks/` | This site (the public-facing docs). |
| `docs/` | Older deep references not yet migrated to GitBook (memory pipeline diagrams, agent flows, etc.). |
The high-level shape lives in [Architecture](../features/architecture.md). The deep developer architecture lives in [Architecture](architecture.md).
`CLAUDE.md` at the repo root is the source of truth for AI agents working on the codebase. Same rules apply to humans.
---
## Start here
* [**Getting Set Up**](getting-set-up.md). building from source, toolchain, vendored Tauri CLI, sidecar staging.
* [**Testing Strategy**](testing-strategy.md). Vitest, cargo test, WDIO E2E. Where each test goes.
* [**E2E Testing**](e2e-testing.md). running end-to-end specs locally and in CI.
* [**Release Policy**](release-policy.md). release cadence, version policy, OAuth-and-installer rules.
If it's your first time pulling the repo:
## Building features
1. [**Getting Set Up**](getting-set-up.md). Toolchain, dependencies, the vendored Tauri CLI, sidecar staging — everything `pnpm dev` needs to actually start.
2. [**Architecture**](architecture.md). How the desktop app, the Rust core sidecar, the JSON-RPC bridge, and the dual sockets fit together. Read this before you make non-trivial changes.
3. [**Frontend**](frontend.md) and [**Tauri Shell**](tauri-shell.md). The React app and the desktop host that wraps it.
* [**Subconscious Loop**](../features/subconscious.md). background task evaluation against the workspace.
---
## Working with agents
## Testing
* [**Coding Harness**](coding-harness.md). the agent's code-focused tool surface and how to extend it.
* [**Agent Observability**](agent-observability.md). the artifact-capture layer that makes E2E tests debuggable.
OpenHuman ships with three test layers. Know which one your change belongs in:
## Other contributor docs
- [**Testing Strategy**](testing-strategy.md). When to write Vitest vs cargo tests vs WDIO.
- [**E2E Testing**](e2e-testing.md). WDIO/Appium specs, dual-platform setup (Linux tauri-driver, macOS Appium Mac2), and how to run a single spec locally.
- [**Agent Observability**](agent-observability.md). The artifact-capture layer that makes E2E and agent runs debuggable after the fact.
Anything not yet migrated lives under [`docs/`](https://github.com/tinyhumansai/openhuman/tree/main/docs) in the repo. Notable references:
PRs must clear the **≥ 80% coverage on changed lines** gate. Add tests for new behavior, not just the happy path.
* [Architecture](architecture.md). canonical architecture.
* [`docs/PROMPT_INJECTION_GUARD.md`](../../docs/PROMPT_INJECTION_GUARD.md). security model.
* [Frontend chapter](frontend.md). React app structure (`app/src/`).
* [Tauri shell chapter](tauri-shell.md). desktop host (`app/src-tauri/`).
---
[`CLAUDE.md`](../../CLAUDE.md) is the source of truth for AI agents working on the codebase, with the same rules contributors are expected to follow.
## Shipping
- [**Release Policy**](release-policy.md). Version policy, release cadence, OAuth + installer rules.
- [**Cloud Deploy**](cloud-deploy.md). Backend/cloud-side deployment when a change crosses the desktop boundary.
---
## Going deeper
- [**Coding Harness**](coding-harness.md). The agent's code-focused tool surface and how to extend it.
- [**Chromium Embedded Framework**](cef.md). How embedded provider webviews work, why they don't run injected JS, and what the per-provider scanners do instead.
For features still being built, the [Subconscious Loop](../features/subconscious.md) page covers the background task evaluation system end-to-end.
---
## Contributing
- Open issues and PRs at [tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman).
- PRs target `main`. Push to your fork, not upstream.
- Follow [`CONTRIBUTING.md`](https://github.com/tinyhumansai/openhuman/blob/main/CONTRIBUTING.md) and the issue/PR templates.
- Keep changes focused. A bug fix doesn't need surrounding cleanup; a one-shot operation doesn't need a helper.
Help building toward AGI doesn't have to mean shipping a kernel — bugfixes, docs, integrations, and tests all move the bar.
+3 -3
View File
@@ -43,8 +43,8 @@ OpenHuman is a **React + Tauri v2 desktop app** with a **Rust core** that does t
## Data flow
1. **Connect**. OAuth into a [integration](../features/integrations.md). Backend stores the token; core never sees it in plaintext.
2. **Auto-fetch**. Every five minutes the [scheduler](../features/auto-fetch.md) walks every active connection and asks each native provider to sync.
1. **Connect**. OAuth into a [integration](../features/integrations/README.md). Backend stores the token; core never sees it in plaintext.
2. **Auto-fetch**. Every twenty minutes the [scheduler](../features/integrations/auto-fetch.md) walks every active connection and asks each native provider to sync.
3. **Canonicalize**. Provider output (an email page, a GitHub diff, a Slack channel dump) is normalized into provenance-tagged Markdown.
4. **Chunk**. Markdown is split into ≤3k-token deterministic chunks.
5. **Store**. Chunks land in SQLite (`<workspace>/memory_tree/chunks.db`) and as `.md` files in `<workspace>/wiki/`.
@@ -52,7 +52,7 @@ OpenHuman is a **React + Tauri v2 desktop app** with a **Rust core** that does t
7. **Summarize**. Source / topic / global summary trees are built and refreshed from the chunk pool.
8. **Retrieve**. When you ask a question, the agent queries the Memory Tree (search / drill down / topic / global / fetch).
9. **Compress**. Tool output and large source data go through [TokenJuice](../features/token-compression.md) before entering LLM context.
10. **Route**. The [router](../features/model-routing.md) picks the right provider+model for the task hint.
10. **Route**. The [router](../features/model-routing/README.md) picks the right provider+model for the task hint.
## Privacy boundary
@@ -14,7 +14,7 @@ OpenHuman ships with backend-proxied access to **118+ third-party services**. Co
Once a service is connected, it shows up in three places at once:
1. As an **agent tool**, the model can call it directly.
2. As a **memory source**, [auto-fetch](auto-fetch.md) syncs it into the [Memory Tree](obsidian-wiki/memory-tree.md) every five minutes.
2. As a **memory source**, [auto-fetch](auto-fetch.md) syncs it into the [Memory Tree](../obsidian-wiki/memory-tree.md) every twenty minutes.
3. As a **profile signal**, your activity across services feeds your personalization.
## Some of what's in the catalog
@@ -38,7 +38,7 @@ Some services have **native providers**. Rust modules that know how to ingest th
## How connections work
Click **Connect** on any integration. A browser window opens for OAuth. Once you sign in, the connection becomes active and OpenHuman starts syncing it through [auto-fetch](auto-fetch.md) on the next 5-minute tick.
Click **Connect** on any integration. A browser window opens for OAuth. Once you sign in, the connection becomes active and OpenHuman starts syncing it through [auto-fetch](auto-fetch.md) on the next 20-minute tick.
Each integration shows its current status:
@@ -66,16 +66,16 @@ Beyond third-party services, OpenHuman has **skills**, small sandboxed modules t
Two capabilities ship native rather than as integrations because they're load-bearing for the desktop experience:
* [**Voice**](voice.md). STT in, ElevenLabs TTS out, plus a live Google Meet agent that joins meetings, transcribes them into your Memory Tree, and can speak back into the call.
* [**Native tools**](native-tools.md). built-in web search, web-fetch scraper, and a full filesystem/git/lint/test/grep coder toolset that the agent uses out of the box.
* [**Voice**](../voice.md). STT in, ElevenLabs TTS out, plus a live Google Meet agent that joins meetings, transcribes them into your Memory Tree, and can speak back into the call.
* [**Native tools**](../native-tools.md). built-in web search, web-fetch scraper, and a full filesystem/git/lint/test/grep coder toolset that the agent uses out of the box.
## Privacy boundary
OpenHuman's core never calls any third-party API directly. All requests go through the OpenHuman backend, which handles OAuth tokens and rate limiting. Your tokens never sit on disk in plaintext on your machine, and the agent only sees the _results_ of tool calls, not the credentials.
See [Privacy & Security](privacy-and-security.md) for the full boundary.
See [Privacy & Security](../privacy-and-security.md) for the full boundary.
## See also
* [Auto-fetch from Integrations](auto-fetch.md)
* [Memory Tree](obsidian-wiki/memory-tree.md)
* [Memory Tree](../obsidian-wiki/memory-tree.md)
@@ -1,21 +1,21 @@
---
description: >-
Every five minutes, OpenHuman walks every active integration and folds new
Every twenty minutes, OpenHuman walks every active integration and folds new
data into your memory tree. No prompts, no polling loops you have to write.
icon: arrows-rotate
---
# Auto-fetch from Integrations
Most "AI assistants" are reactive: you ask, they think, they answer. OpenHuman is the opposite. It pulls from your stack continuously, so by the time you ask "what landed in my inbox overnight?" the answer is already in the [Memory Tree](obsidian-wiki/memory-tree.md).
Most "AI assistants" are reactive: you ask, they think, they answer. OpenHuman is the opposite. It pulls from your stack continuously, so by the time you ask "what landed in my inbox overnight?" the answer is already in the [Memory Tree](../obsidian-wiki/memory-tree.md).
## How it works
A single periodic scheduler ticks every five minutes. On each tick it walks every active [integration](integrations.md), looks up the matching native provider, and, if enough time has elapsed since that connection's last sync, calls `provider.sync(ctx, SyncReason::Periodic)`.
A single periodic scheduler ticks every twenty minutes. On each tick it walks every active [integration](README.md), looks up the matching native provider, and, if enough time has elapsed since that connection's last sync, calls `provider.sync(ctx, SyncReason::Periodic)`.
```
┌──────────────────────────────────────────────────────────┐
│ every 5 min │
│ every 20 min │
│ │ │
│ ▼ │
│ for each active connection (Gmail, Notion, GitHub, …): │
@@ -34,7 +34,7 @@ A single periodic scheduler ticks every five minutes. On each tick it walks ever
A few things matter here:
* **One global tick, not one task per connection.** The number of connections per user is small; a single 5-minute tick is enough and keeps bookkeeping trivial.
* **One global tick, not one task per connection.** The number of connections per user is small; a single 20-minute tick is enough and keeps bookkeeping trivial.
* **State is per `(toolkit, connection_id)`.** Each connection has its own cursor, its own last-sync timestamp, its own dedup set, its own daily budget. Restarts rebuild this from local KV, a missed periodic sync is harmless because the next tick after restart picks it back up.
* **Native syncs are shared with event-driven paths.** When a webhook or `on_connection_created` event fires a non-periodic sync, it stamps the same sync\_state, so the scheduler doesn't redundantly re-fire.
* **Errors are logged and swallowed.** The scheduler must never panic out of its loop, or periodic sync stops silently for the rest of the process lifetime.
@@ -43,11 +43,11 @@ A few things matter here:
Each provider is responsible for shaping its own ingest. The Gmail provider, for example, fetches a page of new messages, runs the email canonicalizer, and pipes the result through the same `ingest` path the manual UI uses, chunks land in SQLite, summary bucket fills, topic tree gets dirtied for any entities touched.
Other providers (GitHub, Slack, Notion, …) follow the same shape: fetch new items since cursor → canonicalize → ingest into the [Memory Tree](obsidian-wiki/memory-tree.md).
Other providers (GitHub, Slack, Notion, …) follow the same shape: fetch new items since cursor → canonicalize → ingest into the [Memory Tree](../obsidian-wiki/memory-tree.md).
## Why a 5-minute tick
## Why a 20-minute tick
The original design ran at 60 seconds. With several connected providers, that meant a steady drumbeat of HTTP fetches and DB writes, visibly busy on a laptop. Five minutes trades a little staleness for noticeably less foreground load. The per-provider `sync_interval_secs` still caps the _minimum_ delay between actual syncs; the global tick only loosens the upper bound.
The original design ran at 60 seconds. With several connected providers, that meant a steady drumbeat of HTTP fetches and DB writes, visibly busy on a laptop. Twenty minutes trades a little staleness for noticeably less foreground load. The per-provider `sync_interval_secs` still caps the _minimum_ delay between actual syncs; the global tick only loosens the upper bound.
## Tuning and visibility
@@ -57,6 +57,6 @@ The original design ran at 60 seconds. With several connected providers, that me
## See also
* [Third-party Integrations](integrations.md). the connector layer auto-fetch runs on top of.
* [Memory Tree](obsidian-wiki/memory-tree.md). where everything ends up.
* [Smart Token Compression](token-compression.md). what keeps "fetch everything" cheap.
* [Third-party Integrations](README.md). the connector layer auto-fetch runs on top of.
* [Memory Tree](../obsidian-wiki/memory-tree.md). where everything ends up.
* [Smart Token Compression](../token-compression.md). what keeps "fetch everything" cheap.
@@ -58,5 +58,6 @@ Routing isn't a UI dropdown. The agent loop itself emits hints based on what it'
## See also
- [Smart Token Compression](token-compression.md). what makes large reasoning calls affordable.
- [Native Tools](native-tools.md). different tool calls hint at different routes.
- [Smart Token Compression](../token-compression.md). what makes large reasoning calls affordable.
- [Native Tools](../native-tools.md). different tool calls hint at different routes.
- [Local AI (optional)](local-ai.md). lightweight chat hints can run on-device.
@@ -15,7 +15,7 @@ This is a deliberate scoping. The previous design tried to put chat, vision, STT
| Workload | Default model | Implementation |
| ------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Memory embeddings** | `all-minilm:latest` | `src/openhuman/embeddings/ollama.rs` — used by the [Memory Tree](obsidian-wiki/memory-tree.md) for vector search. |
| **Memory embeddings** | `all-minilm:latest` | `src/openhuman/embeddings/ollama.rs` — used by the [Memory Tree](../obsidian-wiki/memory-tree.md) for vector search. |
| **Summary-tree building** | `gemma3:1b-it-qat` (configurable) | `src/openhuman/tree_summarizer/ops.rs` — source / topic / global summary builders for the Memory Tree. |
| **Heartbeat loop** | small chat model | `src/openhuman/heartbeat/` — periodic background reflection. |
| **Learning / reflection** | small chat model | `src/openhuman/learning/reflection.rs` — passes that consolidate what was learned. |
@@ -27,13 +27,13 @@ Each of these is a **per-feature opt-in flag**. Turning on local AI does not sil
| Workload | Why cloud |
| ------------------ | --------------------------------------------------------------------------------------------------- |
| **Chat (default)** | Frontier reasoning quality. Routed via the [model router](model-routing.md) under one subscription. |
| **Chat (default)** | Frontier reasoning quality. Routed via the [model router](README.md) under one subscription. |
| **Vision** | Same. |
| **STT** | Backend-proxied transcription (`src/openhuman/voice/cloud_transcribe.rs`). |
| **TTS** | [ElevenLabs](voice.md) under the hood (`reply_speech.rs`). |
| **TTS** | [ElevenLabs](../voice.md) under the hood (`reply_speech.rs`). |
| **Web search** | Backend proxy (no API key on your machine). |
For **lightweight or medium chat hints** (`hint:reaction`, `hint:classify`, `hint:format`, `hint:sentiment`, `hint:summarize`, `hint:medium`, `hint:tool_lite`), the [router](model-routing.md) will prefer the local provider when local AI is enabled and Ollama is reachable. Heavy hints (`hint:reasoning`, `hint:agentic`, `hint:coding`) stay cloud.
For **lightweight or medium chat hints** (`hint:reaction`, `hint:classify`, `hint:format`, `hint:sentiment`, `hint:summarize`, `hint:medium`, `hint:tool_lite`), the [router](README.md) will prefer the local provider when local AI is enabled and Ollama is reachable. Heavy hints (`hint:reasoning`, `hint:agentic`, `hint:coding`) stay cloud.
## How it works
@@ -78,6 +78,6 @@ OpenHuman handles the rest: lifecycle (`src/openhuman/local_ai/service.rs`), API
## See also
* [Memory Tree](obsidian-wiki/memory-tree.md). what local embeddings + summarization power.
* [Automatic Model Routing](model-routing.md). how lightweight chat hints prefer the local provider.
* [Privacy & Security](../features/privacy-and-security.md). what moves on-device when you opt in.
* [Memory Tree](../obsidian-wiki/memory-tree.md). what local embeddings + summarization power.
* [Automatic Model Routing](README.md). how lightweight chat hints prefer the local provider.
* [Privacy & Security](../privacy-and-security.md). what moves on-device when you opt in.
+1 -1
View File
@@ -61,4 +61,4 @@ A plugin-only model means tools live in different processes, behind RPC, with th
## See also
- [Smart Token Compression](token-compression.md). what keeps tool output costs bounded.
- [Third-party Integrations](integrations.md). for the long tail of third-party services.
- [Third-party Integrations](integrations/README.md). for the long tail of third-party services.
+1 -1
View File
@@ -50,4 +50,4 @@ It's also the cleanest possible export: stop using OpenHuman tomorrow and you ke
## See also
* [Memory Tree](memory-tree.md). the pipeline that produces the vault.
* [Auto-fetch from Integrations](../auto-fetch.md). how the vault grows on its own.
* [Auto-fetch from Integrations](../integrations/auto-fetch.md). how the vault grows on its own.
@@ -151,4 +151,4 @@ A few rules to keep the pipeline coherent:
## See also
* [Memory Tree (user-facing)](memory-tree.md). the product surface this pipeline powers.
* [Local AI](../local-ai.md). opt-in path for running embeddings + summarization on-device.
* [Local AI](../model-routing/local-ai.md). opt-in path for running embeddings + summarization on-device.
@@ -42,7 +42,7 @@ retrieval ── search · drill_down · topic · global · fetch
The hot path (`canonicalize → chunk → stage → fast-score → persist → enqueue extract jobs`) is fast. Heavy work, embeddings, entity extraction, sealing summary buckets, daily digests, runs in background workers out of the `jobs/` queue so the UI never blocks.
Embeddings and summary-tree building can run **on-device via Ollama** if you turn on [Local AI](../local-ai.md); otherwise they go through the OpenHuman backend like any other model call.
Embeddings and summary-tree building can run **on-device via Ollama** if you turn on [Local AI](../model-routing/local-ai.md); otherwise they go through the OpenHuman backend like any other model call.
## Three trees, three scopes
@@ -75,7 +75,7 @@ Trees give you compression _and_ navigation. Embeddings still live inside (in `s
## Triggering ingest
* **Automatic**. every active integration is auto-fetched every five minutes; see [Auto-fetch](../auto-fetch.md).
* **Automatic**. every active integration is auto-fetched every twenty minutes; see [Auto-fetch](../integrations/auto-fetch.md).
* **Manual**. the Memory tab in the desktop app exposes a "Run ingest" trigger per source.
* **RPC**. `openhuman.memory_tree_ingest` for advanced workflows.
@@ -103,12 +103,12 @@ Open it from the bottom navigation bar.
**Search & retrieval.** A search bar over the Memory Tree. Source-scoped, topic-scoped or global queries are all supported, and any result links back to the underlying chunk file in your Obsidian vault for full provenance.
**Routing.** The Intelligence tab also surfaces which model the agent is using per task, see [Automatic Model Routing](../model-routing.md).
**Routing.** The Intelligence tab also surfaces which model the agent is using per task, see [Automatic Model Routing](../model-routing/README.md).
## See also
* [Obsidian Wiki](./). open the vault in Obsidian and edit it directly.
* [Auto-fetch from Integrations](../auto-fetch.md). how the tree stays fresh.
* [Auto-fetch from Integrations](../integrations/auto-fetch.md). how the tree stays fresh.
* [Smart Token Compression](../token-compression.md). what makes ingesting "everything" cheap.
* [Local AI (optional)](../local-ai.md). opt in to keep embeddings and summary-tree building on-device.
* [Local AI (optional)](../model-routing/local-ai.md). opt in to keep embeddings and summary-tree building on-device.
* [Memory Tree Pipeline](memory-tree-pipeline.md). contributor-facing deep dive on the async queue, workers and tree-state machine.
+1 -1
View File
@@ -63,7 +63,7 @@ The desktop app maintains a persistent connection to the OpenHuman backend. Resp
Your local state persists on your device. Preferences, settings, and connected-source configurations remain available offline. The local Memory Tree is fully accessible, you can browse the [Obsidian vault](../features/obsidian-wiki/) and read your existing notes without any network connection.
Auto-fetch and live LLM calls require connectivity. When the network returns, the next 5-minute tick picks up where it left off.
Auto-fetch and live LLM calls require connectivity. When the network returns, the next 20-minute tick picks up where it left off.
***
+5 -5
View File
@@ -18,7 +18,7 @@ OpenHuman is designed so that the **memory of your life lives on your machine**.
**No training on your data.** Your conversations, your Memory Tree, and your personal information are never used to train AI models or improve systems.
**Optional [Local AI](../features/local-ai.md).** If you want embeddings and summary-tree building to stay on your machine, opt in. Heartbeat / learning / subconscious loops can be moved on-device the same way.
**Optional [Local AI](../features/model-routing/local-ai.md).** If you want embeddings and summary-tree building to stay on your machine, opt in. Heartbeat / learning / subconscious loops can be moved on-device the same way.
***
@@ -35,9 +35,9 @@ OpenHuman is designed so that the **memory of your life lives on your machine**.
| | |
| --- | --- |
| **LLM calls** | Proxied through the backend under one subscription, then forwarded to the underlying provider (Anthropic / OpenAI / Google / etc.) per the [model router](../features/model-routing.md). |
| **LLM calls** | Proxied through the backend under one subscription, then forwarded to the underlying provider (Anthropic / OpenAI / Google / etc.) per the [model router](../features/model-routing/README.md). |
| **Web search proxy** | The native [web search tool](../features/native-tools.md) calls a backend proxy so you don't carry a search API key. |
| **Integration OAuth & tool proxy** | Token storage and rate-limited request brokering for [118+ integrations](../features/integrations.md). |
| **Integration OAuth & tool proxy** | Token storage and rate-limited request brokering for [118+ integrations](../features/integrations/README.md). |
| **TTS streaming** | [ElevenLabs](../features/voice.md) audio streams. Audio is generated and discarded — not retained. |
***
@@ -46,7 +46,7 @@ OpenHuman is designed so that the **memory of your life lives on your machine**.
OpenHuman accesses an integration only after you complete its OAuth flow. Each connection has its own scope; you can revoke any of them at any time from the Skills tab.
[Auto-fetch](../features/auto-fetch.md) does run continuously while a connection is active, that is the whole point. But it is bound by:
[Auto-fetch](../features/integrations/auto-fetch.md) does run continuously while a connection is active, that is the whole point. But it is bound by:
- The **OAuth scope** you granted that integration.
- A **per-provider sync interval** (e.g. Gmail every 15 min by default).
@@ -64,7 +64,7 @@ Because canonicalization, chunking, scoring and summary trees all run **inside y
Compression and locality together become the privacy architecture.
<figure><img src="../.gitbook/assets/V17. Privacy Shield@2x.png" alt=""><figcaption></figcaption></figure>
<figure><img src="../.gitbook/assets/V17 Privacy Shield@2x.png" alt=""><figcaption></figcaption></figure>
## Security
+92 -222
View File
@@ -5,310 +5,180 @@ icon: loader
# Subconscious Loop
Background task evaluation and execution system. Periodically checks user-defined and system tasks against the current workspace state, decides what to do, and either acts autonomously or escalates to the user.
A background task evaluation and execution system. On a periodic tick, it loads a list of user-defined and system tasks, reads the current state of your workspace, decides what to do about each one, and either acts autonomously or escalates to you for approval.
Think of it as the agent's idle thread: the part that keeps thinking after you've stopped typing.
---
## Architecture
## How a tick works
```
┌─────────────────────────────────────────────────────────┐
│ Heartbeat Engine
(sleeps N minutes between ticks)
│ Heartbeat
│ (sleeps a few minutes between ticks) │
└──────────────────────┬──────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Subconscious Engine
│ Subconscious Engine │
│ │
│ 1. Load due tasks from SQLite
│ 2. Insert in_progress log entries
│ 3. Build situation report (memory + workspace state)
│ 4. Evaluate tasks with local Ollama model
│ 5. Execute decisions (act / noop / escalate)
│ 6. Update log entries in place
│ 1. Load due tasks
│ 2. Mark each one in-progress
│ 3. Build a situation report (memory + workspace)
│ 4. Evaluate every task with the local model │
│ 5. Execute the decision (act / noop / escalate) │
│ 6. Write the outcome back to the activity log
└─────────────────────────────────────────────────────────┘
┌───────────┼───────────┐
▼ ▼ ▼
noop act escalate
(skip) (execute) (agentic-v1)
(skip) (execute) (deeper agent)
```
### Key files
| File | Purpose |
|------|---------|
| `src/openhuman/heartbeat/engine.rs` | Periodic scheduler, delegates to subconscious engine |
| `src/openhuman/subconscious/engine.rs` | Core tick logic, state management, overlap guard |
| `src/openhuman/subconscious/executor.rs` | Task execution routing (local model vs agentic-v1) |
| `src/openhuman/subconscious/prompt.rs` | Prompt builders for evaluation and execution |
| `src/openhuman/subconscious/store.rs` | SQLite persistence (tasks, log, escalations) |
| `src/openhuman/subconscious/types.rs` | Data types and enums |
| `src/openhuman/subconscious/situation_report.rs` | Builds context from memory and workspace state |
| `src/openhuman/subconscious/global.rs` | Global singleton shared between heartbeat and RPC |
| `src/openhuman/subconscious/schemas.rs` | RPC endpoint handlers |
| `app/src/hooks/useSubconscious.ts` | Frontend hook for data fetching and actions |
| `app/src/pages/Intelligence.tsx` | UI rendering (Subconscious tab) |
| `app/src/utils/tauriCommands/subconscious.ts` | TypeScript RPC wrappers |
Each tick is independent. If a tick is still running when the next one starts (slow model call, network blip), the new tick takes over and the old one's in-progress entries are marked cancelled. Ticks never stack.
---
## Task Types
## Task types
### System tasks
Seeded automatically on engine initialization. Cannot be deleted, only disabled.
Seeded automatically when the engine starts. Cannot be deleted, only disabled. The defaults cover things you'd want any assistant watching for:
Default system tasks:
- Check connected skills for errors or disconnections
- Review new memory updates for actionable items
- Monitor system health (Ollama, memory, connections)
- Monitor system health (local model, memory, connections)
Additional system tasks are imported from `HEARTBEAT.md` in the workspace directory (one task per `- ` line).
You can extend the system task set by listing additional ones in a `HEARTBEAT.md` file in your workspace, one task per line.
### User tasks
Added manually via the UI. Can be toggled on/off and deleted.
Anything you add manually from the UI. Toggle on/off, edit, delete. Examples:
Examples:
- "Check urgent emails" (read-only)
- "Send daily summary to Slack" (write intent)
- "Summarize Notion updates" (read-only)
---
## Tick Lifecycle
## Decisions
### 1. Overlap guard
For every due task, the local model returns one of three decisions:
Each tick gets a monotonically increasing generation counter. If a new tick starts while the old one is still running (e.g., slow LLM call), the old tick's results are discarded and its `in_progress` log entries are marked as `cancelled`.
| Decision | Meaning |
| ----------- | ---------------------------------------------------- |
| Skip | Nothing relevant right now |
| Act | Something relevant found, execute the task |
| Escalate | Needs deeper reasoning, hand off to the cloud agent |
The heartbeat uses `tokio::time::sleep` (not `interval`) so ticks never stack up.
### 2. Load due tasks
Query: enabled, not completed, `next_run_at <= now` or never run.
### 3. Log as in_progress
Each due task gets a single log row inserted with `decision = "in_progress"`. This row is updated in place as the task progresses, no duplicate rows.
### 4. Evaluate with local model
The local Ollama model receives all due tasks + a situation report and returns a per-task decision:
| Decision | Meaning |
|----------|---------|
| `noop` | Nothing relevant right now |
| `act` | Something relevant found — execute the task |
| `escalate` | Needs deeper reasoning — hand off to agentic-v1 |
### 5. Execute
Routing depends on the decision and the task's intent:
How that decision gets executed depends on whether the task has **write intent** (it asks the agent to take an action) or is **read-only** (it asks the agent to look and report):
```
Decision: noop
Update log to "noop", advance schedule
Decision: Skip
Log "nothing new", schedule the next run
Decision: act
├─ Task has write intent (needs_tools = true)
│ → Execute with local model
└─ Task is read-only
→ Execute with local model
Decision: Act
→ Execute on the local model (read or write)
Decision: escalate
├─ Task has write intent (needs_tools = true)
│ → Run agentic-v1 with full permissions
│ → No approval needed (user explicitly asked for the write action)
Decision: Escalate
├─ Write-intent task
│ → Run the cloud agent with full permissions
│ → No approval needed (you explicitly asked for the action)
└─ Task is read-only
→ Run agentic-v1 in analysis-only mode
→ If response contains "RECOMMENDED ACTION:" (unsolicited write)
│ → Create escalation for user approval
│ → On approval → run agentic-v1 with full permissions
└─ Read-only task
→ Run the cloud agent in analysis-only mode
→ If the agent surfaces an unsolicited recommended action
│ → Create an escalation card for your approval
│ → On approval → re-run with full permissions
└─ Otherwise → log result, done
```
### 6. Update log entry
Every task evaluation lands in the activity log with a colored dot and a short status:
The same row inserted in step 3 is updated to the final state:
| Decision | Dot color | Text |
|----------|-----------|------|
| `in_progress` | Blue (pulsing) | "Evaluating..." |
| `act` | Green | Result text |
| `noop` | Gray | "Nothing new" |
| `escalate` | Amber | "Waiting for approval" |
| `failed` | Coral | Error message |
| `cancelled` | Gray | "Cancelled" |
| `dismissed` | Gray | "Skipped" |
| State | Color | Text |
| ---------------- | --------------- | ---------------------- |
| In progress | Blue (pulsing) | "Evaluating…" |
| Acted | Green | Result text |
| Skipped | Gray | "Nothing new" |
| Awaiting approval | Amber | "Waiting for approval" |
| Failed | Coral | Error message |
| Cancelled | Gray | "Cancelled" |
| Dismissed | Gray | "Skipped" |
---
## Execution Models
## Two models, one loop
### Local Ollama model
| Stage | Where it runs | Why |
| ------------------------------------- | ------------------------------ | ----------------------------------------------------- |
| Per-task evaluation (every tick) | Local model (Ollama) | Free, no rate limit, fine on-device |
| Text-only execution (summarize, check)| Local model | Same |
| Tool-using execution (send, post, …) | Cloud agent | Tools, larger context, retries on rate-limit |
| Analysis mode for escalated reads | Cloud agent (read-only) | Deeper reasoning when the local model defers |
Used for:
- Task evaluation (all tasks, every tick)
- Text-only task execution (summarize, check, monitor, review)
No cost, no rate limits, runs on-device.
### agentic-v1 (cloud)
Used for:
- Tool-required task execution (send, post, delete, create)
- Analysis-only mode for read-only tasks escalated by the local model
Rate-limit retry: up to 3 attempts with exponential backoff (2s, 4s, 8s) on 429 errors.
The split keeps the loop cheap: you only pay for cloud calls when a task actually needs them.
---
## Approval Gate
## Approval gate
Approval is only required when the AI wants to take a **write action that the user didn't explicitly request**.
Approval is only required when the agent wants to take a **write action that you didn't explicitly ask for**.
| Task intent | AI wants to write | Approval needed? |
|-------------|-------------------|-----------------|
| "Send digest to Slack" (write) | Yes | No — user asked for it |
| "Check urgent emails" (read) | No | No read-only result |
| "Check urgent emails" (read) | Yes (wants to forward them) | **Yes** unsolicited write |
| Task intent | Agent wants to write | Approval needed? |
| -------------------------------- | ------------------------ | -------------------------- |
| "Send digest to Slack" (write) | Yes | No, you asked for it |
| "Check urgent emails" (read) | No | No, read-only result |
| "Check urgent emails" (read) | Yes (forward them) | **Yes**, unsolicited write |
The approval flow:
1. agentic-v1 runs in analysis-only mode
2. Response contains `RECOMMENDED ACTION: Forward 3 urgent emails to #team-alerts`
3. Escalation card appears in UI under "Approval Needed"
4. User clicks "Go ahead" → agentic-v1 runs again with full permissions
5. Or user clicks "Skip" → nothing happens
### Skill-related escalations
1. The cloud agent runs in analysis-only mode.
2. It surfaces a recommendation, e.g. *"forward 3 urgent emails to #team-alerts."*
3. An escalation card appears in the UI under **Approval Needed**.
4. **Go ahead** re-runs with full permissions.
5. **Skip** does nothing.
Escalations related to skills (detected by keywords: skill, oauth, notion, gmail, integration, disconnect, re-auth) show a "Fix in Skills" button that navigates to the Skills page instead of "Go ahead".
Skill-related escalations (broken integration, expired OAuth, missing scope) show a **Fix in Skills** button that takes you straight to the Skills page instead.
---
## Failure Handling
## Failure handling
### Consecutive failure counter
A failure counter tracks consecutive ticks where the whole evaluation step failed (local model down, network out). It resets to zero on any successful tick and shows up in the UI status bar in coral when non-zero.
Tracked in `EngineState.consecutive_failures`. Increments when the entire LLM evaluation fails (Ollama down, network error). Resets to 0 on any successful tick. Surfaced in the UI status bar as "N failed" in coral.
Per-task failures don't trip this counter, the tick itself is still considered successful.
Individual task execution failures do NOT increment this counter, they are logged per-task but the tick itself is considered successful.
### last_tick_at advancement
`last_tick_at` only advances on successful ticks. If the LLM evaluation fails or the tick is cancelled, `last_tick_at` stays unchanged so the next tick's situation report covers the same time range, nothing is missed.
If a tick fails or is cancelled, the engine doesn't advance its "last seen" timestamp, so the next successful tick covers the same window. Nothing in your workspace gets skipped.
---
## Configuration
In `config.toml` under `[heartbeat]`:
The loop is configurable in the desktop app:
```toml
[heartbeat]
enabled = true # Enable the heartbeat loop
interval_minutes = 5 # Tick interval (minimum 5)
inference_enabled = true # Enable local model evaluation
context_budget_tokens = 40000 # Max tokens for situation report
```
Defaults: `enabled = true`, `interval_minutes = 5`, `inference_enabled = true`.
- **Enable / disable.** Turn the entire background loop on or off.
- **Tick interval.** How often a tick fires. Defaults to 5 minutes; that's also the minimum.
- **Inference.** Whether the local model evaluates tasks each tick. Disable this if you'd rather only run things via the manual **Run Now** button.
- **Context budget.** How much of the workspace situation report can be passed in at once. The default is sane; raise it for richer context, lower it for tighter cost.
---
## SQLite Schema
## In the UI
Database: `{workspace_dir}/subconscious/subconscious.db`
Lives under **Intelligence → Subconscious**.
### subconscious_tasks
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT PK | UUID |
| title | TEXT | Task description |
| source | TEXT | `"system"` or `"user"` |
| recurrence | TEXT | `"pending"`, `"once"`, or `"cron:expr"` |
| enabled | INTEGER | 1 = active, 0 = paused |
| last_run_at | REAL | Unix timestamp of last evaluation |
| next_run_at | REAL | Unix timestamp of next scheduled run |
| completed | INTEGER | 1 = done (one-off tasks) |
| created_at | REAL | Unix timestamp |
### subconscious_log
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT PK | UUID |
| task_id | TEXT | FK to tasks |
| tick_at | REAL | Unix timestamp of the tick |
| decision | TEXT | `in_progress`, `act`, `noop`, `escalate`, `failed`, `cancelled`, `dismissed` |
| result | TEXT | Result text or error message |
| duration_ms | INTEGER | Execution duration |
| created_at | REAL | Unix timestamp |
### subconscious_escalations
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT PK | UUID |
| task_id | TEXT | FK to tasks |
| log_id | TEXT | FK to log entry |
| title | TEXT | Escalation title |
| description | TEXT | What needs approval |
| priority | TEXT | `critical`, `important`, `normal` |
| status | TEXT | `pending`, `approved`, `dismissed` |
| created_at | REAL | Unix timestamp |
| resolved_at | REAL | When approved/dismissed |
- **Status bar.** Task count, total ticks, last tick time, failure counter (if any).
- **Active Tasks.** System tasks (read-only, with a "default" badge) and your own tasks (toggle + delete).
- **Approval Needed.** Amber cards for pending escalations. Each has a title, description, and priority. Buttons: **Go ahead**, **Fix in Skills** (when relevant), or **Skip**.
- **Activity Log.** Chronological feed of every task evaluation, colored dot + result. Auto-refreshes while anything is in progress.
- **Run Now.** Manually trigger a tick. Returns immediately; the UI polls for the result.
---
## RPC Endpoints
## See also
All under `openhuman.subconscious_*`:
| Method | Description |
|--------|-------------|
| `subconscious_status` | Get engine status (enabled, ticks, failures) |
| `subconscious_trigger` | Manually trigger a tick (runs in background, returns immediately) |
| `subconscious_tasks_list` | List all tasks |
| `subconscious_tasks_add` | Add a user task |
| `subconscious_tasks_update` | Update task (title, enabled, recurrence) |
| `subconscious_tasks_remove` | Remove a user task (system tasks can only be disabled) |
| `subconscious_log_list` | List activity log entries |
| `subconscious_escalations_list` | List escalations (filterable by status) |
| `subconscious_escalations_approve` | Approve and execute an escalation |
| `subconscious_escalations_dismiss` | Dismiss an escalation |
---
## UI (Intelligence Page → Subconscious Tab)
### Status bar
Shows: task count, total ticks, last tick time, consecutive failures (if > 0).
### Active Tasks
- **System tasks**: displayed as plain text with green dot and "default" badge. No controls.
- **User tasks**: toggle switch (enable/disable) + delete button on hover.
- **Add task**: text input + "Add" button at the bottom.
### Approval Needed
Amber cards for pending escalations. Each shows title, description, priority badge.
- **"Go ahead"**: approve and execute the write action.
- **"Fix in Skills"**: shown for skill-related escalations, navigates to Skills page.
- **"Skip"**: dismiss without executing.
### Activity Log
Chronological list of task evaluations. Each entry shows timestamp, colored dot, and result text. Auto-polls every 2s while any entries are `in_progress`.
### Run Now
Triggers a manual tick. The tick runs in the background, the RPC returns immediately and the UI polls for updates.
- [Memory Tree](obsidian-wiki/memory-tree.md), what the situation report reads from.
- [Auto-fetch from Integrations](integrations/auto-fetch.md), how the workspace stays fresh between ticks.
- [Local AI (optional)](model-routing/local-ai.md), the on-device model that powers evaluation.
+1 -1
View File
@@ -21,7 +21,7 @@ Each rule names a tool/command pattern and a reduction strategy (truncate, dedup
## Why this matters for memory
TokenJuice is what makes [auto-fetch](auto-fetch.md) economically viable. When the Gmail provider syncs a page of 200 messages, TokenJuice compacts each canonicalized email _before_ it enters the model that builds summaries. The same applies to GitHub diffs, Slack channel dumps, and any other firehose source.
TokenJuice is what makes [auto-fetch](integrations/auto-fetch.md) economically viable. When the Gmail provider syncs a page of 200 messages, TokenJuice compacts each canonicalized email _before_ it enters the model that builds summaries. The same applies to GitHub diffs, Slack channel dumps, and any other firehose source.
Concretely: ingesting your last six months of email through a frontier model costs single-digit dollars instead of hundreds.
+1 -1
View File
@@ -50,4 +50,4 @@ This is real, not a demo: see commits `0bc74575` (live note-taking), `f1203479`
## See also
* [Memory Tree](obsidian-wiki/memory-tree.md). where Meet transcripts and notes live.
* [Automatic Model Routing](model-routing.md). Meet's brain uses `hint:fast` for low-latency conversational turns.
* [Automatic Model Routing](model-routing/README.md). Meet's brain uses `hint:fast` for low-latency conversational turns.
+4 -4
View File
@@ -38,7 +38,7 @@ When you first open OpenHuman, you'll be asked to sign in. Multiple sign-in opti
## Connect your first source
OpenHuman works by connecting to your existing tools through [third-party integrations](../features/integrations.md). Each connection expands your [Memory Tree](../features/obsidian-wiki/memory-tree.md). You choose what to connect, and you can revoke access at any time.
OpenHuman works by connecting to your existing tools through [third-party integrations](../features/integrations/README.md). Each connection expands your [Memory Tree](../features/obsidian-wiki/memory-tree.md). You choose what to connect, and you can revoke access at any time.
The 118+ catalog spans Gmail, Notion, GitHub, Slack, Stripe, Calendar, Drive, Linear, Jira, Outlook, Dropbox, Airtable, Salesforce, HubSpot, Figma, Asana, Trello, Telegram, WhatsApp, Discord, Microsoft Teams, Twitter / X, Reddit, Spotify, YouTube, Facebook, Instagram and more.
@@ -49,7 +49,7 @@ Recommended starting points:
* **Notion**. for structured docs and exports.
* **GitHub**. if you write code.
Click **Connect** on any integration, complete the OAuth flow, and the next [auto-fetch](../features/auto-fetch.md) tick will start syncing it within five minutes.
Click **Connect** on any integration, complete the OAuth flow, and the next [auto-fetch](../features/integrations/auto-fetch.md) tick will start syncing it within twenty minutes.
***
@@ -73,7 +73,7 @@ Once a source is connected and auto-fetch has run a tick, try prompts like:
* "Connect what my team discussed in Slack with what I was reviewing in Notion."
* "What did Sarah say about the project across email and chat?"
OpenHuman picks the right model for each task automatically, see [Automatic Model Routing](../features/model-routing.md).
OpenHuman picks the right model for each task automatically, see [Automatic Model Routing](../features/model-routing/README.md).
***
@@ -90,7 +90,7 @@ After your first request, explore what else OpenHuman can do:
* **Skills** extend the assistant's capabilities, fetching data, running scheduled tasks, processing information.
* **Integrations** let you push structured results to Notion, Google Sheets, and other connected tools.
Learn more in [Skills & Integrations](../features/integrations.md).
Learn more in [Skills & Integrations](../features/integrations/README.md).
***
+4 -4
View File
@@ -24,17 +24,17 @@ The same chunks the agent reasons over are written as `.md` files in `<workspace
You can't trust a memory you can't read. The vault is the inverse of the usual "AI memory" black box.
### 3. [third-party integrations](../features/integrations.md) feeding the tree on autopilot
### 3. [third-party integrations](../features/integrations/README.md) feeding the tree on autopilot
OpenHuman ships with **118+ third-party integrations**. Gmail, Notion, GitHub, Slack, Stripe, Calendar, Drive, Linear, Jira, and more. Connecting any of them is a one-click OAuth flow.
Once connected, the [auto-fetch scheduler](../features/auto-fetch.md) ticks every five minutes, pulls fresh data from every active connection, and pipes the results through the same ingest path the manual UI uses. By the time you ask "what landed in my inbox overnight?", the answer is already in the memory tree.
Once connected, the [auto-fetch scheduler](../features/integrations/auto-fetch.md) ticks every twenty minutes, pulls fresh data from every active connection, and pipes the results through the same ingest path the manual UI uses. By the time you ask "what landed in my inbox overnight?", the answer is already in the memory tree.
### 4. An agent with the right tools, the right model, and a budget
When you talk to the agent, four things happen behind the scenes:
* **Model routing**. The model parameter can be a hint (`hint:reasoning`, `hint:fast`, `hint:vision`). The [router](../features/model-routing.md) resolves the hint to the right provider+model. One subscription, many models.
* **Model routing**. The model parameter can be a hint (`hint:reasoning`, `hint:fast`, `hint:vision`). The [router](../features/model-routing/README.md) resolves the hint to the right provider+model. One subscription, many models.
* **Native tools**. A built-in [web search, web-fetch scraper, and full filesystem/git/lint/test/grep coder toolset](../features/native-tools.md) are wired in by default. No "install a plugin to read files" friction.
* **TokenJuice compression**. Verbose tool output (git logs, large emails, build output) is compacted by a [rule overlay](../features/token-compression.md) before it ever enters the model's context. Sweeping through your last six months of email costs single-digit dollars instead of hundreds.
* **Voice, when you want it**. STT in, [ElevenLabs TTS](../features/voice.md) out, with a live Google Meet agent that can listen, take notes, and speak back into the call.
@@ -45,7 +45,7 @@ When you talk to the agent, four things happen behind the scenes:
┌────────────────────────────────────────────────────────────┐
│ Third-party services (118+) │
│ ▲ ▲ │
│ one-click auto-fetch every 5 min │
│ one-click auto-fetch every 20 min │
└──────┼───────────┼─────────────────────────────────────────┘
│ │
▼ ▼
@@ -1,41 +0,0 @@
---
icon: user-lock
---
# Account & Security
#### Billing & Usage
View and manage your subscription, credits, and payment methods. See the Pricing page for plan details.
Your billing dashboard shows: current plan, included monthly value, cycle budget, 5-hour cap, discount percentage, and storage. Below that, your inference budget tracks daily usage, tokens consumed this cycle, 5-hour cap spending, and cycle end date with a progress bar.
**Pay as You Go:** Top up credits in +$5, +$10, or +$25 increments. Redeem coupon codes (XXXX-XXXX format).
**Pay with Crypto:** Toggle for annual crypto payments.
**Auto-Recharge:** Toggle to auto-top-up when balance is low. Requires a saved payment method.
**Payment Methods:** Add a card to enable auto-recharge and plan upgrades.
#### Recovery Phrase
Manage your BIP39 recovery phrase for encryption and wallet access. This phrase is the key to your encrypted data. Store it securely offline. If you lose your recovery phrase, your encrypted data cannot be recovered.
#### Team
Manage your teams, members, and invites.
**Your Teams:** Shows teams with role (Owner/Member), plan tier, and status.
**Create New Team:** Enter a name and click Create.
**Join Existing Team:** Enter an invite code and click Join.
#### Connections
Review and manage linked account connections. Currently showing as Coming Soon: Google (emails, contacts, calendar), Notion (tasks, documents), Web3 Wallet (trading), Crypto Trading Exchanges (trades with deep insights).
Note: Gmail and Notion are available now as 3rd Party Skills in the Skills tab. The Connections page will offer deeper native integrations when they launch.
**Privacy notice:** All data and credentials are stored locally with zero-data retention policy. Your information is encrypted and never shared with third parties.
@@ -1,45 +0,0 @@
---
icon: head-side-circuit
---
# AI & Skills
#### Local AI Model
Choose your model tier based on device capability.
OpenHuman detects your system specs automatically: RAM, CPU cores, and GPU type.
| Tier | Size | RAM | GPU | Model | Best For |
| ----------- | ------ | ------ | ------------------------- | ---------------------- | ------------------------------------ |
| Lightweight | \~1 GB | 4 GB+ | No | gemma3:1b-it-q4\_0 | Older machines, minimal resource use |
| Balanced | \~3 GB | 8 GB+ | No | gemma3:4b-it-qat | Moderate hardware |
| Performance | \~8 GB | 16 GB+ | Yes (Apple Silicon Metal) | gemma3:12b-it-q4\_K\_M | Best quality, recommended |
The active tier is marked "ACTIVE" and the recommended tier is marked "RECOMMENDED." Switching tiers triggers a new model download.
"Show Advanced" expands additional model configuration options.
#### AI Configuration
Configure persona, prompting behavior, and AI runtime settings.
**AI System Overview:** Prompt and markdown orchestration handled in Rust runtime. Shows configuration status (Ready or Fallback Mode) and loading duration.
**Local Model Runtime:** State (ready/loading/error) and target model. "Open Manager" and "Retry Download" buttons.
**SOUL Persona Configuration:** Defines OpenHuman's identity and behavior. Shows identity name (OpenHuman), role (AI assistant), source, and load timestamp. "Refresh SOUL" reloads persona configuration.
**TOOLS Configuration:** Available tools count and active skills count. "Refresh TOOLS" reloads tool definitions.
**Refresh All AI Configuration:** Reloads the entire AI configuration stack.
#### Skills
Configure browser access and installed skill capabilities.
**Browser Access:** Controls whether OpenHuman's browser tool can visit public domains. Private and file URLs are always blocked.
"Restrict to allowlist" limits access to only approved domains. When unchecked, any public domain is accessible.
Shows registered integrations list.
@@ -1,40 +0,0 @@
---
icon: nfc-signal
---
# Automation & Channels
Navigate to **Settings → Automation & Channels**. Configure desktop automation, messaging channels, and the auto-fetch schedule for each connected integration.
#### Accessibility Automation
Desktop permissions and assisted controls.
**Permissions:** Accessibility (GRANTED/DENIED) and Input Monitoring (GRANTED/DENIED). Buttons: Request Accessibility, Open Input Monitoring, Refresh Status.
**Features:** Toggles for Device Control (interact with UI elements) and Predictive Input (provide input predictions).
#### Messaging Channels
Configure the default messaging channel and auth modes.
**Default Messaging Channel:** Choose between Telegram, Discord, or Web. Shows active route status.
**Channel Integrations:** Configure auth modes for Telegram and Discord. Click a channel name to open its configuration page.
#### Auto-fetch & Cron Jobs
OpenHuman runs a global [auto-fetch](../features/auto-fetch.md) tick every five minutes that walks every active connection and pulls fresh data into the [Memory Tree](../features/obsidian-wiki/memory-tree.md). On top of that:
**Core Cron Jobs:** System-level jobs in the OpenHuman core scheduler database.
**Per-integration sync intervals:** Each [integration](../features/integrations.md) declares its own minimum interval between syncs. The defaults are sensible; you can override them here.
| Integration | Default sync interval |
| ----------- | --------------------- |
| Gmail | every 15 minutes |
| Notion | every 20 minutes |
More frequent syncing keeps data fresher but uses more inference budget. [TokenJuice](../features/token-compression.md) keeps the cost bounded even at high frequencies.
Click **Refresh Cron Jobs** to reload the schedule.
+3 -3
View File
@@ -37,13 +37,13 @@ use super::providers::{get_provider, ProviderContext, SyncReason};
/// from per-provider `sync_interval_secs` — this just bounds how long
/// past a provider's interval we might fire.
///
/// 5 min trades a little staleness for noticeably less foreground load:
/// 20 min trades a little staleness for noticeably less foreground load:
/// each tick triggers an HTTP fetch + DB write per due connection, and
/// for users with several connected providers the old 60s cadence kept
/// the laptop visibly busy. Per-provider `sync_interval_secs` still
/// caps the *minimum* delay between actual syncs — this only loosens
/// the upper bound.
const TICK_SECONDS: u64 = 300;
const TICK_SECONDS: u64 = 1200;
/// Process-wide guard so the scheduler is only started once even
/// when both `start_channels` and `bootstrap_skill_runtime` call into
@@ -236,7 +236,7 @@ mod tests {
fn tick_seconds_is_sane_default() {
// Sanity check: don't accidentally ship a 1-second tick.
assert!(TICK_SECONDS >= 30);
assert!(TICK_SECONDS <= 600);
assert!(TICK_SECONDS <= 3600);
}
#[test]