diff --git a/.husky/pre-push b/.husky/pre-push index 7a0e8555e..a6a469a48 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -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() { diff --git a/README.md b/README.md index 6dc43899f..f9581bed2 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Latest Release

-> **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. + +

+ The Tet +

+ +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 evolve—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. +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 | diff --git a/gitbooks/.gitbook/assets/2. How It Works@2x.png b/gitbooks/.gitbook/assets/2. How It Works@2x.png deleted file mode 100644 index a264ee241..000000000 Binary files a/gitbooks/.gitbook/assets/2. How It Works@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/25. Distributed Teams@2x.png b/gitbooks/.gitbook/assets/25. Distributed Teams@2x.png deleted file mode 100644 index 1e8c1608f..000000000 Binary files a/gitbooks/.gitbook/assets/25. Distributed Teams@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/6. Inline Autocomplete@2x.png b/gitbooks/.gitbook/assets/6. Inline Autocomplete@2x.png deleted file mode 100644 index c6fec243b..000000000 Binary files a/gitbooks/.gitbook/assets/6. Inline Autocomplete@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/9. Skills & Integrations@2x.png b/gitbooks/.gitbook/assets/9. Skills & Integrations@2x.png deleted file mode 100644 index 04a152483..000000000 Binary files a/gitbooks/.gitbook/assets/9. Skills & Integrations@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V02 — Two Innovations@2x.png b/gitbooks/.gitbook/assets/V02 — Two Innovations@2x.png deleted file mode 100644 index 314bd0adc..000000000 Binary files a/gitbooks/.gitbook/assets/V02 — Two Innovations@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V04_The_ANI_Problem@2x.png b/gitbooks/.gitbook/assets/V04_The_ANI_Problem@2x.png deleted file mode 100644 index 22b8e5f42..000000000 Binary files a/gitbooks/.gitbook/assets/V04_The_ANI_Problem@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V05 — Performance Benchmarks@2x (1).png b/gitbooks/.gitbook/assets/V05 — Performance Benchmarks@2x (1).png deleted file mode 100644 index 9dc4ea118..000000000 Binary files a/gitbooks/.gitbook/assets/V05 — Performance Benchmarks@2x (1).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V05 — Performance Benchmarks@2x.png b/gitbooks/.gitbook/assets/V05 — Performance Benchmarks@2x.png deleted file mode 100644 index c8d74a5af..000000000 Binary files a/gitbooks/.gitbook/assets/V05 — Performance Benchmarks@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V07_Purkinje_Cell_to_Subconscious@2x.png b/gitbooks/.gitbook/assets/V07_Purkinje_Cell_to_Subconscious@2x.png deleted file mode 100644 index ee26c9d77..000000000 Binary files a/gitbooks/.gitbook/assets/V07_Purkinje_Cell_to_Subconscious@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V08_How_Pieces_Connect@2x.png b/gitbooks/.gitbook/assets/V08_How_Pieces_Connect@2x.png deleted file mode 100644 index ff6b26c58..000000000 Binary files a/gitbooks/.gitbook/assets/V08_How_Pieces_Connect@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V09 — Neocortex Hero@2x.png b/gitbooks/.gitbook/assets/V09 — Neocortex Hero@2x.png deleted file mode 100644 index b052408e9..000000000 Binary files a/gitbooks/.gitbook/assets/V09 — Neocortex Hero@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V10_Knowledge_Graph_Visualization@2x.png b/gitbooks/.gitbook/assets/V10_Knowledge_Graph_Visualization@2x.png deleted file mode 100644 index 8f752a7db..000000000 Binary files a/gitbooks/.gitbook/assets/V10_Knowledge_Graph_Visualization@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1) (1).png b/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1) (1).png deleted file mode 100644 index b7333d122..000000000 Binary files a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1) (1).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1) (2).png b/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1) (2).png deleted file mode 100644 index b7333d122..000000000 Binary files a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1) (2).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1).png b/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1).png deleted file mode 100644 index b7333d122..000000000 Binary files a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (1).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (2).png b/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (2).png deleted file mode 100644 index b7333d122..000000000 Binary files a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x (2).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x.png b/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x.png deleted file mode 100644 index b7333d122..000000000 Binary files a/gitbooks/.gitbook/assets/V11 — Tiered Memory Deep Dive@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V12_Neuroscience_of_Forgetting@2x.png b/gitbooks/.gitbook/assets/V12_Neuroscience_of_Forgetting@2x.png deleted file mode 100644 index a195f5219..000000000 Binary files a/gitbooks/.gitbook/assets/V12_Neuroscience_of_Forgetting@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V13_Subconscious_Loop@2x.png b/gitbooks/.gitbook/assets/V13_Subconscious_Loop@2x.png deleted file mode 100644 index 8ee9227ab..000000000 Binary files a/gitbooks/.gitbook/assets/V13_Subconscious_Loop@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V14_Mirror_Test_Concept@2x.png b/gitbooks/.gitbook/assets/V14_Mirror_Test_Concept@2x.png deleted file mode 100644 index 3793dbf0e..000000000 Binary files a/gitbooks/.gitbook/assets/V14_Mirror_Test_Concept@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V15 — Three Pillars@2x.png b/gitbooks/.gitbook/assets/V15 — Three Pillars@2x.png deleted file mode 100644 index 008c72519..000000000 Binary files a/gitbooks/.gitbook/assets/V15 — Three Pillars@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/V16_Data_Flow_Pipeline@2x.png b/gitbooks/.gitbook/assets/V16_Data_Flow_Pipeline@2x.png deleted file mode 100644 index 03533aebc..000000000 Binary files a/gitbooks/.gitbook/assets/V16_Data_Flow_Pipeline@2x.png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/image (1) (1).png b/gitbooks/.gitbook/assets/image (1) (1).png deleted file mode 100644 index 9de536ebb..000000000 Binary files a/gitbooks/.gitbook/assets/image (1) (1).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/image (1).png b/gitbooks/.gitbook/assets/image (1).png deleted file mode 100644 index 9de536ebb..000000000 Binary files a/gitbooks/.gitbook/assets/image (1).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/image (2).png b/gitbooks/.gitbook/assets/image (2).png deleted file mode 100644 index d0d8d169d..000000000 Binary files a/gitbooks/.gitbook/assets/image (2).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/image (3).png b/gitbooks/.gitbook/assets/image (3).png deleted file mode 100644 index 3165f0476..000000000 Binary files a/gitbooks/.gitbook/assets/image (3).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/image (4).png b/gitbooks/.gitbook/assets/image (4).png deleted file mode 100644 index 1718a5309..000000000 Binary files a/gitbooks/.gitbook/assets/image (4).png and /dev/null differ diff --git a/gitbooks/.gitbook/assets/memory-tree-pipeline.excalidraw b/gitbooks/.gitbook/assets/memory-tree-pipeline.excalidraw deleted file mode 100644 index 29ee1a1ce..000000000 --- a/gitbooks/.gitbook/assets/memory-tree-pipeline.excalidraw +++ /dev/null @@ -1,1353 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "openhuman-memory-tree-async-pipeline", - "elements": [ - { - "id": "title", - "type": "text", - "x": 355, - "y": 20, - "width": 740, - "height": 40, - "text": "OpenHuman Memory Tree Async Pipeline", - "fontSize": 30, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 32, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 1, - "version": 1, - "versionNonce": 1, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "subtitle", - "type": "text", - "x": 235, - "y": 64, - "width": 980, - "height": 24, - "text": "Leaf ingestion -> jobs queue -> workers -> source/topic/global tree building", - "fontSize": 18, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 18, - "strokeColor": "#495057", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 2, - "version": 1, - "versionNonce": 2, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "lane1", - "type": "rectangle", - "x": 40, - "y": 120, - "width": 310, - "height": 340, - "strokeColor": "#1971c2", - "backgroundColor": "#e7f5ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 3, - "version": 1, - "versionNonce": 3, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "lane2", - "type": "rectangle", - "x": 390, - "y": 120, - "width": 340, - "height": 340, - "strokeColor": "#2b8a3e", - "backgroundColor": "#ebfbee", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 4, - "version": 1, - "versionNonce": 4, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "lane3", - "type": "rectangle", - "x": 770, - "y": 120, - "width": 390, - "height": 340, - "strokeColor": "#e67700", - "backgroundColor": "#fff4e6", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 5, - "version": 1, - "versionNonce": 5, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "lane4", - "type": "rectangle", - "x": 1200, - "y": 120, - "width": 440, - "height": 340, - "strokeColor": "#9c36b5", - "backgroundColor": "#f8f0fc", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 6, - "version": 1, - "versionNonce": 6, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "lane5", - "type": "rectangle", - "x": 40, - "y": 500, - "width": 760, - "height": 220, - "strokeColor": "#0b7285", - "backgroundColor": "#e3fafc", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 7, - "version": 1, - "versionNonce": 7, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "lane6", - "type": "rectangle", - "x": 840, - "y": 500, - "width": 800, - "height": 220, - "strokeColor": "#495057", - "backgroundColor": "#f1f3f5", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 8, - "version": 1, - "versionNonce": 8, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "h1", - "type": "text", - "x": 135, - "y": 135, - "width": 120, - "height": 28, - "text": "1. Ingest", - "fontSize": 24, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 24, - "strokeColor": "#1971c2", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 9, - "version": 1, - "versionNonce": 9, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "h2", - "type": "text", - "x": 505, - "y": 135, - "width": 110, - "height": 28, - "text": "2. Queue", - "fontSize": 24, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 24, - "strokeColor": "#2b8a3e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 10, - "version": 1, - "versionNonce": 10, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "h3", - "type": "text", - "x": 890, - "y": 135, - "width": 150, - "height": 28, - "text": "3. Workers", - "fontSize": 24, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 24, - "strokeColor": "#e67700", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 11, - "version": 1, - "versionNonce": 11, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "h4", - "type": "text", - "x": 1320, - "y": 135, - "width": 200, - "height": 28, - "text": "4. Tree State", - "fontSize": 24, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 24, - "strokeColor": "#9c36b5", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 12, - "version": 1, - "versionNonce": 12, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "h5", - "type": "text", - "x": 275, - "y": 515, - "width": 290, - "height": 28, - "text": "5. Scheduler / Background", - "fontSize": 24, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 24, - "strokeColor": "#0b7285", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 13, - "version": 1, - "versionNonce": 13, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "h6", - "type": "text", - "x": 1100, - "y": 515, - "width": 280, - "height": 28, - "text": "6. Leaf Lifecycle", - "fontSize": 24, - "fontFamily": 1, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 24, - "strokeColor": "#343a40", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 14, - "version": 1, - "versionNonce": 14, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "b1", - "type": "rectangle", - "x": 75, - "y": 185, - "width": 240, - "height": 240, - "strokeColor": "#1971c2", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 15, - "version": 1, - "versionNonce": 15, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "t1", - "type": "text", - "x": 93, - "y": 205, - "width": 204, - "height": 198, - "text": "JSON-RPC / source ingestion\n\nchat | email | document\n\ncanonicalise\n-> chunk_markdown\n-> score_chunks_fast\n-> upsert_chunks_tx\n-> lifecycle_status = pending_extraction\n-> persist fast score rows\n-> enqueue extract_chunk per chunk\n-> wake_workers()", - "fontSize": 18, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 194, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 16, - "version": 1, - "versionNonce": 16, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "b2", - "type": "rectangle", - "x": 435, - "y": 185, - "width": 250, - "height": 240, - "strokeColor": "#2b8a3e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 17, - "version": 1, - "versionNonce": 17, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "t2", - "type": "text", - "x": 453, - "y": 205, - "width": 214, - "height": 198, - "text": "SQLite: memory_tree/chunks.db\n\nmem_tree_chunks\nmem_tree_score\nmem_tree_entity_index\nmem_tree_jobs\nmem_tree_trees\nmem_tree_buffers\nmem_tree_summaries\n\njobs fields\nkind | payload_json | dedupe_key\nstatus | attempts | available_at_ms\nlocked_until_ms | last_error", - "fontSize": 18, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 194, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 18, - "version": 1, - "versionNonce": 18, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "b3", - "type": "rectangle", - "x": 815, - "y": 185, - "width": 300, - "height": 135, - "strokeColor": "#e67700", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 19, - "version": 1, - "versionNonce": 19, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "t3", - "type": "text", - "x": 833, - "y": 205, - "width": 264, - "height": 108, - "text": "jobs::start(workspace_dir)\n\nrecover_stale_locks()\nspawn 3 worker tasks\nNotify wakeup + 5s polling fallback\nshared Semaphore(3) for LLM-bound work", - "fontSize": 18, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 104, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 20, - "version": 1, - "versionNonce": 20, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "b4", - "type": "rectangle", - "x": 815, - "y": 335, - "width": 300, - "height": 90, - "strokeColor": "#d9480f", - "backgroundColor": "#fff8f0", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 21, - "version": 1, - "versionNonce": 21, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "t4", - "type": "text", - "x": 833, - "y": 355, - "width": 264, - "height": 54, - "text": "Handlers\nextract_chunk | append_buffer | seal\ntopic_route | digest_daily | flush_stale", - "fontSize": 18, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 50, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 22, - "version": 1, - "versionNonce": 22, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "b5", - "type": "rectangle", - "x": 1240, - "y": 185, - "width": 360, - "height": 240, - "strokeColor": "#9c36b5", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 23, - "version": 1, - "versionNonce": 23, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "t5", - "type": "text", - "x": 1258, - "y": 205, - "width": 324, - "height": 198, - "text": "Tree building outputs\n\nsource tree\nL0 buffer -> seal -> L1/L2/... summaries\n\ntopic tree\ncurator hotness gate\noptional append_buffer(topic)\n\nglobal tree\ndigest_daily -> daily node\nappend_daily_and_cascade", - "fontSize": 18, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 194, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 24, - "version": 1, - "versionNonce": 24, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "b6", - "type": "rectangle", - "x": 85, - "y": 575, - "width": 670, - "height": 105, - "strokeColor": "#0b7285", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 25, - "version": 1, - "versionNonce": 25, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "t6", - "type": "text", - "x": 103, - "y": 597, - "width": 634, - "height": 72, - "text": "Scheduler loop\n\nUTC daily tick -> enqueue digest_daily(yesterday) + flush_stale(today)\nflush_stale scans stale buffers and enqueues force seal jobs\nworkers consume these through the same mem_tree_jobs pipeline", - "fontSize": 18, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 68, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 26, - "version": 1, - "versionNonce": 26, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "s1", - "type": "rectangle", - "x": 875, - "y": 585, - "width": 130, - "height": 70, - "strokeColor": "#495057", - "backgroundColor": "#fff3bf", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 27, - "version": 1, - "versionNonce": 27, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "st1", - "type": "text", - "x": 891, - "y": 607, - "width": 98, - "height": 24, - "text": "pending_extraction", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 20, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 28, - "version": 1, - "versionNonce": 28, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "s2", - "type": "rectangle", - "x": 1045, - "y": 585, - "width": 110, - "height": 70, - "strokeColor": "#495057", - "backgroundColor": "#d3f9d8", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 29, - "version": 1, - "versionNonce": 29, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "st2", - "type": "text", - "x": 1069, - "y": 607, - "width": 62, - "height": 24, - "text": "admitted", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 20, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 30, - "version": 1, - "versionNonce": 30, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "s3", - "type": "rectangle", - "x": 1195, - "y": 585, - "width": 110, - "height": 70, - "strokeColor": "#495057", - "backgroundColor": "#d0ebff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 31, - "version": 1, - "versionNonce": 31, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "st3", - "type": "text", - "x": 1223, - "y": 607, - "width": 54, - "height": 24, - "text": "buffered", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 20, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 32, - "version": 1, - "versionNonce": 32, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "s4", - "type": "rectangle", - "x": 1345, - "y": 585, - "width": 110, - "height": 70, - "strokeColor": "#495057", - "backgroundColor": "#e5dbff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 33, - "version": 1, - "versionNonce": 33, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "st4", - "type": "text", - "x": 1375, - "y": 607, - "width": 50, - "height": 24, - "text": "sealed", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 20, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 34, - "version": 1, - "versionNonce": 34, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "s5", - "type": "rectangle", - "x": 1045, - "y": 665, - "width": 110, - "height": 36, - "strokeColor": "#c92a2a", - "backgroundColor": "#ffe3e3", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "roundness": { "type": 3 }, - "seed": 35, - "version": 1, - "versionNonce": 35, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "st5", - "type": "text", - "x": 1074, - "y": 672, - "width": 52, - "height": 20, - "text": "dropped", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "center", - "verticalAlign": "top", - "baseline": 16, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 36, - "version": 1, - "versionNonce": 36, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "life-note", - "type": "text", - "x": 1185, - "y": 665, - "width": 390, - "height": 36, - "text": "extract_chunk decides admitted vs dropped. append_buffer moves admitted leaves into buffers. seal creates summaries and parent links.", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 32, - "strokeColor": "#495057", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 37, - "version": 1, - "versionNonce": 37, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - }, - { - "id": "a1", - "type": "arrow", - "x": 315, - "y": 305, - "width": 115, - "height": 0, - "points": [[0, 0], [115, 0]], - "strokeColor": "#2f9e44", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 38, - "version": 1, - "versionNonce": 38, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [115, 0], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a2", - "type": "arrow", - "x": 685, - "y": 305, - "width": 125, - "height": 0, - "points": [[0, 0], [125, 0]], - "strokeColor": "#e67700", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 39, - "version": 1, - "versionNonce": 39, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [125, 0], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a3", - "type": "arrow", - "x": 1115, - "y": 305, - "width": 125, - "height": 0, - "points": [[0, 0], [125, 0]], - "strokeColor": "#9c36b5", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 40, - "version": 1, - "versionNonce": 40, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [125, 0], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a4", - "type": "arrow", - "x": 430, - "y": 575, - "width": 70, - "height": 120, - "points": [[0, 0], [70, -120]], - "strokeColor": "#0b7285", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 41, - "version": 1, - "versionNonce": 41, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [70, -120], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a5", - "type": "arrow", - "x": 1005, - "y": 620, - "width": 40, - "height": 0, - "points": [[0, 0], [40, 0]], - "strokeColor": "#2b8a3e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 42, - "version": 1, - "versionNonce": 42, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [40, 0], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a6", - "type": "arrow", - "x": 1155, - "y": 620, - "width": 40, - "height": 0, - "points": [[0, 0], [40, 0]], - "strokeColor": "#1971c2", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 43, - "version": 1, - "versionNonce": 43, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [40, 0], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a7", - "type": "arrow", - "x": 1305, - "y": 620, - "width": 40, - "height": 0, - "points": [[0, 0], [40, 0]], - "strokeColor": "#9c36b5", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 44, - "version": 1, - "versionNonce": 44, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [40, 0], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "a8", - "type": "arrow", - "x": 1100, - "y": 655, - "width": 0, - "height": 10, - "points": [[0, 0], [0, 10]], - "strokeColor": "#c92a2a", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 3, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 45, - "version": 1, - "versionNonce": 45, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false, - "lastCommittedPoint": [0, 10], - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow" - }, - { - "id": "foot", - "type": "text", - "x": 40, - "y": 750, - "width": 1540, - "height": 60, - "text": "Job kinds in play: extract_chunk -> append_buffer(source) -> optional seal -> topic_route -> optional append_buffer(topic). Independent background flow: scheduler -> digest_daily / flush_stale -> seal. All paths go through mem_tree_jobs, so retries, dedupe, stale lock recovery, and worker wakeups stay centralized.", - "fontSize": 16, - "fontFamily": 3, - "textAlign": "left", - "verticalAlign": "top", - "baseline": 56, - "strokeColor": "#343a40", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "seed": 46, - "version": 1, - "versionNonce": 46, - "isDeleted": false, - "groupIds": [], - "boundElements": null, - "updated": 1, - "link": null, - "locked": false - } - ], - "appState": { - "gridSize": null, - "viewBackgroundColor": "#ffffff" - }, - "files": {} -} diff --git a/gitbooks/.gitbook/assets/screen.png b/gitbooks/.gitbook/assets/screen.png deleted file mode 100644 index 834f9c623..000000000 Binary files a/gitbooks/.gitbook/assets/screen.png and /dev/null differ diff --git a/gitbooks/README.md b/gitbooks/README.md index ce22ad484..106d11f7f 100644 --- a/gitbooks/README.md +++ b/gitbooks/README.md @@ -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. diff --git a/gitbooks/SUMMARY.md b/gitbooks/SUMMARY.md index bf56dc7f7..346b3879a 100644 --- a/gitbooks/SUMMARY.md +++ b/gitbooks/SUMMARY.md @@ -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) diff --git a/gitbooks/developing/README.md b/gitbooks/developing/README.md index 4db696ccd..046795c80 100644 --- a/gitbooks/developing/README.md +++ b/gitbooks/developing/README.md @@ -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. diff --git a/gitbooks/features/architecture.md b/gitbooks/features/architecture.md index af251261a..5c0d32760 100644 --- a/gitbooks/features/architecture.md +++ b/gitbooks/features/architecture.md @@ -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 (`/memory_tree/chunks.db`) and as `.md` files in `/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 diff --git a/gitbooks/features/integrations.md b/gitbooks/features/integrations/README.md similarity index 88% rename from gitbooks/features/integrations.md rename to gitbooks/features/integrations/README.md index ee74be010..e56e2f154 100644 --- a/gitbooks/features/integrations.md +++ b/gitbooks/features/integrations/README.md @@ -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) diff --git a/gitbooks/features/auto-fetch.md b/gitbooks/features/integrations/auto-fetch.md similarity index 71% rename from gitbooks/features/auto-fetch.md rename to gitbooks/features/integrations/auto-fetch.md index dcf554790..5d61f7226 100644 --- a/gitbooks/features/auto-fetch.md +++ b/gitbooks/features/integrations/auto-fetch.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. diff --git a/gitbooks/features/model-routing.md b/gitbooks/features/model-routing/README.md similarity index 91% rename from gitbooks/features/model-routing.md rename to gitbooks/features/model-routing/README.md index e17f065cf..34e4f1782 100644 --- a/gitbooks/features/model-routing.md +++ b/gitbooks/features/model-routing/README.md @@ -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. diff --git a/gitbooks/features/local-ai.md b/gitbooks/features/model-routing/local-ai.md similarity index 89% rename from gitbooks/features/local-ai.md rename to gitbooks/features/model-routing/local-ai.md index f04b8f28a..45e053f1e 100644 --- a/gitbooks/features/local-ai.md +++ b/gitbooks/features/model-routing/local-ai.md @@ -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. diff --git a/gitbooks/features/native-tools.md b/gitbooks/features/native-tools.md index 5904e5b09..c7a082ee5 100644 --- a/gitbooks/features/native-tools.md +++ b/gitbooks/features/native-tools.md @@ -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. diff --git a/gitbooks/features/obsidian-wiki/README.md b/gitbooks/features/obsidian-wiki/README.md index cae2a3f8f..d58d9b989 100644 --- a/gitbooks/features/obsidian-wiki/README.md +++ b/gitbooks/features/obsidian-wiki/README.md @@ -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. diff --git a/gitbooks/features/obsidian-wiki/memory-tree-pipeline.md b/gitbooks/features/obsidian-wiki/memory-tree-pipeline.md index a6a2174e7..f796d63c8 100644 --- a/gitbooks/features/obsidian-wiki/memory-tree-pipeline.md +++ b/gitbooks/features/obsidian-wiki/memory-tree-pipeline.md @@ -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. diff --git a/gitbooks/features/obsidian-wiki/memory-tree.md b/gitbooks/features/obsidian-wiki/memory-tree.md index 0502582c6..9d3337df4 100644 --- a/gitbooks/features/obsidian-wiki/memory-tree.md +++ b/gitbooks/features/obsidian-wiki/memory-tree.md @@ -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. diff --git a/gitbooks/features/platform.md b/gitbooks/features/platform.md index dab4a0953..8735e43b5 100644 --- a/gitbooks/features/platform.md +++ b/gitbooks/features/platform.md @@ -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. *** diff --git a/gitbooks/features/privacy-and-security.md b/gitbooks/features/privacy-and-security.md index 1cbf27341..a508ca4ca 100644 --- a/gitbooks/features/privacy-and-security.md +++ b/gitbooks/features/privacy-and-security.md @@ -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. -
+
## Security diff --git a/gitbooks/features/subconscious.md b/gitbooks/features/subconscious.md index e9e3727d0..336c0cc1d 100644 --- a/gitbooks/features/subconscious.md +++ b/gitbooks/features/subconscious.md @@ -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. diff --git a/gitbooks/features/token-compression.md b/gitbooks/features/token-compression.md index 22ee7fe7c..8cc097d6b 100644 --- a/gitbooks/features/token-compression.md +++ b/gitbooks/features/token-compression.md @@ -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. diff --git a/gitbooks/features/voice.md b/gitbooks/features/voice.md index 35ee7b0fe..e6077a195 100644 --- a/gitbooks/features/voice.md +++ b/gitbooks/features/voice.md @@ -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. diff --git a/gitbooks/overview/getting-started.md b/gitbooks/overview/getting-started.md index 161be07c4..da0751a07 100644 --- a/gitbooks/overview/getting-started.md +++ b/gitbooks/overview/getting-started.md @@ -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). *** diff --git a/gitbooks/overview/how-it-works.md b/gitbooks/overview/how-it-works.md index 3310a8ebb..71c9f1c2b 100644 --- a/gitbooks/overview/how-it-works.md +++ b/gitbooks/overview/how-it-works.md @@ -24,17 +24,17 @@ The same chunks the agent reasons over are written as `.md` files in `= 30); - assert!(TICK_SECONDS <= 600); + assert!(TICK_SECONDS <= 3600); } #[test]