GITBOOK-41: No subject

This commit is contained in:
Steven Enamakel
2026-05-09 06:15:18 +00:00
committed by gitbook-bot
parent 72048814ff
commit 24bf2a5932
17 changed files with 308 additions and 335 deletions
+13 -13
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/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.
[**118+ third-party integrations**](features/integrations.md)**, with** [**auto-fetch**](features/obsidian-wiki/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/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.
**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/) 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,22 +35,22 @@ 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 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.
- It **speaks**, listens, and joins meetings, voice is a first-class surface, not an afterthought.
- It **preserves privacy** by design. The Memory Tree's SQLite database and your Obsidian vault stay on your machine. Integration tokens are held by the OpenHuman backend, not on disk in plaintext on your laptop.
* 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.
* It **speaks**, listens, and joins meetings, voice is a first-class surface, not an afterthought.
* It **preserves privacy** by design. The Memory Tree's SQLite database and your Obsidian vault stay on your machine. Integration tokens are held by the OpenHuman backend, not on disk in plaintext on your laptop.
## Who it's for
OpenHuman is built for people and teams who operate across many conversations and tools, and feel the cost of it.
- **Knowledge workers** who spend their days across 8+ applications and lose context every time they switch.
- **Developers and power users** who want a memory and context layer that actually scales, and that they can audit by opening a folder of Markdown.
- **High-volume communicators** who miss decisions, context, and follow-ups buried in message noise across multiple platforms.
- **Traders and analysts** who need fast signal extraction and risk awareness across information channels.
- **Distributed teams** who make decisions in chat but need structured follow-through in external tools.
* **Knowledge workers** who spend their days across 8+ applications and lose context every time they switch.
* **Developers and power users** who want a memory and context layer that actually scales, and that they can audit by opening a folder of Markdown.
* **High-volume communicators** who miss decisions, context, and follow-ups buried in message noise across multiple platforms.
* **Traders and analysts** who need fast signal extraction and risk awareness across information channels.
* **Distributed teams** who make decisions in chat but need structured follow-through in external tools.
## What OpenHuman does not do
+5 -5
View File
@@ -11,8 +11,8 @@
* [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)
* [Third-party Integrations (118+)](features/integrations/README.md)
* [Auto-fetch from Integrations](features/integrations/auto-fetch.md)
* [Auto-fetch from Integrations](features/obsidian-wiki/auto-fetch.md)
* [Third-party Integrations (118+)](features/integrations.md)
* [Smart Token Compression](features/token-compression.md)
* [Automatic Model Routing](features/model-routing/README.md)
* [Local AI (optional)](features/model-routing/local-ai.md)
@@ -21,7 +21,6 @@
* [Subconscious Loop](features/subconscious.md)
* [Privacy & Security](features/privacy-and-security.md)
* [Platform & Availability](features/platform.md)
* [Architecture](features/architecture.md)
## Developing
@@ -34,8 +33,9 @@
* [Chromium Embedded Framework](developing/cef.md)
* [Coding Harness](developing/coding-harness.md)
* [Agent Observability](developing/agent-observability.md)
* [Frontend (app/src/)](developing/frontend.md)
* [Tauri Shell (app/src-tauri/)](developing/tauri-shell.md)
* [Architecture](developing/architecture/README.md)
* [Frontend (app/src/)](developing/architecture/frontend.md)
* [Tauri Shell (app/src-tauri/)](developing/architecture/tauri-shell.md)
## Legal
+24 -24
View File
@@ -3,26 +3,26 @@ description: Build, run, test, and ship OpenHuman from source.
icon: code-branch
---
# Developing OpenHuman
# Overview
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 |
| ----------- | ----------------------------------------------------------------------------------------------------------- |
| 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.). |
| `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.). |
`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
@@ -30,43 +30,43 @@ If it's your first time pulling the repo:
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.
3. [**Frontend**](architecture/frontend.md) and [**Tauri Shell**](architecture/tauri-shell.md). The React app and the desktop host that wraps it.
---
***
## Testing
OpenHuman ships with three test layers. Know which one your change belongs in:
- [**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.
* [**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.
PRs must clear the **≥ 80% coverage on changed lines** gate. Add tests for new behavior, not just the happy path.
---
***
## 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.
* [**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.
* [**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.
* Open issues and PRs at [tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman).
* PRs target `main`. Push to your fork, not upstream.
* Follow [`CONTRIBUTING.md`](../../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.
@@ -4,7 +4,7 @@ icon: code-branch
# Architecture
OpenHuman is open-sourced under GNU GPL3. This page is the high-level shape of the system; the deep developer architecture lives in [deep architecture reference](../developing/architecture.md) in the repo.
OpenHuman is open-sourced under GNU GPL3. This page is the high-level shape of the system; the deep developer architecture lives in [deep architecture reference](../architecture.md) in the repo.
## The shape
@@ -37,42 +37,42 @@ OpenHuman is a **React + Tauri v2 desktop app** with a **Rust core** that does t
**Where logic lives:**
- **Rust core**. all business logic. Memory Tree, integrations, model routing, tools, voice. Authoritative.
- **Tauri shell**. windowing, process lifecycle, IPC. A delivery vehicle, not where features live.
- **React frontend**. UI and orchestration. Calls into core via JSON-RPC.
* **Rust core**. all business logic. Memory Tree, integrations, model routing, tools, voice. Authoritative.
* **Tauri shell**. windowing, process lifecycle, IPC. A delivery vehicle, not where features live.
* **React frontend**. UI and orchestration. Calls into core via JSON-RPC.
## Data flow
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.
1. **Connect**. OAuth into a [integration](../../features/integrations.md). Backend stores the token; core never sees it in plaintext.
2. **Auto-fetch**. Every twenty minutes the [scheduler](../../features/obsidian-wiki/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/`.
6. **Score**. Background workers run embeddings, entity extraction, hotness scoring.
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/README.md) picks the right provider+model for the task hint.
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/) picks the right provider+model for the task hint.
## Privacy boundary
Stays on your machine:
- The Memory Tree SQLite DB.
- The Obsidian Markdown vault.
- Audio capture buffers and any local model state.
* The Memory Tree SQLite DB.
* The Obsidian Markdown vault.
* Audio capture buffers and any local model state.
Goes through the OpenHuman backend (under one subscription):
- LLM calls (model providers).
- Web search proxy.
- Integration OAuth and tool proxying.
- TTS streaming.
* LLM calls (model providers).
* Web search proxy.
* Integration OAuth and tool proxying.
* TTS streaming.
See [Privacy & Security](../features/privacy-and-security.md) for the full picture.
See [Privacy & Security](../../features/privacy-and-security.md) for the full picture.
## Open source
- **Repo:** [github.com/tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman). GNU GPL3.
- **Issues and PRs** are welcome. The project is in early beta.
- For contributors, the canonical developer guide is [deep architecture reference](../developing/architecture.md).
* **Repo:** [github.com/tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman). GNU GPL3.
* **Issues and PRs** are welcome. The project is in early beta.
* For contributors, the canonical developer guide is [deep architecture reference](../architecture.md).
@@ -1,9 +1,11 @@
---
description: The React + Vite frontend (`app/src/`) — architecture, state, services, providers, routing, components, hooks.
description: >-
The React + Vite frontend (`app/src/`) — architecture, state, services,
providers, routing, components, hooks.
icon: browsers
---
# Frontend (`app/src/`)
# Frontend (app/src/)
The OpenHuman desktop UI: a Vite + React 19 tree under `app/src/` (Yarn workspace `openhuman-app`). It uses Redux Toolkit with persistence for session state, talks to the backend over REST + Socket.io, and calls the Rust core sidecar via JSON-RPC (`coreRpcClient` / Tauri `core_rpc_relay`). Heavy logic lives in the core, not here.
@@ -11,22 +13,22 @@ This is one consolidated reference. Use the table of contents above (or your rea
## Quick reference
| Section | Covers |
| --- | --- |
| [Architecture](#architecture-overview) | Provider chain, build, layout, conventions |
| [State Management](#state-management) | Redux Toolkit slices, selectors, persistence |
| [Services Layer](#services-layer) | `apiClient`, `socketService`, `coreRpcClient` |
| [Providers](#providers) | `User`, `Socket`, `AI`, `Skill` providers |
| [Pages & Routing](#pages-routing) | `HashRouter`, route guards, main routes |
| [Components](#components) | UI / settings component patterns |
| [Hooks & Utilities](#hooks-utilities) | Shared hooks, helpers, config |
| Section | Covers |
| ------------------------------------------------- | --------------------------------------------- |
| [Architecture](frontend.md#architecture-overview) | Provider chain, build, layout, conventions |
| [State Management](frontend.md#state-management) | Redux Toolkit slices, selectors, persistence |
| [Services Layer](frontend.md#services-layer) | `apiClient`, `socketService`, `coreRpcClient` |
| [Providers](frontend.md#providers) | `User`, `Socket`, `AI`, `Skill` providers |
| [Pages & Routing](frontend.md#pages-routing) | `HashRouter`, route guards, main routes |
| [Components](frontend.md#components) | UI / settings component patterns |
| [Hooks & Utilities](frontend.md#hooks-utilities) | Shared hooks, helpers, config |
## Scale
| Metric | Value |
| --- | --- |
| TypeScript / TSX files under `app/src/` | ~285 (`find app/src -name '*.ts' -o -name '*.tsx' \| wc -l` to refresh) |
| Test runner | Vitest (`app/test/vitest.config.ts`) |
| Metric | Value |
| --------------------------------------- | ------------------------------------------------------------------------ |
| TypeScript / TSX files under `app/src/` | \~285 (`find app/src -name '*.ts' -o -name '*.tsx' \| wc -l` to refresh) |
| Test runner | Vitest (`app/test/vitest.config.ts`) |
## Directory layout
@@ -46,18 +48,17 @@ app/src/
└── assets/ # Icons and static assets
```
## Architecture overview
### System architecture
OpenHumans desktop UI is a **React 19** app (`app/src/`) that:
- Uses **Redux Toolkit** with persistence for session-related state
- Connects to the backend with **REST** (`apiClient`) and **Socket.io** (`socketService`)
- Calls the **Rust core** process over HTTP via **`coreRpcClient`** / Tauri **`core_rpc_relay`** (JSON-RPC methods implemented in repo root `src/openhuman/`, exposed through `core_server`)
- Loads **AI prompts** from bundled `src/openhuman/agent/prompts` (repo root) and from Tauri **`ai_get_config`** when packaged
- Uses a **minimal MCP-style** helper layer under `lib/mcp/` (transport, validation), not a large in-repo Telegram MCP tool bundle
* Uses **Redux Toolkit** with persistence for session-related state
* Connects to the backend with **REST** (`apiClient`) and **Socket.io** (`socketService`)
* Calls the **Rust core** process over HTTP via **`coreRpcClient`** / Tauri **`core_rpc_relay`** (JSON-RPC methods implemented in repo root `src/openhuman/`, exposed through `core_server`)
* Loads **AI prompts** from bundled `src/openhuman/agent/prompts` (repo root) and from Tauri **`ai_get_config`** when packaged
* Uses a **minimal MCP-style** helper layer under `lib/mcp/` (transport, validation), not a large in-repo Telegram MCP tool bundle
### Entry points
@@ -115,33 +116,21 @@ services/
#### Runtime config precedence
The desktop app does not bake the core RPC URL or the API host into the
bundle as a hard requirement. At runtime the app resolves them in this order
(highest first):
The desktop app does not bake the core RPC URL or the API host into the bundle as a hard requirement. At runtime the app resolves them in this order (highest first):
1. **Login-screen RPC URL field**, saved via `utils/configPersistence` and
restored on next launch. End users configure the sidecar address here, not
by hand-editing `config.toml` or `.env` files.
2. **Tauri `core_rpc_url` command**, the port the bundled sidecar is
listening on for this process.
1. **Login-screen RPC URL field**, saved via `utils/configPersistence` and restored on next launch. End users configure the sidecar address here, not by hand-editing `config.toml` or `.env` files.
2. **Tauri `core_rpc_url` command**, the port the bundled sidecar is listening on for this process.
3. **`VITE_OPENHUMAN_CORE_RPC_URL`**, build-time fallback for development.
4. The hardcoded `http://127.0.0.1:7788/rpc` default.
Once the RPC handshake succeeds, `services/backendUrl` calls
`openhuman.config_resolve_api_url` to pull `api_url` (and other safe client
fields) from the loaded core `Config`. `VITE_BACKEND_URL` is only used as a
web fallback when the app runs outside Tauri.
Once the RPC handshake succeeds, `services/backendUrl` calls `openhuman.config_resolve_api_url` to pull `api_url` (and other safe client fields) from the loaded core `Config`. `VITE_BACKEND_URL` is only used as a web fallback when the app runs outside Tauri.
Components that need the backend URL should call `useBackendUrl()` (or
`getBackendUrl()` from non-React code), they must not import the static
`BACKEND_URL` constant from `utils/config`, which represents the build-time
value only.
Components that need the backend URL should call `useBackendUrl()` (or `getBackendUrl()` from non-React code), they must not import the static `BACKEND_URL` constant from `utils/config`, which represents the build-time value only.
### Related docs
- Rust architecture: [Architecture](architecture.md)
- Tauri shell: [Tauri Shell](tauri-shell.md)
* Rust architecture: [Architecture](../architecture.md)
* Tauri shell: [Tauri Shell](tauri-shell.md)
## State Management
@@ -202,14 +191,14 @@ interface AuthState {
**Actions:**
- `setToken(token: string)` - Store JWT after login
- `clearToken()` - Remove token on logout
- `setOnboarded({ userId, isOnboarded })` - Mark user as onboarded
* `setToken(token: string)` - Store JWT after login
* `clearToken()` - Remove token on logout
* `setOnboarded({ userId, isOnboarded })` - Mark user as onboarded
**Selectors (`store/authSelectors.ts`):**
- `selectToken` - Get current JWT
- `selectIsOnboarded(userId)` - Check if user completed onboarding
* `selectToken` - Get current JWT
* `selectIsOnboarded(userId)` - Check if user completed onboarding
#### Socket Slice (`store/socketSlice.ts`)
@@ -228,14 +217,14 @@ interface SocketState {
**Actions:**
- `setSocketStatus({ userId, status })` - Update connection status
- `setSocketId({ userId, socketId })` - Store socket ID
- `clearSocketState(userId)` - Clear user's socket state
* `setSocketStatus({ userId, status })` - Update connection status
* `setSocketId({ userId, socketId })` - Store socket ID
* `clearSocketState(userId)` - Clear user's socket state
**Selectors (`store/socketSelectors.ts`):**
- `selectSocketStatus(userId)` - Get connection status
- `selectIsSocketConnected(userId)` - Boolean connected check
* `selectSocketStatus(userId)` - Get connection status
* `selectIsSocketConnected(userId)` - Boolean connected check
#### User Slice (`store/userSlice.ts`)
@@ -253,10 +242,10 @@ interface UserState {
**Actions:**
- `setUser(user)` - Store user profile
- `setUserLoading(loading)` - Set loading state
- `setUserError(error)` - Set error state
- `clearUser()` - Clear profile on logout
* `setUser(user)` - Store user profile
* `setUserLoading(loading)` - Set loading state
* `setUserError(error)` - Set error state
* `clearUser()` - Clear profile on logout
#### Telegram Slice (`store/telegram/`)
@@ -264,11 +253,11 @@ Complex nested state management for Telegram integration.
**Files:**
- `index.ts` - Slice exports (actions, thunks)
- `types.ts` - Entity and state interfaces
- `reducers.ts` - Synchronous reducers
- `extraReducers.ts` - Async thunk handlers
- `thunks.ts` - Async operations
* `index.ts` - Slice exports (actions, thunks)
* `types.ts` - Entity and state interfaces
* `reducers.ts` - Synchronous reducers
* `extraReducers.ts` - Async thunk handlers
* `thunks.ts` - Async operations
**State Structure:**
@@ -287,29 +276,29 @@ telegram.byUser[telegramUserId] = {
**Reducers:**
- `setCurrentUser` - Store authenticated Telegram user
- `setSessionString` - Store MTProto session (for persistence)
- `setConnectionStatus` - Update connection state
- `setAuthStatus` - Update authentication state
- `addChat` / `updateChat` - Manage chat list
- `addMessage` / `updateMessage` - Manage message history
- `setThreads` - Store thread data
* `setCurrentUser` - Store authenticated Telegram user
* `setSessionString` - Store MTProto session (for persistence)
* `setConnectionStatus` - Update connection state
* `setAuthStatus` - Update authentication state
* `addChat` / `updateChat` - Manage chat list
* `addMessage` / `updateMessage` - Manage message history
* `setThreads` - Store thread data
**Thunks (`store/telegram/thunks.ts`):**
- `initializeTelegram(userId)` - Initialize MTProto client
- `connectTelegram(userId)` - Establish Telegram connection
- `fetchChats(userId)` - Load chat list
- `fetchMessages({ userId, chatId })` - Load message history
- `disconnectTelegram(userId)` - Clean disconnect
* `initializeTelegram(userId)` - Initialize MTProto client
* `connectTelegram(userId)` - Establish Telegram connection
* `fetchChats(userId)` - Load chat list
* `fetchMessages({ userId, chatId })` - Load message history
* `disconnectTelegram(userId)` - Clean disconnect
**Selectors (`store/telegramSelectors.ts`):**
- `selectTelegramState(userId)` - Get full Telegram state
- `selectTelegramConnectionStatus(userId)` - Get connection status
- `selectTelegramAuthStatus(userId)` - Get auth status
- `selectTelegramChats(userId)` - Get chat list
- `selectTelegramMessages(userId, chatId)` - Get messages for chat
* `selectTelegramState(userId)` - Get full Telegram state
* `selectTelegramConnectionStatus(userId)` - Get connection status
* `selectTelegramAuthStatus(userId)` - Get auth status
* `selectTelegramChats(userId)` - Get chat list
* `selectTelegramMessages(userId, chatId)` - Get messages for chat
### Typed Hooks
@@ -325,15 +314,15 @@ export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
#### What's Persisted
- `auth.token` - JWT for authentication
- `auth.isOnboardedByUser` - Per-user onboarding status
- `telegram.byUser` - Telegram state (sessions, chats, etc.)
* `auth.token` - JWT for authentication
* `auth.isOnboardedByUser` - Per-user onboarding status
* `telegram.byUser` - Telegram state (sessions, chats, etc.)
#### What's NOT Persisted
- `socket` - Connection state (reconnects on app start)
- `user.loading` / `user.error` - Transient UI states
- Telegram loading/error states
* `socket` - Connection state (reconnects on app start)
* `user.loading` / `user.error` - Transient UI states
* Telegram loading/error states
#### Storage Backend
@@ -396,9 +385,7 @@ function MyComponent({ userId }) {
4. **Per-user state scoping** - Key state by user ID
5. **Avoid localStorage** - Use Redux-Persist instead
---
***
## Services Layer
@@ -425,10 +412,10 @@ HTTP REST client for backend communication.
#### Features
- Fetch-based implementation
- Auto-injects JWT from Redux store
- Typed request/response handling
- Error handling with typed errors
* Fetch-based implementation
* Auto-injects JWT from Redux store
* Typed request/response handling
* Error handling with typed errors
#### Usage
@@ -501,10 +488,10 @@ Socket.io client singleton for real-time communication.
#### Features
- Singleton pattern - single connection per app
- Auth token passed in socket `auth` object
- Transports: polling first, then WebSocket upgrade
- Auto-reconnection handling
* Singleton pattern - single connection per app
* Auth token passed in socket `auth` object
* Transports: polling first, then WebSocket upgrade
* Auto-reconnection handling
#### API
@@ -618,9 +605,7 @@ These wrap user profile loading, AI/memory client coordination, and skills catal
4. **Handle errors gracefully** - Retry for transient failures
5. **Pass auth via proper channels** - Socket auth object, not query string
---
***
## Providers
@@ -666,9 +651,9 @@ Manages realtime connectivity: **web** uses the JS Socket.io client; **Tauri** b
#### Responsibilities
- Connect when `auth.token` is available; disconnect when cleared
- In Tauri: install listeners once, connect Rust socket, coordinate daemon lifecycle (`useDaemonLifecycle`)
- Update Redux socket slice / connection status
* Connect when `auth.token` is available; disconnect when cleared
* In Tauri: install listeners once, connect Rust socket, coordinate daemon lifecycle (`useDaemonLifecycle`)
* Update Redux socket slice / connection status
#### Implementation
@@ -715,8 +700,8 @@ Minimal user context provider (most user state is in Redux).
#### Responsibilities
- Legacy user context for compatibility
- May be deprecated in favor of Redux
* Legacy user context for compatibility
* May be deprecated in favor of Redux
#### Implementation
@@ -810,8 +795,8 @@ useEffect(() => {
Example:
- `SocketContext` provides `socket` instance and `emit` method
- Redux stores `socketStatus` and `socketId`
* `SocketContext` provides `socket` instance and `emit` method
* Redux stores `socketStatus` and `socketId`
### Testing Providers
@@ -856,9 +841,7 @@ test('SocketProvider connects when token is available', () => {
});
```
---
***
## Pages & Routing
@@ -998,9 +981,9 @@ Landing page for unauthenticated users.
**Features:**
- App introduction and branding
- CTA to login/signup
- Public route (redirects if authenticated)
* App introduction and branding
* CTA to login/signup
* Public route (redirects if authenticated)
#### Login Page (`pages/Login.tsx`)
@@ -1008,9 +991,9 @@ Authentication page.
**Features:**
- Telegram OAuth button
- Opens `/auth/telegram?platform=desktop` in browser
- Handles deep link callback
* Telegram OAuth button
* Opens `/auth/telegram?platform=desktop` in browser
* Handles deep link callback
```typescript
export function Login() {
@@ -1033,10 +1016,10 @@ Main dashboard after authentication.
**Features:**
- Protected route (requires auth + onboarded)
- Connection status indicators
- Navigation to settings modal
- Future: Chat list, messages, etc.
* Protected route (requires auth + onboarded)
* Connection status indicators
* Navigation to settings modal
* Future: Chat list, messages, etc.
```typescript
export function Home() {
@@ -1280,9 +1263,7 @@ const location = useLocation();
const { itemId } = location.state;
```
---
***
## Components
@@ -1437,10 +1418,10 @@ const [showModal, setShowModal] = useState(false);
**Features:**
- QR code login flow
- Phone number login flow
- Connection status display
- Error handling
* QR code login flow
* Phone number login flow
* Connection status display
* Error handling
#### GmailConnectionIndicator
@@ -1636,7 +1617,7 @@ export function ConnectionsPanel() {
#### Settings Hooks
##### useSettingsNavigation
**useSettingsNavigation**
URL-based navigation for settings modal.
@@ -1660,7 +1641,7 @@ navigateBack(); // → /settings
closeModal(); // → previous non-settings route
```
##### useSettingsAnimation
**useSettingsAnimation**
Animation state management.
@@ -1680,7 +1661,7 @@ const { animationClass } = useSettingsAnimation();
#### Settings Components
##### SettingsHeader
**SettingsHeader**
User profile section at top of settings.
@@ -1693,7 +1674,7 @@ interface SettingsHeaderProps {
<SettingsHeader user={user} onClose={handleClose} />
```
##### SettingsMenuItem
**SettingsMenuItem**
Individual menu item with icon and chevron.
@@ -1714,7 +1695,7 @@ interface SettingsMenuItemProps {
/>
```
##### SettingsBackButton
**SettingsBackButton**
Back navigation button.
@@ -1726,7 +1707,7 @@ interface SettingsBackButtonProps {
<SettingsBackButton onClick={navigateBack} />
```
##### SettingsPanelLayout
**SettingsPanelLayout**
Wrapper for settings panels.
@@ -1794,9 +1775,7 @@ const [isOpen, setIsOpen] = useState(false);
/>
```
---
***
## Hooks & Utilities
@@ -1904,7 +1883,7 @@ function ProfileHeader() {
#### Settings Modal Hooks
##### useSettingsNavigation (`components/settings/hooks/useSettingsNavigation.ts`)
**useSettingsNavigation (`components/settings/hooks/useSettingsNavigation.ts`)**
URL-based navigation for settings modal.
@@ -1937,7 +1916,7 @@ function SettingsMenu() {
}
```
##### useSettingsAnimation (`components/settings/hooks/useSettingsAnimation.ts`)
**useSettingsAnimation (`components/settings/hooks/useSettingsAnimation.ts`)**
Animation state management for settings modal.
@@ -1967,9 +1946,7 @@ function SettingsModal() {
#### Configuration (`utils/config.ts`)
Build-time environment variable access. These constants only carry the value
that was baked into the bundle, for the **runtime** URL the app actually
talks to, see `services/backendUrl` and `hooks/useBackendUrl` below.
Build-time environment variable access. These constants only carry the value that was baked into the bundle, for the **runtime** URL the app actually talks to, see `services/backendUrl` and `hooks/useBackendUrl` below.
```typescript
// Build-time fallback only (used outside Tauri).
@@ -1989,9 +1966,7 @@ if (DEBUG) {
}
```
> **Do not** import `BACKEND_URL` directly to make API calls. Resolve the URL
> at runtime so the core sidecar's `api_url` (set on the login screen via
> `openhuman.config_resolve_api_url`) takes effect:
> **Do not** import `BACKEND_URL` directly to make API calls. Resolve the URL at runtime so the core sidecar's `api_url` (set on the login screen via `openhuman.config_resolve_api_url`) takes effect:
>
> ```typescript
> // React components
@@ -2296,6 +2271,4 @@ const user = await apiClient.get<User>('/users/me');
// user is typed as User
```
---
***
@@ -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 twenty minutes.
2. As a **memory source**, [auto-fetch](obsidian-wiki/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 20-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](obsidian-wiki/auto-fetch.md) on the next 20-minute tick.
Each integration shows its current status:
@@ -50,7 +50,7 @@ You can revoke any connection at any time from the Skills tab.
## Messaging channels
Three integrations are special. OpenHuman uses them to *talk back* to you, not just read from them:
Three integrations are special. OpenHuman uses them to _talk back_ to you, not just read from them:
* **Telegram**. the primary messaging channel. Two-way: send and receive messages, manage chats, search history, create groups, 80+ actions on your behalf. All actions run through your own encrypted credentials.
* **Discord**. send and receive messages via Discord. Connect your account to receive OpenHuman messages there.
@@ -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)
* [Auto-fetch from Integrations](obsidian-wiki/auto-fetch.md)
* [Memory Tree](obsidian-wiki/memory-tree.md)
+23 -23
View File
@@ -1,7 +1,7 @@
---
description: >-
Built-in web search, web-fetch scraper, and a full filesystem / git / lint /
test / grep coder toolset. No "install a plugin" friction.
Built-in web search, web-fetch scraper, and a full filesystem / git / lint /
test / grep coder toolset. No "install a plugin" friction.
icon: toolbox
---
@@ -23,9 +23,9 @@ Use it for: research, "what's the latest on X", citation hunting.
A purpose-built "GET-and-read" tool, separate from generic `http_request` / `curl`:
- Caps response at 1 MB.
- 20-second timeout.
- Strips boilerplate; returns clean text the agent can reason over.
* Caps response at 1 MB.
* 20-second timeout.
* Strips boilerplate; returns clean text the agent can reason over.
Use it for: reading articles, blog posts, docs pages, GitHub READMEs without the noise.
@@ -35,30 +35,30 @@ Use it for: reading articles, blog posts, docs pages, GitHub READMEs without the
A complete toolset for working on real codebases:
| Tool | What it does |
| --- | --- |
| `file_read` | Read a file (with line numbers, like `cat -n`). |
| `file_write` | Write a new file. |
| `edit_file` | Targeted edits — match-and-replace with strict uniqueness checks. |
| `apply_patch` | Apply a unified diff. |
| `glob_search` | Find files by glob pattern. |
| `grep` | Ripgrep-style search across the tree. |
| `git_operations` | Status, diff, log, blame, branch, commit. |
| `run_linter` | Run the project's linter. |
| `run_tests` | Run the project's test command. |
| Tool | What it does |
| ---------------- | ----------------------------------------------------------------- |
| `file_read` | Read a file (with line numbers, like `cat -n`). |
| `file_write` | Write a new file. |
| `edit_file` | Targeted edits — match-and-replace with strict uniqueness checks. |
| `apply_patch` | Apply a unified diff. |
| `glob_search` | Find files by glob pattern. |
| `grep` | Ripgrep-style search across the tree. |
| `git_operations` | Status, diff, log, blame, branch, commit. |
| `run_linter` | Run the project's linter. |
| `run_tests` | Run the project's test command. |
Together this is what makes OpenHuman a viable coding partner instead of a chat window that *pretends* to know the codebase.
Together this is what makes OpenHuman a viable coding partner instead of a chat window that _pretends_ to know the codebase.
## Why ship them natively
A plugin-only model means tools live in different processes, behind RPC, with their own auth and packaging stories. That's fine for open-ended extensibility, but for the **core** tools every agent needs (read a file, search the web, edit code), shipping them in-process means:
- Consistent error handling.
- Zero install friction.
- All output passes through [TokenJuice](token-compression.md) for free.
- Predictable security boundary (filesystem tools respect workspace scoping).
* Consistent error handling.
* Zero install friction.
* All output passes through [TokenJuice](token-compression.md) for free.
* Predictable security boundary (filesystem tools respect workspace scoping).
## See also
- [Smart Token Compression](token-compression.md). what keeps tool output costs bounded.
- [Third-party Integrations](integrations/README.md). for the long tail of third-party services.
* [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.
+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](../integrations/auto-fetch.md). how the vault grows on its own.
* [Auto-fetch from Integrations](auto-fetch.md). how the vault grows on its own.
@@ -7,11 +7,11 @@ 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](memory-tree.md).
## How it works
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)`.
A single periodic scheduler ticks every twenty 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)`.
```
┌──────────────────────────────────────────────────────────┐
@@ -43,7 +43,7 @@ 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](memory-tree.md).
## Why a 20-minute tick
@@ -57,6 +57,6 @@ The original design ran at 60 seconds. With several connected providers, that me
## See also
* [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.
* [Third-party Integrations](../integrations.md). the connector layer auto-fetch runs on top of.
* [Memory Tree](memory-tree.md). where everything ends up.
* [Smart Token Compression](../token-compression.md). what keeps "fetch everything" cheap.
+10 -12
View File
@@ -13,8 +13,6 @@ The Memory Tree is OpenHuman's knowledge base. It is not a vector database with
Every source you connect feeds the same pipeline:
```
source adapters (chat / email / document)
@@ -75,7 +73,7 @@ Trees give you compression _and_ navigation. Embeddings still live inside (in `s
## Triggering ingest
* **Automatic**. every active integration is auto-fetched every twenty minutes; see [Auto-fetch](../integrations/auto-fetch.md).
* **Automatic**. every active integration is auto-fetched every twenty minutes; see [Auto-fetch](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.
@@ -87,13 +85,13 @@ Open it from the bottom navigation bar.
**Memory metrics:**
| Metric | What it shows |
| --- | --- |
| **Storage** | Total size of `<workspace>/memory_tree/chunks.db` and the Obsidian vault. |
| **Sources** | How many distinct sources have been ingested (one per Gmail label, Slack channel, document, etc.). |
| **Chunks** | Total ≤3k-token chunks in the store. |
| **Topics** | Number of topic trees materialized so far (per-entity summaries built from "hot" entities). |
| **First / latest memory** | Timestamps of the oldest and newest chunks. |
| Metric | What it shows |
| ------------------------- | -------------------------------------------------------------------------------------------------- |
| **Storage** | Total size of `<workspace>/memory_tree/chunks.db` and the Obsidian vault. |
| **Sources** | How many distinct sources have been ingested (one per Gmail label, Slack channel, document, etc.). |
| **Chunks** | Total ≤3k-token chunks in the store. |
| **Topics** | Number of topic trees materialized so far (per-entity summaries built from "hot" entities). |
| **First / latest memory** | Timestamps of the oldest and newest chunks. |
**Memory graph.** A force-directed visualization of entities and their relationships, drawn from the entity index. The graph grows as auto-fetch pulls more data, sparse early on, denser within a few days.
@@ -103,12 +101,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/README.md).
**Routing.** The Intelligence tab also surfaces which model the agent is using per task, see [Automatic Model Routing](../model-routing/).
## See also
* [Obsidian Wiki](./). open the vault in Obsidian and edit it directly.
* [Auto-fetch from Integrations](../integrations/auto-fetch.md). how the tree stays fresh.
* [Auto-fetch from Integrations](auto-fetch.md). how the tree stays fresh.
* [Smart Token Compression](../token-compression.md). what makes ingesting "everything" cheap.
* [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.
+2 -2
View File
@@ -49,7 +49,7 @@ OpenHuman is built as a native application rather than a web wrapper for three r
└──────────────────────────────────────────────────┘
```
The shell is a delivery vehicle (windowing, process lifecycle, IPC). All product logic lives in the Rust core. The React frontend talks to the core over JSON-RPC. See [Architecture](architecture.md) for the full picture.
The shell is a delivery vehicle (windowing, process lifecycle, IPC). All product logic lives in the Rust core. The React frontend talks to the core over JSON-RPC. See [Architecture](../developing/architecture/) for the full picture.
***
@@ -61,7 +61,7 @@ The desktop app maintains a persistent connection to the OpenHuman backend. Resp
## Offline behavior
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.
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](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 20-minute tick picks up where it left off.
+18 -18
View File
@@ -18,27 +18,27 @@ 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/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.
**Optional** [**Local AI**](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.
***
## What stays on your machine
| | |
| --- | --- |
| **Memory Tree SQLite database** | Local — `<workspace>/memory_tree/chunks.db`. |
| **Obsidian Markdown vault** | Local — `<workspace>/wiki/`. Yours to read, edit, copy, delete. |
| **Audio capture buffers** | Local. Discarded after STT. |
| **Local model state** | Local. |
| | |
| ------------------------------- | --------------------------------------------------------------- |
| **Memory Tree SQLite database** | Local — `<workspace>/memory_tree/chunks.db`. |
| **Obsidian Markdown vault** | Local — `<workspace>/wiki/`. Yours to read, edit, copy, delete. |
| **Audio capture buffers** | Local. Discarded after STT. |
| **Local model state** | Local. |
## What the OpenHuman backend handles
| | |
| --- | --- |
| **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/README.md). |
| **TTS streaming** | [ElevenLabs](../features/voice.md) audio streams. Audio is generated and discarded — not retained. |
| | |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **LLM calls** | Proxied through the backend under one subscription, then forwarded to the underlying provider (Anthropic / OpenAI / Google / etc.) per the [model router](model-routing/). |
| **Web search proxy** | The native [web search tool](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](integrations.md). |
| **TTS streaming** | [ElevenLabs](voice.md) audio streams. Audio is generated and discarded — not retained. |
***
@@ -46,11 +46,11 @@ 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/integrations/auto-fetch.md) does run continuously while a connection is active, that is the whole point. But it is bound by:
[Auto-fetch](obsidian-wiki/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).
- A **daily budget** per connection that caps API usage.
* The **OAuth scope** you granted that integration.
* A **per-provider sync interval** (e.g. Gmail every 15 min by default).
* A **daily budget** per connection that caps API usage.
If you revoke a connection, the next tick stops syncing it; chunks already in your local Memory Tree remain there because they're yours.
@@ -72,7 +72,7 @@ Compression and locality together become the privacy architecture.
**Sandboxed skills.** Each skill runs in its own isolated execution environment with enforced memory and resource limits. Skills cannot access each other's data, the host system's file system, or your credentials.
**Workspace-scoped tools.** The native [filesystem tools](../features/native-tools.md) operate within the workspace the user opens; they do not have ambient access to the rest of the disk.
**Workspace-scoped tools.** The native [filesystem tools](native-tools.md) operate within the workspace the user opens; they do not have ambient access to the rest of the disk.
**Short-lived tokens.** Authentication tokens between the app and the backend are time-limited.
+55 -53
View File
@@ -1,5 +1,7 @@
---
description: Background loop that evaluates user / system tasks against the workspace and decides what to do.
description: >-
Background loop that evaluates user / system tasks against the workspace and
decides what to do.
icon: loader
---
@@ -9,7 +11,7 @@ A background task evaluation and execution system. On a periodic tick, it loads
Think of it as the agent's idle thread: the part that keeps thinking after you've stopped typing.
---
***
## How a tick works
@@ -39,7 +41,7 @@ Think of it as the agent's idle thread: the part that keeps thinking after you'v
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
@@ -47,9 +49,9 @@ Each tick is independent. If a tick is still running when the next one starts (s
Seeded automatically when the engine starts. Cannot be deleted, only disabled. The defaults cover things you'd want any assistant watching for:
- Check connected skills for errors or disconnections
- Review new memory updates for actionable items
- Monitor system health (local model, memory, connections)
* Check connected skills for errors or disconnections
* Review new memory updates for actionable items
* Monitor system health (local model, memory, connections)
You can extend the system task set by listing additional ones in a `HEARTBEAT.md` file in your workspace, one task per line.
@@ -57,21 +59,21 @@ You can extend the system task set by listing additional ones in a `HEARTBEAT.md
Anything you add manually from the UI. Toggle on/off, edit, delete. Examples:
- "Check urgent emails" (read-only)
- "Send daily summary to Slack" (write intent)
- "Summarize Notion updates" (read-only)
* "Check urgent emails" (read-only)
* "Send daily summary to Slack" (write intent)
* "Summarize Notion updates" (read-only)
---
***
## Decisions
For every due task, the local model returns one of three decisions:
| Decision | Meaning |
| ----------- | ---------------------------------------------------- |
| Skip | Nothing relevant right now |
| Act | Something relevant found, execute the task |
| Escalate | Needs deeper reasoning, hand off to the cloud agent |
| Decision | Meaning |
| -------- | --------------------------------------------------- |
| Skip | Nothing relevant right now |
| Act | Something relevant found, execute the task |
| Escalate | Needs deeper reasoning, hand off to the cloud agent |
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):
@@ -97,52 +99,52 @@ Decision: Escalate
Every task evaluation lands in the activity log with a colored dot and a short status:
| State | Color | Text |
| ---------------- | --------------- | ---------------------- |
| In progress | Blue (pulsing) | "Evaluating…" |
| Acted | Green | Result text |
| Skipped | Gray | "Nothing new" |
| 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" |
| Failed | Coral | Error message |
| Cancelled | Gray | "Cancelled" |
| Dismissed | Gray | "Skipped" |
---
***
## Two models, one loop
| 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 |
| 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 |
The split keeps the loop cheap: you only pay for cloud calls when a task actually needs them.
---
***
## Approval gate
Approval is only required when the agent wants to take a **write action that you didn't explicitly ask for**.
| 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 |
| 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. The cloud agent runs in analysis-only mode.
2. It surfaces a recommendation, e.g. *"forward 3 urgent emails to #team-alerts."*
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.
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
@@ -152,33 +154,33 @@ Per-task failures don't trip this counter, the tick itself is still considered s
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
The loop is configurable in the desktop app:
- **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.
* **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.
---
***
## In the UI
Lives under **Intelligence → Subconscious**.
- **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.
* **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.
---
***
## See also
- [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.
* [Memory Tree](obsidian-wiki/memory-tree.md), what the situation report reads from.
* [Auto-fetch from Integrations](obsidian-wiki/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](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.
TokenJuice is what makes [auto-fetch](obsidian-wiki/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.
+5 -5
View File
@@ -4,7 +4,7 @@ icon: play
# Getting Started
This page walks you through setting up OpenHuman and running your first request.
This page walks you through setting up OpenHuman and running your first request.
OpenHuman is open source under the GNU GPL3 license. The codebase is at [github.com/tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman).
@@ -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/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.
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.
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/integrations/auto-fetch.md) tick will start syncing it within twenty minutes.
Click **Connect** on any integration, complete the OAuth flow, and the next [auto-fetch](../features/obsidian-wiki/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/README.md).
OpenHuman picks the right model for each task automatically, see [Automatic Model Routing](../features/model-routing/).
***
@@ -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/README.md).
Learn more in [Skills & Integrations](../features/integrations.md).
***
+3 -3
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/README.md) feeding the tree on autopilot
### 3. [third-party integrations](../features/integrations.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/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.
Once connected, the [auto-fetch scheduler](../features/obsidian-wiki/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/README.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/) 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.