mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-06-04 10:14:47 +08:00
docs: update for container config DB, on-wake, and CLI scope
- CLAUDE.md: new key files, updated groups verbs, rewritten self-mod section, new Container Config and Container Restart sections - db-central.md: container_configs table (§1.15), migrations 014+015 - db-session.md: messages_in schema with trigger, source_session_id, on_wake columns - schema.ts: comment no longer references disk-based config - cli.instructions.md: rewritten for scope-aware usage, auto-fill, restart/config ops, group-scoped examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,7 +72,10 @@ For ad-hoc queries from skills or scripts, use the in-tree wrapper rather than t
|
||||
| `src/onecli-approvals.ts` | OneCLI credentialed-action approval bridge |
|
||||
| `src/user-dm.ts` | Cold-DM resolution + `user_dms` cache |
|
||||
| `src/group-init.ts` | Per-agent-group filesystem scaffold (CLAUDE.md, skills, agent-runner-src overlay) |
|
||||
| `src/db/` | DB layer — agent_groups, messaging_groups, sessions, user_roles, user_dms, pending_*, migrations |
|
||||
| `src/db/container-configs.ts` | CRUD for `container_configs` table (per-group container runtime config) |
|
||||
| `src/backfill-container-configs.ts` | Migrates legacy `container.json` files into the DB on startup |
|
||||
| `src/container-restart.ts` | Kill + on-wake respawn for agent group containers |
|
||||
| `src/db/` | DB layer — agent_groups, messaging_groups, sessions, container_configs, user_roles, user_dms, pending_*, migrations |
|
||||
| `src/channels/` | Channel adapter infra (registry, Chat SDK bridge); specific channel adapters are skill-installed from the `channels` branch |
|
||||
| `src/providers/` | Host-side provider container-config (`claude` baked in; `opencode` etc. installed from the `providers` branch) |
|
||||
| `container/agent-runner/src/` | Agent-runner: poll loop, formatter, provider abstraction, MCP tools, destinations |
|
||||
@@ -93,7 +96,7 @@ ncl help
|
||||
|
||||
| Resource | Verbs | What it is |
|
||||
|----------|-------|------------|
|
||||
| groups | list, get, create, update, delete | Agent groups (workspace, personality, container config) |
|
||||
| groups | list, get, create, update, delete, restart, config get/update, config add-mcp-server/remove-mcp-server, config add-package/remove-package | Agent groups (workspace, personality, container config) |
|
||||
| messaging-groups | list, get, create, update, delete | A single chat/channel on one platform |
|
||||
| wirings | list, get, create, update, delete | Links a messaging group to an agent group (session mode, triggers) |
|
||||
| users | list, get, create, update | Platform identities (`<channel>:<handle>`) |
|
||||
@@ -120,10 +123,32 @@ Each `/add-<name>` skill is idempotent: `git fetch origin <branch>` → copy mod
|
||||
|
||||
One tier of agent self-modification today:
|
||||
|
||||
1. **`install_packages` / `add_mcp_server`** — changes to the per-agent-group container config only (apt/npm deps, wire an existing MCP server). Single admin approval per request; on approve, the handler in `src/modules/self-mod/apply.ts` rebuilds the image when needed (`install_packages` only) and restarts the container. `container/agent-runner/src/mcp-tools/self-mod.ts`.
|
||||
1. **`install_packages` / `add_mcp_server`** — changes to the per-agent-group container config in the DB (apt/npm deps, wire an existing MCP server). Single admin approval per request; on approve, the handler in `src/modules/self-mod/apply.ts` rebuilds the image when needed (`install_packages` only), writes an `on_wake` message, kills the container, and respawns via `onExit` callback. The on-wake message is only picked up by the fresh container's first poll — dying containers can never steal it. `container/agent-runner/src/mcp-tools/self-mod.ts`.
|
||||
|
||||
A second tier (direct source-level self-edits via a draft/activate flow) is planned but not yet implemented.
|
||||
|
||||
## Container Config
|
||||
|
||||
Per-agent-group container runtime config (provider, model, packages, MCP servers, mounts, etc.) lives in the `container_configs` table in the central DB. Materialized to `groups/<folder>/container.json` at spawn time so the container runner can read it. Managed via `ncl groups config get/update` and the self-mod MCP tools.
|
||||
|
||||
**`cli_scope`** — controls what the agent can do with `ncl` from inside the container:
|
||||
|
||||
| Value | Behavior |
|
||||
|-------|----------|
|
||||
| `disabled` | Agent never learns about ncl (instructions excluded from CLAUDE.md). Host dispatch rejects any `cli_request`. |
|
||||
| `group` (default) | Agent can access `groups`, `sessions`, `destinations`, `members` only, scoped to its own agent group. `--id` and group args are auto-filled. Cross-group access rejected. `cli_scope` changes blocked. |
|
||||
| `global` | Unrestricted. Set automatically for owner agent groups via `init-first-agent`. |
|
||||
|
||||
Key files: `src/db/container-configs.ts`, `src/container-config.ts`, `src/cli/dispatch.ts` (scope enforcement), `src/claude-md-compose.ts` (instructions exclusion).
|
||||
|
||||
## Container Restart
|
||||
|
||||
`ncl groups restart --id <group-id> [--rebuild] [--message <text>]`. Kills running containers; if `--message` is provided, writes an `on_wake` message and respawns via `onExit` callback. Without `--message`, containers come back on the next user message. From inside a container, `--id` is auto-filled and only the calling session is restarted.
|
||||
|
||||
The `on_wake` column on `messages_in` ensures wake messages are only picked up by a fresh container's first poll iteration. This prevents the race where a dying container (still in its SIGTERM grace period) could steal the message. `killContainer` accepts an optional `onExit` callback that fires after the process exits, guaranteeing the old container is gone before the new one spawns.
|
||||
|
||||
Key files: `src/container-restart.ts`, `src/container-runner.ts` (`killContainer`), `container/agent-runner/src/db/messages-in.ts` (`getPendingMessages`).
|
||||
|
||||
## Secrets / Credentials / OneCLI
|
||||
|
||||
API keys, OAuth tokens, and auth credentials are managed by the OneCLI gateway. Secrets are injected into per-agent containers at request time — none are passed in env vars or through chat context. The container agent sees this via the `onecli-gateway` container skill (`container/skills/onecli-gateway/SKILL.md`), which teaches it how the proxy works, how to handle auth errors, and to never ask for raw credentials. Host-side wiring: `src/onecli-approvals.ts`, `ensureAgent()` in `container-runner.ts`. Run `onecli --help`.
|
||||
|
||||
@@ -1,49 +1,51 @@
|
||||
## Admin CLI (`ncl`)
|
||||
|
||||
The `ncl` command is available at `/usr/local/bin/ncl`. It lets you query and modify NanoClaw's central configuration — agent groups, messaging groups, wirings, users, roles, and more.
|
||||
The `ncl` command is available at `/usr/local/bin/ncl`. It lets you query and modify NanoClaw's central configuration.
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
ncl <resource> <verb> [<id>] [--flags]
|
||||
ncl <resource> <verb> [--flags]
|
||||
ncl <resource> help
|
||||
ncl help
|
||||
```
|
||||
|
||||
### Scope
|
||||
|
||||
Your CLI access may be scoped. Run `ncl help` to see which resources are available and whether args are auto-filled. Under `group` scope (the default), `--id` and group-related args are auto-filled to your agent group — you don't need to pass them.
|
||||
|
||||
### Resources
|
||||
|
||||
Run `ncl help` for the full list. Common resources:
|
||||
|
||||
| Resource | Verbs | What it is |
|
||||
|----------|-------|------------|
|
||||
| groups | list, get, create, update, delete | Agent groups (workspace, personality, container config) |
|
||||
| messaging-groups | list, get, create, update, delete | A single chat/channel on one platform |
|
||||
| wirings | list, get, create, update, delete | Links a messaging group to an agent group (session mode, triggers) |
|
||||
| users | list, get, create, update | Platform identities (`<channel>:<handle>`) |
|
||||
| roles | list, grant, revoke | Owner / admin privileges (global or scoped to an agent group) |
|
||||
| members | list, add, remove | Unprivileged access gate for an agent group |
|
||||
| destinations | list, add, remove | Where an agent group can send messages |
|
||||
| groups | list, get, create, update, delete, restart, config get/update, config add-mcp-server/remove-mcp-server, config add-package/remove-package | Agent groups (workspace, personality, container config) |
|
||||
| sessions | list, get | Active sessions (read-only) |
|
||||
| user-dms | list | Cold-DM cache (read-only) |
|
||||
| dropped-messages | list | Messages from unregistered senders (read-only) |
|
||||
| approvals | list, get | Pending approval requests (read-only) |
|
||||
| destinations | list, add, remove | Where an agent group can send messages |
|
||||
| members | list, add, remove | Unprivileged access gate for an agent group |
|
||||
|
||||
Additional resources (available under `global` scope only): messaging-groups, wirings, users, roles, user-dms, dropped-messages, approvals.
|
||||
|
||||
### When to use
|
||||
|
||||
- **Looking up your own config** — `ncl groups get <your-group-id>` to see your agent group settings.
|
||||
- **Finding who you're wired to** — `ncl wirings list` to see which messaging groups route to which agent groups.
|
||||
- **Checking user roles** — `ncl roles list` to see who is an owner/admin.
|
||||
- **Answering questions about the system** — when the user asks about groups, channels, users, or configuration, query `ncl` rather than guessing.
|
||||
- **Looking up your own config** — `ncl groups get` or `ncl groups config get` to see your container config.
|
||||
- **Restarting your container** — `ncl groups restart` (with optional `--rebuild` and `--message`).
|
||||
- **Checking who's in your group** — `ncl members list`.
|
||||
- **Seeing your destinations** — `ncl destinations list`.
|
||||
- **Answering questions about the system** — query `ncl` rather than guessing.
|
||||
|
||||
### Access rules
|
||||
|
||||
Read commands (list, get) are open. Write commands (create, update, delete, grant, revoke, add, remove) require admin approval — the request is held until an admin approves it.
|
||||
Read commands (list, get) are open. Write commands (create, update, delete, restart, config update, add, remove) require admin approval — the request is held until an admin approves it.
|
||||
|
||||
### Approval flow
|
||||
|
||||
Write commands (create, update, delete, grant, revoke, add, remove) require admin approval. Here's what happens:
|
||||
Write commands require admin approval. Here's what happens:
|
||||
|
||||
1. You run the command (e.g. `ncl groups create --name "Research" --folder research`).
|
||||
1. You run the command (e.g. `ncl groups config update --model claude-sonnet-4-5-20250514`).
|
||||
2. The command returns immediately with an `approval-pending` response — it has **not** been executed yet.
|
||||
3. An admin or owner gets a notification (on the same channel when possible) showing exactly what you requested, with approve/reject options.
|
||||
3. An admin or owner gets a notification showing exactly what you requested, with approve/reject options.
|
||||
4. Once the admin responds:
|
||||
- **Approved:** the command executes and the result is delivered back to you as a system message in this conversation.
|
||||
- **Rejected:** you get a system message saying the request was rejected.
|
||||
@@ -54,25 +56,24 @@ You don't need to poll or retry — the result arrives automatically.
|
||||
|
||||
```bash
|
||||
# Read commands (no approval needed)
|
||||
ncl groups list
|
||||
ncl groups get abc123
|
||||
ncl wirings list --messaging-group-id mg_xyz
|
||||
ncl roles list
|
||||
ncl wirings help
|
||||
ncl groups get
|
||||
ncl groups config get
|
||||
ncl sessions list
|
||||
ncl destinations list
|
||||
ncl members list
|
||||
|
||||
# Write commands (approval required)
|
||||
ncl groups create --name "Research" --folder research
|
||||
ncl groups update abc123 --name "Research v2"
|
||||
ncl roles grant --user telegram:jane --role admin
|
||||
ncl roles grant --user discord:bob --role admin --group abc123
|
||||
ncl members add --user-id telegram:jane --agent-group-id abc123
|
||||
ncl destinations add --agent-group-id abc123 --messaging-group-id mg_xyz
|
||||
ncl groups restart
|
||||
ncl groups restart --rebuild --message "Config updated."
|
||||
ncl groups config update --model claude-sonnet-4-5-20250514
|
||||
ncl groups config add-mcp-server --name rss --command npx --args '["some-rss-mcp"]'
|
||||
ncl groups config add-package --npm some-package
|
||||
ncl members add --user telegram:jane
|
||||
```
|
||||
|
||||
### Tips
|
||||
|
||||
- Use `ncl <resource> help` to see all available fields, types, enums, and which fields are required or updatable.
|
||||
- Use `ncl <resource> help` to see all available fields, types, enums, and which fields are auto-filled.
|
||||
- Flags use `--hyphen-case` (e.g. `--agent-group-id`), mapped to `underscore_case` DB columns automatically.
|
||||
- `list` supports filtering by any non-auto column (e.g. `ncl wirings list --messaging-group-id mg_xyz`). Default limit is 200 rows; override with `--limit N`.
|
||||
- For composite-key resources (roles, members, destinations), use the custom verbs (grant/revoke, add/remove) instead of create/delete.
|
||||
- `list` supports filtering by any non-auto column. Default limit is 200 rows; override with `--limit N`.
|
||||
- Write commands return `approval-pending` immediately — don't treat this as an error. Wait for the system message with the result.
|
||||
|
||||
+29
-1
@@ -10,7 +10,7 @@ Access layer: `src/db/`. Authoritative schema reference: `src/db/schema.ts` (com
|
||||
|
||||
### 1.1 `agent_groups`
|
||||
|
||||
Agent workspaces. Each maps 1:1 to a `groups/<folder>/` directory containing `CLAUDE.md`, skills, and `container.json`. Container config lives on disk, not in the DB.
|
||||
Agent workspaces. Each maps 1:1 to a `groups/<folder>/` directory containing `CLAUDE.md` and skills. Container config lives in `container_configs` (see §1.x below); a `container.json` file is materialized at spawn time for the container runner to read.
|
||||
|
||||
```sql
|
||||
CREATE TABLE agent_groups (
|
||||
@@ -294,6 +294,32 @@ CREATE TABLE schema_version (
|
||||
);
|
||||
```
|
||||
|
||||
### 1.15 `container_configs`
|
||||
|
||||
Per-agent-group container runtime config. Source of truth for provider, model, packages, MCP servers, mounts, CLI scope, etc. Materialized to `groups/<folder>/container.json` at spawn time.
|
||||
|
||||
```sql
|
||||
CREATE TABLE container_configs (
|
||||
agent_group_id TEXT PRIMARY KEY REFERENCES agent_groups(id) ON DELETE CASCADE,
|
||||
provider TEXT,
|
||||
model TEXT,
|
||||
effort TEXT,
|
||||
image_tag TEXT,
|
||||
assistant_name TEXT,
|
||||
max_messages_per_prompt INTEGER,
|
||||
skills TEXT NOT NULL DEFAULT '"all"',
|
||||
mcp_servers TEXT NOT NULL DEFAULT '{}',
|
||||
packages_apt TEXT NOT NULL DEFAULT '[]',
|
||||
packages_npm TEXT NOT NULL DEFAULT '[]',
|
||||
additional_mounts TEXT NOT NULL DEFAULT '[]',
|
||||
cli_scope TEXT NOT NULL DEFAULT 'group', -- disabled | group | global
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
- **Readers:** `src/container-config.ts`, `src/container-runner.ts`, `src/cli/dispatch.ts` (scope enforcement), `src/claude-md-compose.ts`
|
||||
- **Writers:** `src/db/container-configs.ts`, `src/modules/self-mod/apply.ts`, `src/backfill-container-configs.ts`
|
||||
|
||||
---
|
||||
|
||||
## 2. Migration system
|
||||
@@ -313,6 +339,8 @@ Migrations live in `src/db/migrations/`, one file per migration. Runner: `runMig
|
||||
| 007 | `007-pending-approvals-title-options.ts` | `ALTER TABLE pending_approvals` add `title`, `options_json` (retrofits DBs created between 003 and 007) |
|
||||
| 008 | `008-dropped-messages.ts` | `unregistered_senders` |
|
||||
| 009 | `009-drop-pending-credentials.ts` | Drop the defunct `pending_credentials` table |
|
||||
| 014 | `014-container-configs.ts` | `container_configs` — per-agent-group container runtime config |
|
||||
| 015 | `015-cli-scope.ts` | `ALTER TABLE container_configs ADD COLUMN cli_scope` |
|
||||
|
||||
Numbers 005 and 006 are intentionally absent — migrations were renumbered during early development.
|
||||
|
||||
|
||||
+16
-13
@@ -33,19 +33,22 @@ Every message landing in the session: user chat, scheduled task, recurring task,
|
||||
|
||||
```sql
|
||||
CREATE TABLE messages_in (
|
||||
id TEXT PRIMARY KEY,
|
||||
seq INTEGER UNIQUE, -- EVEN only (host assigns) — see §3
|
||||
kind TEXT NOT NULL,
|
||||
timestamp TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'pending', -- pending|completed|failed|paused
|
||||
process_after TEXT,
|
||||
recurrence TEXT, -- cron expr for recurring
|
||||
series_id TEXT, -- groups occurrences of a recurring task
|
||||
tries INTEGER DEFAULT 0,
|
||||
platform_id TEXT,
|
||||
channel_type TEXT,
|
||||
thread_id TEXT,
|
||||
content TEXT NOT NULL -- JSON; shape depends on kind
|
||||
id TEXT PRIMARY KEY,
|
||||
seq INTEGER UNIQUE, -- EVEN only (host assigns) — see §3
|
||||
kind TEXT NOT NULL,
|
||||
timestamp TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'pending', -- pending|completed|failed|paused
|
||||
process_after TEXT,
|
||||
recurrence TEXT, -- cron expr for recurring
|
||||
series_id TEXT, -- groups occurrences of a recurring task
|
||||
tries INTEGER DEFAULT 0,
|
||||
trigger INTEGER NOT NULL DEFAULT 1, -- 0 = context only (don't wake), 1 = wake agent
|
||||
platform_id TEXT,
|
||||
channel_type TEXT,
|
||||
thread_id TEXT,
|
||||
content TEXT NOT NULL, -- JSON; shape depends on kind
|
||||
source_session_id TEXT, -- agent-to-agent return path
|
||||
on_wake INTEGER NOT NULL DEFAULT 0 -- 1 = only deliver on container's first poll
|
||||
);
|
||||
CREATE INDEX idx_messages_in_series ON messages_in(series_id);
|
||||
```
|
||||
|
||||
+1
-2
@@ -7,8 +7,7 @@
|
||||
export const SCHEMA = `
|
||||
-- Agent workspaces: folder, skills, CLAUDE.md.
|
||||
-- All workspaces are equal; privilege lives on users, not groups.
|
||||
-- Container config (mcpServers, packages, imageTag, additionalMounts) lives
|
||||
-- in groups/<folder>/container.json on disk, not in the DB.
|
||||
-- Container config lives in the container_configs table (see migration 014).
|
||||
CREATE TABLE agent_groups (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user