mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-06-04 10:14:47 +08:00
docs: drop v2 framing across CLAUDE.md and 12 docs
Renamed 12 docs/v2-*.md → docs/*.md (already in index from earlier git mv). Rewrote CLAUDE.md to describe the codebase as just "the codebase" rather than "v2"; added a "Channels and Providers (skill-installed)" section reflecting the new model and updated the docs index links. Agent (general-purpose) cleaned the 12 doc bodies: - Dropped "NanoClaw v2" / "v2 schema" / "(v2)" prose throughout - Rewrote inter-doc cross-references docs/v2-X.md → docs/X.md - Architecture, agent-runner-details: collapsed v1↔v2 comparison tables into present-tense facts; added notes that trunk only ships `claude` and that channel adapters are skill-installed from the `channels` branch - Setup-wiring, checklist: dropped v1→v2 migration items that no longer apply - Frozen runtime paths preserved: data/v2.db, data/v2-sessions/, container name nanoclaw-v2 git grep confirms remaining `\bv2\b` matches in docs/ are only those runtime paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# NanoClaw v2 Agent-Runner Details
|
||||
# NanoClaw Agent-Runner Details
|
||||
|
||||
Implementation-level details for the agent-runner inside the container. See [v2-architecture-draft.md](v2-architecture-draft.md) for the high-level design.
|
||||
Implementation-level details for the agent-runner inside the container. See [architecture.md](architecture.md) for the high-level design.
|
||||
|
||||
## Separation of Concerns
|
||||
|
||||
@@ -8,7 +8,7 @@ The agent-runner has two layers:
|
||||
|
||||
1. **Agent-runner core** — owns the poll loop, message formatting, DB reads/writes, MCP tool implementations, routing, status management, media handling. This is NanoClaw-specific and shared across all providers.
|
||||
|
||||
2. **Agent provider** — owns the SDK interaction. Takes formatted prompts, pushes them to the SDK, yields events back. Each SDK (Claude, Codex, OpenCode) gets its own provider implementation.
|
||||
2. **Agent provider** — owns the SDK interaction. Takes formatted prompts, pushes them to the SDK, yields events back. Trunk ships the `claude` provider; additional providers (OpenCode, Codex, etc.) are installed by `/add-<provider>` skills from the `providers` branch.
|
||||
|
||||
The boundary: the agent-runner decides **what** to send and **what to do** with results. The provider decides **how** to talk to the SDK.
|
||||
|
||||
@@ -91,6 +91,8 @@ type ProviderEvent =
|
||||
|
||||
## Provider Implementations
|
||||
|
||||
Only the `claude` provider ships in trunk. The Codex and OpenCode sections below document the provider interface for reference and for skills that install additional providers — they are not baked into the core image.
|
||||
|
||||
### Claude Provider
|
||||
|
||||
Wraps `@anthropic-ai/claude-agent-sdk`'s `query()`.
|
||||
@@ -445,7 +447,7 @@ pending → processing → completed
|
||||
|
||||
### MCP Tools
|
||||
|
||||
The agent-runner runs an MCP server (same as v1) that exposes NanoClaw tools to the agent. In v2, all tools write to the session DB instead of IPC files.
|
||||
The agent-runner runs an MCP server that exposes NanoClaw tools to the agent. All tools write to the session DB.
|
||||
|
||||
**DB path:** The MCP server receives the session DB path via environment variable. It opens a second connection to the same SQLite file (WAL mode allows concurrent access).
|
||||
|
||||
@@ -691,8 +693,6 @@ For `task` kind messages with a `script` field in the content:
|
||||
4. If `wakeAgent === false`: mark message as completed, don't invoke the provider
|
||||
5. If `wakeAgent === true`: enrich the prompt with script output, then invoke the provider
|
||||
|
||||
Same as v1 behavior.
|
||||
|
||||
### Transcript Archiving
|
||||
|
||||
The agent-runner archives conversation transcripts before context compaction. For Claude, this is handled via the PreCompact hook (provider-internal). For other providers that don't have hooks, the agent-runner archives after each query completes based on the provider's output.
|
||||
@@ -721,15 +721,13 @@ The agent-runner reads config, creates the provider, and enters the poll loop. N
|
||||
### Provider Factory
|
||||
|
||||
```typescript
|
||||
type ProviderName = 'claude' | 'codex' | 'opencode';
|
||||
type ProviderName = 'claude' | string;
|
||||
|
||||
function createProvider(name: ProviderName, config: ProviderConfig): AgentProvider {
|
||||
switch (name) {
|
||||
case 'claude': return new ClaudeProvider(config);
|
||||
case 'codex': return new CodexProvider(config);
|
||||
case 'opencode': return new OpenCodeProvider(config);
|
||||
default: throw new Error(`Unknown provider: ${name}`);
|
||||
}
|
||||
// Trunk registers 'claude'; additional providers self-register when installed via skills.
|
||||
const factory = providerRegistry.get(name);
|
||||
if (!factory) throw new Error(`Unknown provider: ${name}`);
|
||||
return factory(config);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -737,7 +735,7 @@ The provider name comes from the container's environment (`AGENT_PROVIDER` env v
|
||||
|
||||
`ProviderConfig` contains provider-specific settings (API keys, model overrides, etc.) passed via environment variables — not via the interface. Each provider reads what it needs from `env`.
|
||||
|
||||
## What Stays From v1
|
||||
## Agent-Runner Properties
|
||||
|
||||
- MCP server is a separate Node process spawned by the provider (via `mcpServers` config)
|
||||
- The MCP server binary is shared across providers — same tools, same DB access
|
||||
@@ -745,21 +743,7 @@ The provider name comes from the container's environment (`AGENT_PROVIDER` env v
|
||||
- Additional directories discovery (`/workspace/extra/*`)
|
||||
- Logging via stderr (`[agent-runner] ...`)
|
||||
|
||||
## What Changes From v1
|
||||
|
||||
| v1 | v2 |
|
||||
|----|----|
|
||||
| stdin JSON envelope | Poll session DB |
|
||||
| IPC input files for follow-ups | Same DB poll + `provider.push()` |
|
||||
| stdout markers for output | Write messages_out rows |
|
||||
| MCP tools write IPC files | MCP tools write DB rows |
|
||||
| `_close` sentinel for shutdown | Host kills container externally |
|
||||
| `runQuery()` function with inline Claude SDK | `AgentProvider` interface + per-SDK implementations |
|
||||
| Single provider (Claude) | Pluggable providers (Claude, Codex, OpenCode, future) |
|
||||
| `ContainerInput` via stdin | Provider config via env vars + session DB for messages |
|
||||
| IPC polling for follow-ups | DB polling + provider.push() |
|
||||
|
||||
## Related Documents
|
||||
|
||||
- **[v2-architecture-draft.md](v2-architecture-draft.md)** — High-level architecture (session DB schema, central DB, channel adapters, message flow)
|
||||
- **[v2-api-details.md](v2-api-details.md)** — Channel adapter interface, message content examples, host delivery logic
|
||||
- **[architecture.md](architecture.md)** — High-level architecture (session DB schema, central DB, channel adapters, message flow)
|
||||
- **[api-details.md](api-details.md)** — Channel adapter interface, message content examples, host delivery logic
|
||||
@@ -1,10 +1,10 @@
|
||||
# NanoClaw v2 API Details
|
||||
# NanoClaw API Details
|
||||
|
||||
Implementation-level details for the v2 architecture. See [v2-architecture-draft.md](v2-architecture-draft.md) for the high-level design.
|
||||
Implementation-level details for the architecture. See [architecture.md](architecture.md) for the high-level design.
|
||||
|
||||
## Channel Adapter Interface
|
||||
|
||||
### NanoClaw Channel Interface (v2)
|
||||
### NanoClaw Channel Interface
|
||||
|
||||
```typescript
|
||||
interface ChannelSetup {
|
||||
@@ -59,7 +59,7 @@ interface OutboundMessage {
|
||||
|
||||
### Chat SDK Bridge
|
||||
|
||||
Wraps a Chat SDK adapter + Chat instance to conform to the NanoClaw ChannelAdapter interface.
|
||||
Wraps a Chat SDK adapter + Chat instance to conform to the NanoClaw ChannelAdapter interface. Trunk ships the bridge and the channel registry only — platform-specific Chat SDK adapters (Discord, Slack, Telegram, etc.) and native adapters (WhatsApp/Baileys) are installed by the `/add-<channel>` skills from the `channels` branch.
|
||||
|
||||
```typescript
|
||||
function createChatSdkBridge(
|
||||
@@ -170,7 +170,7 @@ function createChatSdkBridge(
|
||||
|
||||
### Native NanoClaw Channel (no Chat SDK)
|
||||
|
||||
Native channels implement the ChannelAdapter interface directly. Example structure for WhatsApp/Baileys:
|
||||
Native channels implement the ChannelAdapter interface directly. The WhatsApp/Baileys adapter is the canonical example — it ships via the `/add-whatsapp` skill, not in trunk:
|
||||
|
||||
```typescript
|
||||
function createWhatsAppChannel(): ChannelAdapter {
|
||||
@@ -293,14 +293,14 @@ function createWhatsAppChannel(): ChannelAdapter {
|
||||
"type": "card",
|
||||
"title": "Deployment Approval",
|
||||
"children": [
|
||||
{ "type": "text", "content": "Deploy v2.1.0 to production?" },
|
||||
{ "type": "text", "content": "Deploy 2.1.0 to production?" },
|
||||
{ "type": "actions", "children": [
|
||||
{ "type": "button", "id": "approve", "label": "Approve", "style": "primary" },
|
||||
{ "type": "button", "id": "reject", "label": "Reject", "style": "danger" }
|
||||
]}
|
||||
]
|
||||
},
|
||||
"fallbackText": "Deployment Approval: Deploy v2.1.0 to production? [Approve] [Reject]"
|
||||
"fallbackText": "Deployment Approval: Deploy 2.1.0 to production? [Approve] [Reject]"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>NanoClaw v2 Architecture</title>
|
||||
<title>NanoClaw Architecture</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
@@ -128,7 +128,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>NanoClaw v2 Architecture</h1>
|
||||
<h1>NanoClaw Architecture</h1>
|
||||
<div class="sub">Session-DB messaging model · Chat SDK bridge · OneCLI credential gateway · per-session containers</div>
|
||||
<nav>
|
||||
<a href="#overview">1 · Overview</a>
|
||||
@@ -396,7 +396,7 @@ flowchart LR
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>NanoClaw v2 · branch <code>v2</code> · generated from docs/v2-checklist.md, v2-architecture-draft.md, v2-isolation-model.md, v2-setup-wiring.md</footer>
|
||||
<footer>NanoClaw · generated from docs/checklist.md, architecture.md, isolation-model.md, setup-wiring.md</footer>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
@@ -1,4 +1,4 @@
|
||||
# NanoClaw v2 Architecture Diagram
|
||||
# NanoClaw Architecture Diagram
|
||||
|
||||
## System Overview
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NanoClaw v2 Architecture (Draft)
|
||||
# NanoClaw Architecture (Draft)
|
||||
|
||||
## Core Idea
|
||||
|
||||
@@ -176,7 +176,7 @@ messages_out content references filenames only:
|
||||
|
||||
No paths in the DB — the convention is the contract. The host reads files from `outbox/{message_id}/` in the mounted session folder and delivers them via the adapter (Chat SDK `FileUpload` with buffer data, or platform-specific upload for native channels). Host cleans up the outbox directory after successful delivery.
|
||||
|
||||
Outbound files use a dedicated `send_file` MCP tool (separate from `send_message`). See [v2-agent-runner-details.md](v2-agent-runner-details.md) for the tool interface.
|
||||
Outbound files use a dedicated `send_file` MCP tool (separate from `send_message`). See [agent-runner-details.md](agent-runner-details.md) for the tool interface.
|
||||
|
||||
### Message Deduplication
|
||||
|
||||
@@ -390,28 +390,21 @@ The receiving agent gets a normal chat message. It doesn't need to know the sour
|
||||
|
||||
This is documented as a pattern, not a built-in feature.
|
||||
|
||||
## What Stays the Same
|
||||
## Core Properties
|
||||
- Container isolation via filesystem mounts
|
||||
- Credential proxy (OneCLI)
|
||||
- Per-agent-group workspace (folder, CLAUDE.md, skills)
|
||||
- Polling-based (not event-driven)
|
||||
- Per-agent-group agent-runner recompilation on container startup (agent can modify its own source, request rebuild/restart, changes persist across teardowns)
|
||||
|
||||
## What Changes
|
||||
|
||||
| Component | v1 | v2 |
|
||||
|-----------|----|----|
|
||||
| Host ↔ container IO | stdin + IPC files | Mounted session DB (messages_in / messages_out) |
|
||||
| Container input | Prompt string piped to stdin | Agent-runner polls messages_in |
|
||||
| Container output | stdout markers | Agent-runner writes to messages_out |
|
||||
| Agent commands | IPC JSON files | messages_out with `kind: 'system'` |
|
||||
| Agent-to-agent | Not supported | messages_out with target agent routing |
|
||||
| Scheduling | Separate scheduler + task table | `process_after` / `deliver_after` + `recurrence` on messages |
|
||||
| Media | Not supported | Signed URLs, downloaded in container |
|
||||
| Channel adapters | Custom per-platform | Chat SDK bridge + standard interface |
|
||||
| Routing | Host checks registeredGroups map | Channel adapter extracts IDs, host maps to entities |
|
||||
| Concurrency | GroupQueue (in-memory) | Chat SDK per-channel + container limits |
|
||||
| Session scoping | One session per agent group folder | Per-session DB, multiple sessions per agent group |
|
||||
- Host ↔ container IO through mounted session DBs (`messages_in` / `messages_out`) — no stdin piping, no IPC files
|
||||
- Agent commands are `messages_out` rows with `kind: 'system'`
|
||||
- Agent-to-agent supported via target-agent routing on `messages_out`
|
||||
- Scheduling uses `process_after` / `deliver_after` + `recurrence` on the same message tables
|
||||
- Media via signed URLs, downloaded in the container
|
||||
- Channel adapters use the Chat SDK bridge + a standard interface (trunk ships only the bridge/registry; platform adapters install via `/add-<channel>` skills)
|
||||
- Routing: channel adapter extracts IDs, host maps to entities
|
||||
- Concurrency: Chat SDK per-channel + container limits
|
||||
- Session scoping: per-session DB, multiple sessions per agent group
|
||||
|
||||
## Design Decisions
|
||||
|
||||
@@ -463,7 +456,7 @@ Typing indicators: host sets typing when a container is active for a session, cl
|
||||
|
||||
### Message Batching
|
||||
|
||||
When multiple messages arrive while the container is down, they accumulate as `handled = 0` rows in messages_in. When the container wakes up, the agent-runner queries all unhandled messages and processes them as a batch — same as v1 where multiple messages are formatted into a single `<messages>` XML block.
|
||||
When multiple messages arrive while the container is down, they accumulate as `handled = 0` rows in messages_in. When the container wakes up, the agent-runner queries all unhandled messages and processes them as a batch — multiple messages are formatted into a single `<messages>` XML block.
|
||||
|
||||
### Message Lifecycle
|
||||
|
||||
@@ -523,11 +516,11 @@ NanoClaw is customized via skills — branches that get merged into the user's i
|
||||
- One line in the barrel file (`channels/index.ts`) to import the self-registering module
|
||||
- Zero changes to routing, formatting, delivery, or container code
|
||||
|
||||
### v1 Conflict Hotspots and v2 Solutions
|
||||
### Conflict Hotspots and Solutions
|
||||
|
||||
Analysis of 33 skill branches shows these files cause the most merge conflicts:
|
||||
|
||||
| v1 hotspot | Why it conflicts | v2 solution |
|
||||
| Hotspot | Why it conflicts | Solution |
|
||||
|-----------|-----------------|-------------|
|
||||
| `src/index.ts` (2000 LOC) | Every skill patches the main loop, imports, init logic | Thin index that wires modules. Logic lives in purpose-specific files (router, delivery, session-manager, host-sweep). |
|
||||
| `src/config.ts` | Every skill adds env vars to a central file | Config declared where it's used. Each module reads its own env vars. No central config registry that every skill edits. |
|
||||
@@ -566,9 +559,9 @@ Shared config (DATA_DIR, TIMEZONE, MAX_CONCURRENT_CONTAINERS) stays in `config.t
|
||||
|
||||
### Code Style
|
||||
|
||||
**Line width: 120 characters.** v1 uses the prettier default of 80, which breaks simple log calls and function signatures across 3-4 lines. v2 uses 120 — most statements fit on one line without sacrificing readability.
|
||||
**Line width: 120 characters.** Most statements fit on one line without sacrificing readability.
|
||||
|
||||
**Concise logging.** v1 has 138 log calls, many spanning 3-4 lines due to pino's structured API + 80-char wrapping. v2 uses a thin wrapper so every log call is one line:
|
||||
**Concise logging.** A thin wrapper keeps every log call on one line:
|
||||
|
||||
```typescript
|
||||
log.info('IPC message sent', { chatJid, sourceGroup });
|
||||
@@ -578,7 +571,7 @@ log.error('Error processing', { file, err });
|
||||
|
||||
### DB File Structure
|
||||
|
||||
v1's DB is one 750-line file with all tables, all CRUD functions, and all migrations inline. v2 splits by entity:
|
||||
The DB layer is split by entity rather than kept in one monolithic file:
|
||||
|
||||
```
|
||||
src/db/
|
||||
@@ -586,7 +579,7 @@ src/db/
|
||||
schema.ts ← CREATE TABLE statements (current state, for reference)
|
||||
migrations/
|
||||
index.ts ← runner: checks version, applies pending
|
||||
001-initial.ts ← v2 initial schema
|
||||
001-initial.ts ← initial schema
|
||||
002-pending-questions.ts ← example: adds pending_questions table
|
||||
... ← skills append new numbered files
|
||||
agent-groups.ts ← CRUD for agent_groups
|
||||
@@ -598,7 +591,7 @@ src/db/
|
||||
**Principles:**
|
||||
- **Split by entity, not by layer.** Each entity file has its own CRUD functions (~50-100 lines). A skill that adds a column to messaging_groups edits `messaging-groups.ts` — doesn't touch sessions or agent groups.
|
||||
- **Schema as current state + migrations as history.** `schema.ts` documents what the DB looks like now (read this to understand the schema). Migrations are append-only numbered files that describe how we got here.
|
||||
- **No inline ALTER TABLE.** v1 accumulates `try { ALTER TABLE } catch { /* exists */ }` blocks forever. v2 uses a migration runner with a `schema_version` table. On startup, it checks the current version and applies pending migrations in order. Each migration is a function: `(db: Database) => void`.
|
||||
- **No inline ALTER TABLE.** A migration runner with a `schema_version` table replaces `try { ALTER TABLE } catch { /* exists */ }` blocks. On startup, it checks the current version and applies pending migrations in order. Each migration is a function: `(db: Database) => void`.
|
||||
- **Skills add migrations.** A skill that needs a new column adds a new numbered migration file. No conflicts with other skills' migrations as long as numbers don't collide (use timestamps or high-enough numbers for skill branches).
|
||||
|
||||
**Agent-runner session DB** uses the same pattern but lighter — no migrations needed since session DBs are created fresh by the host:
|
||||
@@ -795,18 +788,6 @@ stopped → running → idle → stopped
|
||||
- **idle**: Done processing, container still warm (up to 30 min timeout). Polled at 1s so new messages are picked up quickly.
|
||||
- After idle timeout → host kills container → stopped.
|
||||
|
||||
### Migration from v1
|
||||
|
||||
| v1 table | v2 |
|
||||
|----------|-----|
|
||||
| `registered_groups` | Split into `agent_groups` + `messaging_groups` + `messaging_group_agents` |
|
||||
| `chats` | Absorbed into `messaging_groups` |
|
||||
| `messages` | Content moves to per-session DBs (messages_in) |
|
||||
| `sessions` (folder → sdk_session_id) | New `sessions` table (folder derived from ID) |
|
||||
| `scheduled_tasks` | Moved to per-session DBs (messages_in with recurrence) |
|
||||
| `task_run_logs` | Dropped — results are in session DB messages_out |
|
||||
| `router_state` | Dropped — replaced by message status in session DBs |
|
||||
|
||||
## Agent-Runner Architecture
|
||||
|
||||
The agent-runner is the process inside the container. It mediates between the session DB and the Claude SDK — polling for work, formatting messages for the agent, translating tool calls into DB rows, and managing the agent lifecycle.
|
||||
@@ -815,13 +796,10 @@ The agent-runner is the process inside the container. It mediates between the se
|
||||
|
||||
All IO goes through the session DB. No stdin, no stdout markers, no IPC files.
|
||||
|
||||
| v1 | v2 |
|
||||
|----|----|
|
||||
| Initial input from stdin (JSON envelope) | Poll `messages_in` |
|
||||
| Follow-up messages from IPC files | Same poll — new rows appear |
|
||||
| Output via stdout markers | Write `messages_out` rows |
|
||||
| MCP tools write IPC files | MCP tools write DB rows |
|
||||
| `_close` sentinel signals shutdown | Host kills container (idle timeout) or agent-runner exits when no pending work |
|
||||
- Initial input and follow-ups: poll `messages_in`
|
||||
- Output: write `messages_out` rows
|
||||
- MCP tools: write DB rows (no IPC files)
|
||||
- Shutdown: host kills the container on idle timeout, or the agent-runner exits when there's no pending work
|
||||
|
||||
### Poll Loop
|
||||
|
||||
@@ -837,9 +815,9 @@ All IO goes through the session DB. No stdin, no stdout markers, no IPC files.
|
||||
|
||||
Agent-runner strips routing fields (`platform_id`, `channel_type`, `thread_id`) before formatting. The agent never sees routing info — it only sees content.
|
||||
|
||||
- **`chat`** — format into `<messages>` XML block (same as v1)
|
||||
- **`chat`** — format into `<messages>` XML block
|
||||
- **`chat-sdk`** — extract text, author, attachments from serialized message; format into `<messages>` XML
|
||||
- **`task`** — format as `[SCHEDULED TASK]` prefix + prompt. Run pre-script if present (same as v1).
|
||||
- **`task`** — format as `[SCHEDULED TASK]` prefix + prompt. Run pre-script if present.
|
||||
- **`webhook`** — format as `[WEBHOOK: source/event]` + JSON payload
|
||||
- **`system`** — host action results (e.g., "register_group succeeded"). Format as system context, not chat.
|
||||
|
||||
@@ -847,9 +825,9 @@ Mixed batches (e.g., a chat message + a system result both pending) are combined
|
||||
|
||||
### MCP Tools
|
||||
|
||||
All v1 IPC-file-based tools are replaced with direct DB writes.
|
||||
MCP tools write directly to the session DB.
|
||||
|
||||
**Carried over (new implementation):**
|
||||
**Core tools:**
|
||||
|
||||
| Tool | What it does |
|
||||
|------|-------------|
|
||||
@@ -870,7 +848,7 @@ All v1 IPC-file-based tools are replaced with direct DB writes.
|
||||
| `send_to_agent` | Write `messages_out` with `channel_type: 'agent'`, `platform_id: '{target}'` |
|
||||
| `send_card` | Write `messages_out` with card structure |
|
||||
|
||||
See [v2-agent-runner-details.md](v2-agent-runner-details.md) for full MCP tool parameter definitions.
|
||||
See [agent-runner-details.md](agent-runner-details.md) for full MCP tool parameter definitions.
|
||||
|
||||
### Cards
|
||||
|
||||
@@ -904,7 +882,7 @@ The command lists are hardcoded in the agent-runner. Admin verification: the hos
|
||||
|
||||
The agent-runner processes recurring task messages like any other messages_in row. After the agent-runner marks a recurring message as `completed`, the **host** handles inserting the next occurrence (new messages_in row with `process_after` advanced to next cron time). The agent-runner doesn't manage recurrence — it just processes what it finds.
|
||||
|
||||
Pre-scripts work the same as v1: if a task message has a `script` field, run it first. If `wakeAgent = false`, mark completed without invoking Claude.
|
||||
Pre-scripts: if a task message has a `script` field, run it first. If `wakeAgent = false`, mark completed without invoking Claude.
|
||||
|
||||
### Agent-to-Agent Messaging
|
||||
|
||||
@@ -912,9 +890,9 @@ Pre-scripts work the same as v1: if a task message has a `script` field, run it
|
||||
|
||||
**Inbound:** Messages from other agents arrive as normal `chat` messages_in rows. The content includes `sender` and `senderId` (e.g., `"senderId": "agent:pr-admin"`). No special formatting — the agent sees it as a chat message.
|
||||
|
||||
### What Stays From v1
|
||||
### Agent-Runner Properties
|
||||
|
||||
- AgentProvider interface wraps SDK-specific query logic (Claude, Codex, OpenCode)
|
||||
- AgentProvider interface wraps SDK-specific query logic (trunk ships the `claude` provider; additional providers like OpenCode install via `/add-<provider>` skills)
|
||||
- Session resume via provider-specific mechanisms
|
||||
- System prompt loading from CLAUDE.md files
|
||||
- PreCompact hook for transcript archiving (Claude provider)
|
||||
@@ -929,5 +907,5 @@ Pre-scripts work the same as v1: if a task message has a `script` field, run it
|
||||
|
||||
## Related Documents
|
||||
|
||||
- **[v2-api-details.md](v2-api-details.md)** — Channel adapter interface (NanoClaw + Chat SDK bridge), message content examples, host delivery logic
|
||||
- **[v2-agent-runner-details.md](v2-agent-runner-details.md)** — AgentProvider interface, MCP tools, message formatting, media handling, provider implementations (Claude, Codex, OpenCode)
|
||||
- **[api-details.md](api-details.md)** — Channel adapter interface (NanoClaw + Chat SDK bridge), message content examples, host delivery logic
|
||||
- **[agent-runner-details.md](agent-runner-details.md)** — AgentProvider interface, MCP tools, message formatting, media handling, provider implementations
|
||||
@@ -1,4 +1,4 @@
|
||||
# NanoClaw v2 Checklist
|
||||
# NanoClaw Checklist
|
||||
|
||||
Status: [x] done, [~] partial, [ ] not started
|
||||
|
||||
@@ -55,7 +55,7 @@ Status: [x] done, [~] partial, [ ] not started
|
||||
- [~] iMessage via Chat SDK (adapter + skill written, not tested)
|
||||
- [x] Backward compatibility with native channels (old adapters still work)
|
||||
- [x] Channel barrel wired (src/index.ts imports barrel, skills uncomment)
|
||||
- [x] Setup flow wired to v2 channels (channel skills + /manage-channels for registration + verify.ts checks all tokens)
|
||||
- [x] Setup flow wired to channels (channel skills + /manage-channels for registration + verify.ts checks all tokens)
|
||||
- [x] Channel Info metadata in each channel skill (type, terminology, how-to-find-id, isolation defaults)
|
||||
- [x] /manage-channels skill (wire channels to agent groups with three isolation levels)
|
||||
- [x] /init-first-agent skill (standalone first-agent bootstrap; walks the operator through channel pick → identity lookup → DM platform_id resolution → wire → welcome DM; fallback to telegram pair-code or "DM the bot first" lookup for channels without cold DM)
|
||||
@@ -253,9 +253,6 @@ Container skills live inside agent containers at runtime (`container/skills/`) a
|
||||
|
||||
## Migration
|
||||
|
||||
- [ ] v1 -> v2 migration skill
|
||||
- [ ] Database migration (v1 SQLite -> v2 central DB + session DBs)
|
||||
- [ ] Channel credential preservation
|
||||
- [ ] Custom skill/code porting
|
||||
- [ ] OneCLI migration check — determine if existing installs need OneCLI re-init (credentials re-scoped to new `agent_group.id` identifier, new SDK version, approval handler registered). If needed, add a migration step to `/update-nanoclaw` or a dedicated skill.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# NanoClaw v2 — Central DB Schema
|
||||
# NanoClaw — Central DB Schema
|
||||
|
||||
Complete reference for `data/v2.db`, the host-owned admin-plane database. Start with [v2-db.md](v2-db.md) for the three-DB overview, the map, and the cross-mount rules.
|
||||
Complete reference for `data/v2.db`, the host-owned admin-plane database. Start with [db.md](db.md) for the three-DB overview, the map, and the cross-mount rules.
|
||||
|
||||
Access layer: `src/db/`. Authoritative schema reference: `src/db/schema.ts` (comments only — actual creation runs via migrations in `src/db/migrations/`).
|
||||
|
||||
@@ -48,7 +48,7 @@ CREATE TABLE messaging_groups (
|
||||
|
||||
### 1.3 `messaging_group_agents`
|
||||
|
||||
Wiring: which agent group handles which messaging group. Many-to-many — the same channel can route to multiple agents (see [v2-isolation-model.md](v2-isolation-model.md)).
|
||||
Wiring: which agent group handles which messaging group. Many-to-many — the same channel can route to multiple agents (see [isolation-model.md](isolation-model.md)).
|
||||
|
||||
```sql
|
||||
CREATE TABLE messaging_group_agents (
|
||||
@@ -157,7 +157,7 @@ CREATE INDEX idx_sessions_lookup ON sessions(messaging_group_id, thread_id);
|
||||
```
|
||||
|
||||
- **Resolved by:** `resolveSession()` in `src/session-manager.ts`.
|
||||
- Creating a session also provisions the session folder and both session DBs via `initSessionFolder()` — see [v2-db-session.md](v2-db-session.md).
|
||||
- Creating a session also provisions the session folder and both session DBs via `initSessionFolder()` — see [db-session.md](db-session.md).
|
||||
|
||||
### 1.9 `pending_questions`
|
||||
|
||||
@@ -193,7 +193,7 @@ CREATE TABLE agent_destinations (
|
||||
CREATE INDEX idx_agent_dest_target ON agent_destinations(target_type, target_id);
|
||||
```
|
||||
|
||||
**Projection invariant (load-bearing).** The central table is the source of truth, but each running container reads from a projection in its own `inbound.db` (see [v2-db-session.md §2.3](v2-db-session.md#23-destinations)). Any code that mutates `agent_destinations` while a container is running must also call `writeDestinations()` (`src/session-manager.ts`) or the container will reject sends with stale data. Known call sites: `createMessagingGroupAgent()` in `src/db/messaging-groups.ts`, the `create_agent` system action in `src/delivery.ts`.
|
||||
**Projection invariant (load-bearing).** The central table is the source of truth, but each running container reads from a projection in its own `inbound.db` (see [db-session.md §2.3](db-session.md#23-destinations)). Any code that mutates `agent_destinations` while a container is running must also call `writeDestinations()` (`src/session-manager.ts`) or the container will reject sends with stale data. Known call sites: `createMessagingGroupAgent()` in `src/db/messaging-groups.ts`, the `create_agent` system action in `src/delivery.ts`.
|
||||
|
||||
Access layer: `src/db/agent-destinations.ts`.
|
||||
|
||||
@@ -253,7 +253,7 @@ Writer: `recordDroppedMessage()` in `src/db/dropped-messages.ts`. On conflict, b
|
||||
|
||||
### 1.13 Chat SDK bridge tables
|
||||
|
||||
State backing the `SqliteStateAdapter` used by the Chat SDK bridge (see [v2-api-details.md](v2-api-details.md)). NanoClaw code rarely touches these directly — they're owned by `src/state-sqlite.ts`.
|
||||
State backing the `SqliteStateAdapter` used by the Chat SDK bridge (see [api-details.md](api-details.md)). NanoClaw code rarely touches these directly — they're owned by `src/state-sqlite.ts`.
|
||||
|
||||
```sql
|
||||
CREATE TABLE chat_sdk_kv (
|
||||
@@ -306,7 +306,7 @@ Migrations live in `src/db/migrations/`, one file per migration. Runner: `runMig
|
||||
|
||||
| # | File | Introduces |
|
||||
|---|------|------------|
|
||||
| 001 | `001-initial.ts` | Core v2 tables: `agent_groups`, `messaging_groups`, `messaging_group_agents`, `users`, `user_roles`, `agent_group_members`, `user_dms`, `sessions`, `pending_questions` |
|
||||
| 001 | `001-initial.ts` | Core tables: `agent_groups`, `messaging_groups`, `messaging_group_agents`, `users`, `user_roles`, `agent_group_members`, `user_dms`, `sessions`, `pending_questions` |
|
||||
| 002 | `002-chat-sdk-state.ts` | `chat_sdk_kv`, `chat_sdk_subscriptions`, `chat_sdk_locks`, `chat_sdk_lists` |
|
||||
| 003 | `003-pending-approvals.ts` | `pending_approvals` (session-bound + OneCLI fields) |
|
||||
| 004 | `004-agent-destinations.ts` | `agent_destinations` + backfill from existing `messaging_group_agents` wirings |
|
||||
@@ -314,6 +314,6 @@ Migrations live in `src/db/migrations/`, one file per migration. Runner: `runMig
|
||||
| 008 | `008-dropped-messages.ts` | `unregistered_senders` |
|
||||
| 009 | `009-drop-pending-credentials.ts` | Drop the defunct `pending_credentials` table |
|
||||
|
||||
Numbers 005 and 006 are intentionally absent — migrations were renumbered during v2 development.
|
||||
Numbers 005 and 006 are intentionally absent — migrations were renumbered during early development.
|
||||
|
||||
Session DB schemas (`INBOUND_SCHEMA`, `OUTBOUND_SCHEMA`) are **not** versioned here. They're `CREATE TABLE IF NOT EXISTS` so new columns land via the session-DB lazy migration helpers (`migrateDeliveredTable()` etc.) when a session file from an older build is reopened. See [v2-db-session.md](v2-db-session.md).
|
||||
Session DB schemas (`INBOUND_SCHEMA`, `OUTBOUND_SCHEMA`) are **not** versioned here. They're `CREATE TABLE IF NOT EXISTS` so new columns land via the session-DB lazy migration helpers (`migrateDeliveredTable()` etc.) when a session file from an older build is reopened. See [db-session.md](db-session.md).
|
||||
@@ -1,6 +1,6 @@
|
||||
# NanoClaw v2 — Per-Session DB Schema
|
||||
# NanoClaw — Per-Session DB Schema
|
||||
|
||||
Reference for the two SQLite files each session owns: `inbound.db` (host writes, container reads) and `outbound.db` (container writes, host reads). Start with [v2-db.md](v2-db.md) for the three-DB overview, the single-writer rule, and the cross-mount visibility constraints.
|
||||
Reference for the two SQLite files each session owns: `inbound.db` (host writes, container reads) and `outbound.db` (container writes, host reads). Start with [db.md](db.md) for the three-DB overview, the single-writer rule, and the cross-mount visibility constraints.
|
||||
|
||||
Schemas live in `src/db/schema.ts` as the `INBOUND_SCHEMA` and `OUTBOUND_SCHEMA` constants. Both files are created by `ensureSchema()` in `src/session-manager.ts` when a new session folder is provisioned.
|
||||
|
||||
@@ -50,7 +50,7 @@ CREATE TABLE messages_in (
|
||||
CREATE INDEX idx_messages_in_series ON messages_in(series_id);
|
||||
```
|
||||
|
||||
Content shapes: see [v2-api-details.md §Session DB Schema Details](v2-api-details.md#session-db-schema-details).
|
||||
Content shapes: see [api-details.md §Session DB Schema Details](api-details.md#session-db-schema-details).
|
||||
|
||||
**Writers (host):** `insertMessage()`, `insertTask()`, `insertRecurrence()` — all in `src/db/session-db.ts`. Each calls `nextEvenSeq()`.
|
||||
**Reader (container):** `container/agent-runner/src/db/messages-in.ts` — polls `status='pending' AND (process_after IS NULL OR process_after <= now)`.
|
||||
@@ -72,7 +72,7 @@ Writer: `markDelivered()` / `markDeliveryFailed()` in `src/db/session-db.ts`. Ol
|
||||
|
||||
### 2.3 `destinations`
|
||||
|
||||
Projection of the central `agent_destinations` table (see [v2-db-central.md §1.10](v2-db-central.md#110-agent_destinations)) for this session's agent. The container resolves `to="name"` against this table; if the row is absent, the send is rejected as `unknown destination`.
|
||||
Projection of the central `agent_destinations` table (see [db-central.md §1.10](db-central.md#110-agent_destinations)) for this session's agent. The container resolves `to="name"` against this table; if the row is absent, the send is rejected as `unknown destination`.
|
||||
|
||||
```sql
|
||||
CREATE TABLE destinations (
|
||||
@@ -141,7 +141,7 @@ CREATE TABLE messages_out (
|
||||
);
|
||||
```
|
||||
|
||||
Content shapes: see [v2-api-details.md §Session DB Schema Details](v2-api-details.md#session-db-schema-details).
|
||||
Content shapes: see [api-details.md §Session DB Schema Details](api-details.md#session-db-schema-details).
|
||||
|
||||
**Writer (container):** `writeMessageOut()` in `container/agent-runner/src/db/messages-out.ts`.
|
||||
**Readers (host):** `src/delivery.ts` (polling delivery), `getMessageIdBySeq()` / `getRoutingBySeq()` for edit/reaction targeting.
|
||||
@@ -1,17 +1,17 @@
|
||||
# NanoClaw v2 Database Architecture — Overview
|
||||
# NanoClaw Database Architecture — Overview
|
||||
|
||||
Orientation for the v2 data model: the three databases, how they fit together, and the invariants that hold across them. For table-level schemas, follow the links below.
|
||||
Orientation for the data model: the three databases, how they fit together, and the invariants that hold across them. For table-level schemas, follow the links below.
|
||||
|
||||
- **[v2-db-central.md](v2-db-central.md)** — every table in `data/v2.db` (identity, wiring, approvals, Chat SDK state) plus the migration system.
|
||||
- **[v2-db-session.md](v2-db-session.md)** — the per-session `inbound.db` + `outbound.db` pair, seq parity, and session folder layout.
|
||||
- **[db-central.md](db-central.md)** — every table in `data/v2.db` (identity, wiring, approvals, Chat SDK state) plus the migration system.
|
||||
- **[db-session.md](db-session.md)** — the per-session `inbound.db` + `outbound.db` pair, seq parity, and session folder layout.
|
||||
|
||||
Related: [v2-architecture-draft.md](v2-architecture-draft.md) for the high-level design; [v2-api-details.md](v2-api-details.md) for inbound/outbound message content shapes; [v2-isolation-model.md](v2-isolation-model.md) for channel-to-agent wiring modes.
|
||||
Related: [architecture.md](architecture.md) for the high-level design; [api-details.md](api-details.md) for inbound/outbound message content shapes; [isolation-model.md](isolation-model.md) for channel-to-agent wiring modes.
|
||||
|
||||
---
|
||||
|
||||
## 1. The three databases
|
||||
|
||||
v2 uses **three kinds of SQLite database**, all on the host filesystem:
|
||||
NanoClaw uses **three kinds of SQLite database**, all on the host filesystem:
|
||||
|
||||
| DB | Location | Writer | Readers | Purpose |
|
||||
|----|----------|--------|---------|---------|
|
||||
@@ -73,7 +73,7 @@ Session DBs are bind-mounted into the container. A few rules you need to know be
|
||||
|
||||
- **`journal_mode = DELETE`, not WAL.** WAL files don't reliably cross the mount and the container can read stale pages. DELETE mode forces each writer to flush the main file.
|
||||
- **Open-write-close on the host.** Host-side writes to `inbound.db` open a connection, write, and close it. Keeping a handle open makes cached pages invisible to the container.
|
||||
- **Container reads read-only.** The container opens `inbound.db` with `readonly: true` and never writes — all container→host state goes through `outbound.db` (see `processing_ack` in [v2-db-session.md](v2-db-session.md#52-processing_ack)).
|
||||
- **Container reads read-only.** The container opens `inbound.db` with `readonly: true` and never writes — all container→host state goes through `outbound.db` (see `processing_ack` in [db-session.md](db-session.md#52-processing_ack)).
|
||||
- **Heartbeat is a file touch.** `.heartbeat` mtime is the liveness signal, not a DB column. A DB write per heartbeat would serialize behind other writers.
|
||||
|
||||
These rules are enforced by convention in `src/session-manager.ts` and `container/agent-runner/src/db/`. If you change how the DBs are opened, re-read that code first.
|
||||
@@ -83,7 +83,7 @@ These rules are enforced by convention in `src/session-manager.ts` and `containe
|
||||
## 5. Design patterns at a glance
|
||||
|
||||
1. **Two-DB session split.** `inbound.db` and `outbound.db` each have one writer, one direction of flow — no cross-mount lock contention.
|
||||
2. **Seq parity.** Even = host, odd = container. Disjoint namespace across both tables lets the agent reference any message by `seq` alone. Details in [v2-db-session.md §3](v2-db-session.md#3-sequence-numbering-invariant).
|
||||
2. **Seq parity.** Even = host, odd = container. Disjoint namespace across both tables lets the agent reference any message by `seq` alone. Details in [db-session.md §3](db-session.md#3-sequence-numbering-invariant).
|
||||
3. **Projection pattern.** `agent_destinations` and `session_routing` are projected from the central DB into each session's `inbound.db` on container wake — the container gets a fast, local read path without querying across the mount.
|
||||
4. **Ack via reverse channel.** Container never writes to `inbound.db`. Status sync happens through `processing_ack` in `outbound.db`, which the host polls and reconciles.
|
||||
5. **Heartbeat out of band.** File `touch` on `.heartbeat`, not a DB write, so liveness doesn't serialize behind other writers.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Channel Isolation Model
|
||||
|
||||
NanoClaw v2 decouples messaging channels from agent groups. When you connect a channel (Discord, Telegram, Slack, GitHub, etc.), you decide how it relates to your existing agents. There are three isolation levels.
|
||||
NanoClaw decouples messaging channels from agent groups. When you connect a channel (Discord, Telegram, Slack, GitHub, etc.), you decide how it relates to your existing agents. There are three isolation levels.
|
||||
|
||||
## The Three Levels
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# v2 Setup Wiring — Status & Remaining Work
|
||||
# Setup Wiring — Status & Remaining Work
|
||||
|
||||
Last updated: 2026-04-09, branch `v2`, commit `1dc5750`
|
||||
Last updated: 2026-04-09
|
||||
|
||||
## What's Done
|
||||
|
||||
@@ -13,7 +13,7 @@ Last updated: 2026-04-09, branch `v2`, commit `1dc5750`
|
||||
- Host sweep reads `processing_ack` table + heartbeat file mtime for stale detection
|
||||
- Container clears stale `processing_ack` entries on startup (crash recovery)
|
||||
- Files: `src/db/schema.ts` (INBOUND_SCHEMA + OUTBOUND_SCHEMA), `src/session-manager.ts`, `src/delivery.ts`, `src/host-sweep.ts`, `container/agent-runner/src/db/connection.ts`, `messages-in.ts`, `messages-out.ts`, `poll-loop.ts`, `mcp-tools/scheduling.ts`, `mcp-tools/interactive.ts`
|
||||
- Container image rebuilt with tsconfig excluding v1 (`container/agent-runner/tsconfig.json`)
|
||||
- Container image rebuilt with tsconfig (`container/agent-runner/tsconfig.json`)
|
||||
- E2E verified: host → Docker container → Claude responds → "E2E works!" ✓
|
||||
|
||||
### OneCLI Integration
|
||||
@@ -23,14 +23,14 @@ Last updated: 2026-04-09, branch `v2`, commit `1dc5750`
|
||||
|
||||
### Channel Barrel
|
||||
- `src/index.ts` imports `./channels/index.js` (the barrel)
|
||||
- Channel skills uncomment lines in the barrel to enable channels
|
||||
- Discord is uncommented by default (it was previously a direct import in index.ts)
|
||||
- Trunk ships the barrel + Chat SDK bridge only; `/add-<channel>` skills drop adapter files in and register them via the barrel slot
|
||||
- No channel adapters ship in trunk
|
||||
|
||||
### Setup Registration (partially)
|
||||
- `setup/register.ts` rewritten to create v2 entities (`agent_groups`, `messaging_groups`, `messaging_group_agents`) in `data/v2.db`
|
||||
- Accepts `--platform-id` (v2) and `--jid` (v1 compat) flags
|
||||
- Added `getMessagingGroupAgentByPair()` to prevent duplicate wiring
|
||||
- `setup/verify.ts` updated to check v2 central DB (counts agent groups with wiring)
|
||||
- `setup/register.ts` creates entities (`agent_groups`, `messaging_groups`, `messaging_group_agents`) in `data/v2.db`
|
||||
- Accepts `--platform-id` flag
|
||||
- `getMessagingGroupAgentByPair()` prevents duplicate wiring
|
||||
- `setup/verify.ts` checks the central DB (counts agent groups with wiring)
|
||||
|
||||
### Router Logging
|
||||
- `src/router.ts` logs `MESSAGE DROPPED` at WARN level when no agents wired, with actionable guidance
|
||||
@@ -39,27 +39,23 @@ Last updated: 2026-04-09, branch `v2`, commit `1dc5750`
|
||||
|
||||
## Previously Open — Now Resolved
|
||||
|
||||
### 1. ~~v2 Channel Skills Don't Register Groups~~ ✅
|
||||
### 1. ~~Channel Skills Don't Register Groups~~ ✅
|
||||
|
||||
Channel skills now point to `/manage-channels` in their "Next Steps" section. Registration is handled by the `/manage-channels` skill, which reads each channel's `## Channel Info` section for platform-specific guidance. Channel skills stay lean (credentials only).
|
||||
|
||||
### 2. ~~v1 add-discord Skill is Incompatible~~ ✅
|
||||
|
||||
Created `/add-discord-v2` skill matching the v2 pattern. Setup SKILL.md updated to reference `/add-discord-v2`.
|
||||
|
||||
### 3. ~~Setup SKILL.md Missing Group Registration Step~~ ✅
|
||||
### 2. ~~Setup SKILL.md Missing Group Registration Step~~ ✅
|
||||
|
||||
Added step 5a "Wire Channels to Agent Groups" between channel installation (step 5) and mount allowlist (step 6). This step invokes `/manage-channels` which handles agent group creation, isolation level decisions, and wiring.
|
||||
|
||||
### 4. ~~Channel Skills Should Know Channel Type~~ ✅
|
||||
### 3. ~~Channel Skills Should Know Channel Type~~ ✅
|
||||
|
||||
Each v2 channel skill now has a `## Channel Info` structured section with: type, terminology, how-to-find-id, supports-threads, typical-use, default-isolation. The `/manage-channels` skill reads this for contextual recommendations.
|
||||
Each channel skill has a `## Channel Info` structured section with: type, terminology, how-to-find-id, supports-threads, typical-use, default-isolation. The `/manage-channels` skill reads this for contextual recommendations.
|
||||
|
||||
### 5. ~~Verify Step Channel Auth Check~~ ✅
|
||||
### 4. ~~Verify Step Channel Auth Check~~ ✅
|
||||
|
||||
`setup/verify.ts` now checks all v2 channel tokens: DISCORD_BOT_TOKEN, TELEGRAM_BOT_TOKEN, SLACK_BOT_TOKEN+SLACK_APP_TOKEN, GITHUB_TOKEN, LINEAR_API_KEY, GCHAT_CREDENTIALS, TEAMS_APP_ID+TEAMS_APP_PASSWORD, WEBEX_BOT_TOKEN, MATRIX_ACCESS_TOKEN, RESEND_API_KEY, WHATSAPP_ACCESS_TOKEN, IMESSAGE_ENABLED, plus WhatsApp Baileys auth dir.
|
||||
`setup/verify.ts` checks all channel tokens: DISCORD_BOT_TOKEN, TELEGRAM_BOT_TOKEN, SLACK_BOT_TOKEN+SLACK_APP_TOKEN, GITHUB_TOKEN, LINEAR_API_KEY, GCHAT_CREDENTIALS, TEAMS_APP_ID+TEAMS_APP_PASSWORD, WEBEX_BOT_TOKEN, MATRIX_ACCESS_TOKEN, RESEND_API_KEY, WHATSAPP_ACCESS_TOKEN, IMESSAGE_ENABLED, plus WhatsApp Baileys auth dir.
|
||||
|
||||
### 6. Agent-Shared Session Mode ✅
|
||||
### 5. Agent-Shared Session Mode ✅
|
||||
|
||||
Added `session_mode: 'agent-shared'` for cross-channel shared sessions (e.g. GitHub + Slack in one conversation). Session resolution looks up by agent_group_id instead of messaging_group_id when this mode is set.
|
||||
|
||||
@@ -67,7 +63,7 @@ Added `session_mode: 'agent-shared'` for cross-channel shared sessions (e.g. Git
|
||||
|
||||
## Architecture Reference
|
||||
|
||||
### v2 Entity Model
|
||||
### Entity Model
|
||||
```
|
||||
agent_groups (id, name, folder, agent_provider, container_config)
|
||||
↕ many-to-many
|
||||
@@ -93,13 +89,13 @@ Channel adapter → routeInbound() → resolve messaging_group → resolve agent
|
||||
### Key Files
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/index.ts` | v2 entry point, imports channel barrel |
|
||||
| `src/channels/index.ts` | Channel barrel — uncomment to enable |
|
||||
| `src/index.ts` | Entry point, imports channel barrel |
|
||||
| `src/channels/index.ts` | Channel barrel — registry/Chat SDK bridge only in trunk; skills drop adapters in |
|
||||
| `src/router.ts` | Inbound routing, auto-creates messaging groups |
|
||||
| `src/session-manager.ts` | Creates inbound.db + outbound.db per session |
|
||||
| `src/delivery.ts` | Polls outbound.db, delivers, handles system actions |
|
||||
| `src/host-sweep.ts` | Syncs processing_ack, stale detection, recurrence |
|
||||
| `src/container-runner.ts` | Spawns containers, OneCLI ensureAgent + applyContainerConfig |
|
||||
| `setup/register.ts` | Creates v2 entities (agent_group, messaging_group, wiring) |
|
||||
| `setup/verify.ts` | Checks v2 central DB for registered groups |
|
||||
| `setup/register.ts` | Creates entities (agent_group, messaging_group, wiring) |
|
||||
| `setup/verify.ts` | Checks central DB for registered groups |
|
||||
| `container/agent-runner/src/db/connection.ts` | Two-DB connection layer (inbound read-only, outbound read-write) |
|
||||
Reference in New Issue
Block a user