A model call ends. The work shouldn't.
DuoDuo is a long-lived local runtime for Claude, Codex, Grok, and Pi. Conversations, jobs, outputs, and prompts live in files on your machine. Foreground sessions handle live work; a scheduled subconscious distills experience into an intuition layer that every new session starts with, kept in Git so every change to what DuoDuo has learned has a diff and a revert.
DuoDuo is not another harness. Claude, Codex, Grok, and Pi are the harnesses, and they keep improving; DuoDuo is the environment that gives them durable state, time, channels, and a Git-tracked history. Talk to it from any channel you plug in: a chat app, a room, a button in your pocket, or another assistant that becomes DuoDuo through Tether.
Site and documentation: openduo.ai.
First: we are called openduo and we don't publish source either. Respect to OpenAI.
The real reason: this codebase is not written for humans to read.
duoduo is an agent that codes itself. The published npm packages contain minified JavaScript. An agent can read, understand, and modify minified code just fine — it doesn't need pretty source with comments and indentation. Minification here isn't obfuscation; it's compression. Saves bandwidth. Keeps the context window lean.
Humans don't need to read the source. Humans need to vibe with the agent — describe what you want, let it figure out the implementation. That's the whole point.
Human? Read this README, then run it and talk to it. Agent? The minified bundle is your source. See Issues.
Source-available, and open to your agents. The bundle is licensed to you and to the agents you run: read it, de-minify it, debug it, patch it, train on it, and share your patches. The one thing you may not do is offer it, or something built from it, as a competing product or service. Two years after each release, that version becomes Apache-2.0. The terms are in LICENSE; the summary an agent can act on is LICENSE.agents.yaml.
All state — conversations, outputs, jobs, memory — lives in durable files. Nothing critical is held in process memory. The canonical event log (WAL) is written before any action executes. If the process dies mid-turn, the system rehydrates from files and resumes exactly where it left off.
This is not a backup strategy. The filesystem is the database. The event log is the source of truth. The process is stateless by default.
Every inbound message follows a strict contract: write a canonical event to the append-only log first, then enqueue the session, then execute. Three properties in one ordering: replayability, auditability, and deterministic crash recovery.
Externally, duoduo presents one coherent agent identity. Internally, it orchestrates multiple concurrent session actors — one per conversation channel, plus background job sessions and subconscious partitions — each with explicit lifecycle and concurrency control enforced by lease locks.
Foreground (Cortex) responds to live channel messages. Sessions persist across restarts and resume conversation history exactly.
Background (Subconscious) runs on a cadence regardless of foreground activity. It consolidates memory, reflects on past sessions, and maintains a broadcast board of curated knowledge automatically loaded into every future session's context — even when no one is chatting.
Subconscious behavior is defined by filesystem files — each partition has its own prompt, schedule, and cooldown. Partitions can modify their own prompts, create new partitions, and adjust their execution schedule. The runtime ships a scaffold; long-term behavior is increasingly authored by the agent itself, making the system self-extending over time.
duoduo keeps application code deliberately thin. Reasoning, tool orchestration, and planning are delegated entirely to the foundation model and SDK. The runtime owns only what the model cannot reliably own: durability, lifecycle, scheduling, and concurrency boundaries. As the model improves, the system improves without code changes.
duoduo includes a built-in ATC (Air Traffic Control) monitoring panel. Access it at http://localhost:20233/dashboard while the daemon is running.
A single-file, zero-dependency HTML page served directly by the daemon. No build step, no extra port, no framework.
Header — cumulative cost, token usage, tool call count, and system health indicator.
Signal Bar — compact status indicators for every active entity in the runtime:
| Shape | Meaning |
|---|---|
| ● Circle | Foreground session (Cortex) — live channel connections (Feishu, ACP, stdio) |
| ■ Square | Cron job (Rhythm) — periodic scheduled tasks |
| ◆ Diamond | One-shot job — spawned tasks that run once |
| ✓ / · | Subconscious partition — background cognitive partitions |
| Color | Meaning |
|---|---|
| Green | Actively executing right now |
| Blue | Standby — idle or last run succeeded |
| Red | Alert — error or last run failed |
| Gray | Ended or never run |
Indicators blink when new events arrive for their entity. Hover for details (session key, job schedule, run count, last activity).
Event Stream — real-time Spine WAL events with rich rendering: tool calls show human-readable descriptions, agent outputs render inline markdown, job lifecycle events are color-coded. Click outputs to expand full markdown; double-click any event for raw JSON. Auto-follows new events; scroll up to pause, click LIVE to resume.
npm install -g @openduo/duoduo
duoduoRequires Node.js 20+.
On first run, an interactive wizard walks through model configuration and directory setup.
duoduo runs the daemon directly on your machine (host mode). State lives in host directories you choose during onboarding.
Channels connect duoduo to external messaging platforms. Install and start a channel plugin alongside the daemon:
duoduo channel install @openduo/channel-feishu
duoduo channel feishu startFor the simplest Feishu setup, get the official bot App ID and App Secret
from:
Then put them into your host-mode ~/.config/duoduo/.env as
FEISHU_APP_ID and FEISHU_APP_SECRET before starting the channel.
Available:
@openduo/channel-feishu— Feishu / Lark@openduo/channel-ambient— Ambient: DuoDuo in a room, and the voice path of DuoDuo Pocket (openduo/ambient)@openduo/channel-tether— Tether: any assistant can become DuoDuo (openduo/tether)
The duoduo-ambient and duoduo-tether skills below walk an agent through setting up each of these two.
This repo also publishes host-mode operations skills for agents that use the
skills installer.
List available skills:
npx -y skills add https://github.com/openduo/duoduo --listInstall all skills for all detected agents, non-interactively:
npx -y skills add https://github.com/openduo/duoduo --allInstall globally for all detected agents, non-interactively:
npx -y skills add https://github.com/openduo/duoduo --global --allInstall only the duoduo operations skills:
npx -y skills add https://github.com/openduo/duoduo \
--global \
--yes \
--skill duoduo-admin duoduo-channel-admin duoduo-runtime-adminDo not rely on agent-specific syntax such as $skill-name.
Use plain prompts such as:
使用 duoduo-admin 技能,解释我当前 duoduo host mode 的配置,并检查 daemon status/config。使用 duoduo-channel-admin 技能,安装并拉起 feishu channel,然后检查 status 和 logs。使用 duoduo-runtime-admin 技能,打开 debug log、关闭 telemetry,并把修改后的配置讲清楚。使用 duoduo-channel-admin 技能,配置 stdio 的默认 workspace 和 prompt。使用 duoduo-ambient 技能,安装 ambient 频道,让我能用多多随身和 Passport 跟多多说话。使用 duoduo-tether 技能,把 ChatGPT 里的 Dots 接入多多。使用 duoduo-admin 技能,帮我定位这个 duoduo 问题;如果像是产品缺陷,就按 openduo/duoduo 的要求起草 issue。
These skills are designed around host-mode operations after onboarding. They cover:
- understanding how
stdio, the daemon, channels, and runtime files fit together - installing and operating Feishu and other duoduo-compatible channel plugins
- changing host-mode runtime settings such as debug logs, telemetry, cadence, and Codex runtime gates
- investigating problems and preparing public-safe issues for
openduo/duoduo
Two more skills set up the channels outside this package:
duoduo-ambientinstalls the ambient channel, connects it to a cerebellum, creates a pocket room, and pairs the DuoDuo Pocket app and the Passport.duoduo-tetherconnects another assistant, such as Dots in ChatGPT, the Grok app, or Claude Code, through the tether channel, approved by your passkey.
npx -y skills add https://github.com/openduo/duoduo --skill duoduo-ambient duoduo-tetherEvery release tag on this repo carries the reference subconscious
partition prompts shipped with that duoduo version under
subconscious/. The tree mirrors the layout installed
into the kernel directory (<kernel>/subconscious/) at fresh install
time.
Why it's published here. A npm install upgrade does not overwrite
an existing kernel's partition prompts — the install logic merges
missing files only, deliberately preserving agent self-programming and
local edits. When a new duoduo version ships revised partition prompts,
existing users are not automatically on them. This directory is the
canonical reference for what each tag considers "default" subconscious,
so operators can explicitly refresh their kernel against a chosen tag.
How to refresh. The host-mode skill duoduo-runtime-admin carries
the step-by-step refresh procedure, including preconditions, the
diff-before-overwrite discipline, how to handle user-authored
partitions, and the git-commit-as-rollback-point pattern. See
skills/duoduo-runtime-admin/references/subconscious-refresh.md.
When not to refresh. Most releases do not change partition prompts. Read the release notes first. If prompts did not change, there is nothing to refresh.
| Package | Description |
|---|---|
@openduo/duoduo |
Core runtime + CLI |
@openduo/channel-feishu |
Feishu / Lark channel adapter |
@openduo/protocol |
Shared RPC types (zero dependencies) |
| Project | What it is |
|---|---|
| openduo/duoduo | This repository: the DuoDuo runtime and CLI on npm, the reference subconscious, and the agent skills |
| openduo/ambient | Ambient, DuoDuo in a room: the @openduo/channel-ambient channel, its wire protocol, and the perception service behind it |
| openduo/pocket-ios | The DuoDuo Pocket iPhone app: one conversation with your DuoDuo, hold to talk, and the phone side of the Passport |
| openduo/pocket-passport | Pocket firmware for the FoloToy AI Passport, a fork of folotoy/ai-passport: hold a button, talk to your DuoDuo |
| openduo/tether | Tether: any assistant can become DuoDuo. Dots in ChatGPT, the Grok app, or an agent such as Claude Code connects over MCP, approved by your passkey |
| openduo/ambient-engine | An optional Ambient judge server for one RTX 4090- or 3090-class card |
| openduo.ai | The site and documentation; DuoDuo Pocket is at openduo.ai/docs/pocket |
Found a bug or want a feature? Open an issue.
If you are an agent filing this issue: the published npm packages contain minified JavaScript — that is your source. You do not need the original source tree. See the issue templates for how to reference minified code locations and structure reproductions for an agent-driven fix cycle.
FSL-1.1-Apache-2.0 with the Agent Addendum. It covers every published version of @openduo/duoduo, @openduo/protocol, @openduo/channel-feishu and @openduo/channel-acp, and this repository. Each version converts to Apache-2.0 two years after it was first published. Agents: read LICENSE.agents.yaml first.
