oo-chat
September 1, 2026 · View on GitHub
An open-source web chat client for ConnectOnion
agents, built with Next.js 16. Paste an agent's 0x… address and chat with it —
streamed tool calls, approvals, Todo List progress, and per-session agent modes
included.
oo-chat is a thin front end: the heavy lifting (connecting to an agent, the
WebSocket protocol, streaming, and per-session persistence) lives in
@connectonion/react.
oo-chat handles routing, layout, and rendering the SDK's event stream.
How it works (30-second version)
You paste 0x… → /[address] (agent profile) → /[address]/[sessionId] (live chat)
│
useAgentForHuman(address, sessionId) ← @connectonion/react
│
WebSocket → wss://oo.openonion.ai (relay) → the remote agent
- User identity is an Ed25519 key held as a non-extractable WebCrypto key in
IndexedDB by
@connectonion/react. Recovery material is shown once and never persisted; short-lived auth tokens remain in memory and are renewed on reload. - Agents are addressed by their
0x…public key; profile + online status come from the relay (fetchAgentInfo). - Recent Chat is reconciled with the authenticated Agent Host on load, every 15 seconds, and when the tab becomes active or comes back online. Host-retained history is authoritative; the sidebar keeps a local cache so navigation remains instant and preserves drafts that the Host has not committed yet.
- Transcripts are cached by the SDK per session
(
localStorage['co:agent:{address}:session:{id}']) for immediate reloads. A remote session can therefore appear in Recent Chat on another device before that device has cached its transcript; opening it loads the canonical snapshot from the Host.
📖 Full data-flow walkthrough: docs/ARCHITECTURE.md.
Getting started
npm install
npm run dev # http://localhost:3000
Open the app, paste an agent address, and start chatting. A user identity (recovery phrase) is generated automatically on first load — back it up from Settings.
Environment
The app reads a single env var (optional):
NEXT_PUBLIC_OPENONION_API_URL=https://oo.openonion.ai # auth/profile backend (default)
The relay (wss://oo.openonion.ai) is an SDK default and not configured here. See
.env.example.
Scripts
npm run dev # dev server (localhost:3000)
npm run build # production build (what Vercel runs)
npm run lint # ESLint
npm start # serve the production build
Project layout
app/
├── page.tsx # agent picker / welcome
├── [address]/page.tsx # agent landing (profile + first message)
├── [address]/[sessionId]/page.tsx # live chat session
├── settings/page.tsx # identity, credits, agents
└── api/
├── auth/route.ts # CORS proxy → oo.openonion.ai auth
└── chat/route.ts # legacy/unused (see ARCHITECTURE §10)
components/chat/ # chat UI: use-agent-sdk.ts + message renderers
hooks/ # identity, agent info, Recent Chat sync
store/chat-store.ts # sidebar conversation index (zustand + persist)
docs/ # ARCHITECTURE.md, DEPLOY.md
The SDK
oo-chat has one SDK boundary: @connectonion/react. It includes the hooks, agent
connection, WebSocket protocol, browser identity, and session persistence. The published
version is pinned by semver in package.json.
Symlinking it to a local checkout for development typechecks against unreleased code
and hides breakage that only appears against the published package — verify on a preview
deploy, not a local build. Publishing the SDK and shipping oo-chat is documented in
docs/DEPLOY.md.
Related projects
../connectonion-react— the React SDK (@connectonion/reacton npm):useAgentForHuman,useVoiceInput,RemoteAgent, the WebSocket protocol, browser identity, and session persistence.../chat-ui(@connectonion/chat-ui) — source registry for the chat components. When fixing design issues incomponents/chat/, mirror the change into../chat-ui/registry/to keep them in sync.
Deploy
Hosted on Vercel (project oo-chat). Push a branch for a preview deploy; merge to
main for production. See docs/DEPLOY.md.
License
Apache-2.0. See LICENSE.