@flame0510/project-aether 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -0
- package/agent-templates/README.md +37 -0
- package/agent-templates/argus/AGENTS.md +52 -0
- package/agent-templates/argus/IDENTITY.md +7 -0
- package/agent-templates/argus/MEMORY.md +9 -0
- package/agent-templates/argus/SOUL.md +24 -0
- package/agent-templates/argus/TOOLS.md +8 -0
- package/agent-templates/atlas/AGENTS.md +47 -0
- package/agent-templates/atlas/HEARTBEAT.md +10 -0
- package/agent-templates/atlas/IDENTITY.md +6 -0
- package/agent-templates/atlas/MEMORY.md +9 -0
- package/agent-templates/atlas/SOUL.md +21 -0
- package/agent-templates/atlas/TOOLS.md +4 -0
- package/agent-templates/base-image/.trigger +0 -0
- package/agent-templates/base-image/Dockerfile +90 -0
- package/agent-templates/base-image/entrypoint.sh +37 -0
- package/agent-templates/custom/AGENTS.md +29 -0
- package/agent-templates/custom/BOOTSTRAP.md +56 -0
- package/agent-templates/custom/MEMORY.md +8 -0
- package/agent-templates/prometheus/AGENTS.md +37 -0
- package/agent-templates/prometheus/IDENTITY.md +6 -0
- package/agent-templates/prometheus/MEMORY.md +9 -0
- package/agent-templates/prometheus/SOUL.md +21 -0
- package/agent-templates/prometheus/TOOLS.md +4 -0
- package/app/agents/ChannelManager.tsx +465 -0
- package/app/agents/ImageDownloadBanner.tsx +159 -0
- package/app/agents/PageClient.tsx +1285 -0
- package/app/agents/create/PageClient.tsx +437 -0
- package/app/agents/create/page.tsx +126 -0
- package/app/agents/loading.tsx +14 -0
- package/app/agents/page.tsx +5 -0
- package/app/api/agents/[id]/backup/route.ts +169 -0
- package/app/api/agents/[id]/channels/pairing/route.ts +69 -0
- package/app/api/agents/[id]/channels/route.ts +14 -0
- package/app/api/agents/[id]/channels/telegram/route.ts +50 -0
- package/app/api/agents/[id]/lifecycle/route.ts +94 -0
- package/app/api/agents/[id]/recreate/route.ts +199 -0
- package/app/api/agents/[id]/restart/route.ts +33 -0
- package/app/api/agents/[id]/restore/route.ts +81 -0
- package/app/api/agents/[id]/route.ts +280 -0
- package/app/api/agents/channels-summary/route.ts +39 -0
- package/app/api/agents/config-json/route.ts +58 -0
- package/app/api/agents/create/route.ts +488 -0
- package/app/api/agents/download-image/route.ts +32 -0
- package/app/api/agents/image-status/route.ts +126 -0
- package/app/api/agents/route.ts +213 -0
- package/app/api/agents/token/route.ts +94 -0
- package/app/api/agents-active/route.ts +190 -0
- package/app/api/agents-config/route.ts +629 -0
- package/app/api/alerts/smoke/route.ts +26 -0
- package/app/api/aliases/add/route.ts +28 -0
- package/app/api/aliases/remove/route.ts +27 -0
- package/app/api/assistant/route.ts +204 -0
- package/app/api/auth/check/route.ts +38 -0
- package/app/api/auth/login/route.ts +85 -0
- package/app/api/auth/logout/route.ts +7 -0
- package/app/api/auth/status/route.ts +33 -0
- package/app/api/config/env/route.ts +132 -0
- package/app/api/config/restart/route.ts +26 -0
- package/app/api/containers/route.ts +75 -0
- package/app/api/cost-override/route.ts +46 -0
- package/app/api/costs/route.ts +84 -0
- package/app/api/credentials/[id]/reveal/route.ts +21 -0
- package/app/api/credentials/[id]/route.ts +52 -0
- package/app/api/credentials/[id]/sync/route.ts +58 -0
- package/app/api/credentials/detect/route.ts +246 -0
- package/app/api/credentials/route.ts +33 -0
- package/app/api/crons/[id]/route.ts +69 -0
- package/app/api/crons/route.ts +12 -0
- package/app/api/crons/runs/route.ts +31 -0
- package/app/api/debug/route.ts +11 -0
- package/app/api/envcheck/route.ts +18 -0
- package/app/api/events/route.ts +24 -0
- package/app/api/gateway/agent/route.ts +154 -0
- package/app/api/gateway/provider/balance/route.ts +38 -0
- package/app/api/gateway/provider/keys.ts +38 -0
- package/app/api/gateway/provider/oauth/route.ts +304 -0
- package/app/api/gateway/provider/route.ts +209 -0
- package/app/api/gateway/route.ts +223 -0
- package/app/api/gateway/sync.ts +189 -0
- package/app/api/lineage/route.ts +54 -0
- package/app/api/memory-context/route.ts +15 -0
- package/app/api/metrics/route.ts +35 -0
- package/app/api/models/route.ts +77 -0
- package/app/api/plugins/route.js +37 -0
- package/app/api/provider/upstream.ts +142 -0
- package/app/api/provider/v1/chat/completions/route.ts +146 -0
- package/app/api/provider/v1/models/route.ts +167 -0
- package/app/api/provider-usage/route.ts +629 -0
- package/app/api/session/route.ts +39 -0
- package/app/api/sessions/[id]/route.ts +38 -0
- package/app/api/sessions/route.ts +23 -0
- package/app/api/setup/agent-image/route.ts +102 -0
- package/app/api/setup/password/route.ts +111 -0
- package/app/api/setup/restart/route.ts +76 -0
- package/app/api/skills/delete/route.js +105 -0
- package/app/api/skills/promote/route.js +129 -0
- package/app/api/skills/route.js +203 -0
- package/app/api/skills/save/route.js +142 -0
- package/app/api/stats/route.ts +34 -0
- package/app/api/stats-since/route.ts +20 -0
- package/app/api/stream/route.ts +70 -0
- package/app/api/system-health/route.ts +233 -0
- package/app/api/tool-calls/route.ts +24 -0
- package/app/api/tools-config/route.ts +163 -0
- package/app/api/update-check/route.ts +127 -0
- package/app/api/version/route.ts +25 -0
- package/app/api/wizard/complete/route.ts +32 -0
- package/app/api/wizard/reset/route.ts +28 -0
- package/app/api/wizard/status/route.ts +28 -0
- package/app/api/workspace/route.ts +392 -0
- package/app/api/workspace/stream/route.ts +136 -0
- package/app/components/AppShell.tsx +33 -0
- package/app/components/AuthGuard.tsx +91 -0
- package/app/components/CostBreakdown.tsx +37 -0
- package/app/components/DashboardHeader.tsx +73 -0
- package/app/components/DashboardLayout.tsx +76 -0
- package/app/components/DashboardToolbar.tsx +61 -0
- package/app/components/FloatingActions.tsx +33 -0
- package/app/components/Icons.tsx +78 -0
- package/app/components/LineageGraphPage.tsx +142 -0
- package/app/components/LiveFeed.tsx +48 -0
- package/app/components/MobileBottomNav.tsx +84 -0
- package/app/components/ModelPickerModal.tsx +94 -0
- package/app/components/PasswordInput.tsx +86 -0
- package/app/components/PulseChat.tsx +362 -0
- package/app/components/Rev4aLoader.tsx +48 -0
- package/app/components/SessionDrawer.tsx +263 -0
- package/app/components/SessionTopology.tsx +289 -0
- package/app/components/Sidebar.tsx +294 -0
- package/app/components/Skeleton.tsx +133 -0
- package/app/components/SystemCockpit.tsx +169 -0
- package/app/components/VersionBanner.tsx +105 -0
- package/app/components/WizardButton.tsx +30 -0
- package/app/components/ui/Badge.tsx +30 -0
- package/app/components/ui/Button.tsx +59 -0
- package/app/components/ui/ConfirmModal.tsx +46 -0
- package/app/components/ui/FilterBar.tsx +33 -0
- package/app/components/ui/Input.tsx +25 -0
- package/app/components/ui/ItemList.tsx +83 -0
- package/app/components/ui/LoadingSpinner.tsx +30 -0
- package/app/components/ui/Metric.tsx +22 -0
- package/app/components/ui/Modal.tsx +42 -0
- package/app/components/ui/Page.tsx +18 -0
- package/app/components/ui/Pill.tsx +6 -0
- package/app/components/ui/PropertyList.tsx +24 -0
- package/app/components/ui/Select.tsx +26 -0
- package/app/components/ui/StatusCard.tsx +32 -0
- package/app/components/ui/Surface.tsx +14 -0
- package/app/components/ui/Tabs.tsx +55 -0
- package/app/components/ui/TemplateOption.tsx +59 -0
- package/app/components/ui/Toast.tsx +44 -0
- package/app/components/ui/index.ts +19 -0
- package/app/components/ui/tokens.ts +18 -0
- package/app/config/PageClient.tsx +293 -0
- package/app/config/loading.tsx +10 -0
- package/app/config/page.tsx +7 -0
- package/app/containers/ContainersClient.tsx +129 -0
- package/app/containers/loading.tsx +21 -0
- package/app/containers/page.tsx +5 -0
- package/app/containers/terminal/[id]/TerminalClient.tsx +313 -0
- package/app/containers/terminal/[id]/page.tsx +6 -0
- package/app/credentials/PageClient.tsx +598 -0
- package/app/credentials/loading.tsx +10 -0
- package/app/credentials/page.tsx +7 -0
- package/app/crons/PageClient.tsx +538 -0
- package/app/crons/loading.tsx +10 -0
- package/app/crons/page.tsx +5 -0
- package/app/design-system.ts +57 -0
- package/app/gateway/PageClient.tsx +1048 -0
- package/app/gateway/loading.tsx +24 -0
- package/app/gateway/page.tsx +5 -0
- package/app/globals.css +1474 -0
- package/app/layout.tsx +45 -0
- package/app/lib/models-context.tsx +41 -0
- package/app/lineage/loading.tsx +10 -0
- package/app/lineage/page.tsx +13 -0
- package/app/loading.tsx +16 -0
- package/app/login/page.tsx +160 -0
- package/app/memory/MemoryContextPageClient.tsx +196 -0
- package/app/memory/loading.tsx +10 -0
- package/app/memory/page.tsx +8 -0
- package/app/page.tsx +31 -0
- package/app/plugins/PageClient.tsx +296 -0
- package/app/plugins/loading.tsx +10 -0
- package/app/plugins/page.tsx +5 -0
- package/app/setup/PageClient.tsx +227 -0
- package/app/setup/loading.tsx +21 -0
- package/app/setup/page.tsx +7 -0
- package/app/skills/PageClient.tsx +499 -0
- package/app/skills/loading.tsx +10 -0
- package/app/skills/page.tsx +5 -0
- package/app/tools/ToolsPageClient.tsx +308 -0
- package/app/tools/loading.tsx +10 -0
- package/app/tools/page.tsx +62 -0
- package/app/tools/tools-catalog.ts +141 -0
- package/app/wizard/PageClient.tsx +485 -0
- package/app/wizard/icons.tsx +89 -0
- package/app/wizard/loading.tsx +24 -0
- package/app/wizard/page.tsx +7 -0
- package/app/wizard/storage.ts +33 -0
- package/app/wizard/useWizard.ts +101 -0
- package/app/workspace/WorkspaceClient.tsx +633 -0
- package/app/workspace/loading.tsx +36 -0
- package/app/workspace/page.tsx +8 -0
- package/bin/docker-entrypoint.sh +21 -0
- package/bin/postinstall.js +20 -0
- package/bin/rev4a.js +696 -0
- package/daemon.js +783 -0
- package/docs/ARCHITECTURE.md +557 -0
- package/docs/CONTAINER-TERMINAL.md +280 -0
- package/docs/DESIGN-SYSTEM.md +99 -0
- package/docs/FRONTEND-ARCHITECTURE.md +119 -0
- package/docs/REV4A.md +504 -0
- package/docs/dev/API-REFERENCE.md +1835 -0
- package/docs/dev/DATABASE.md +224 -0
- package/docs/dev/GATEWAY.md +300 -0
- package/docs/dev/PROVIDERS.md +229 -0
- package/docs/dev/SESSION-MAINTENANCE-PLAN.md +607 -0
- package/docs/dev/WORKSPACE.md +199 -0
- package/docs/rag/DATA-FRESHNESS.md +109 -0
- package/docs/rag/GLOSSARY.md +125 -0
- package/docs/rag/REV4A-OVERVIEW.md +135 -0
- package/docs/rag/WHAT-I-CAN-ANSWER.md +124 -0
- package/lib/agent-setup.ts +130 -0
- package/lib/alerts.ts +115 -0
- package/lib/apiFetch.ts +7 -0
- package/lib/auth.ts +28 -0
- package/lib/billing.ts +100 -0
- package/lib/buildAgentImage.ts +346 -0
- package/lib/channelManager.ts +386 -0
- package/lib/container.ts +60 -0
- package/lib/credentials/db.ts +86 -0
- package/lib/credentials/delivery.ts +448 -0
- package/lib/credentials/detect.ts +149 -0
- package/lib/credentials/hash.ts +9 -0
- package/lib/credentials/providers.ts +110 -0
- package/lib/credentials/vault.ts +195 -0
- package/lib/db-bootstrap.d.ts +3 -0
- package/lib/db-bootstrap.mjs +144 -0
- package/lib/db.ts +25 -0
- package/lib/docker-utils.ts +60 -0
- package/lib/hooks/useDashboard.ts +264 -0
- package/lib/hooks/useRev4aTimezone.ts +28 -0
- package/lib/hooks/useScreenshot.ts +30 -0
- package/lib/memory-context.ts +385 -0
- package/lib/model-catalogue.ts +131 -0
- package/lib/model-pricing.ts +63 -0
- package/lib/openclaw-cron.ts +350 -0
- package/lib/patterns/ApiAdapter.ts +73 -0
- package/lib/patterns/ApiClient.ts +65 -0
- package/lib/patterns/EventBus.ts +113 -0
- package/lib/patterns/FilterStrategy.ts +79 -0
- package/lib/patterns/SessionFactory.ts +117 -0
- package/lib/patterns/sessionPresentation.ts +117 -0
- package/lib/provider-balance.ts +163 -0
- package/lib/requireAuth.tsx +38 -0
- package/lib/rev4a-auth.d.ts +3 -0
- package/lib/rev4a-auth.js +36 -0
- package/lib/rev4a-paths.ts +145 -0
- package/lib/timezone.ts +46 -0
- package/lib/types/index.ts +96 -0
- package/lib/utils/format.ts +82 -0
- package/lineage.js +56 -0
- package/model-pricing.json +482 -0
- package/models.config.json +844 -0
- package/next-env.d.ts +6 -0
- package/next.config.mjs +7 -0
- package/package.json +82 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-64.png +0 -0
- package/public/favicon.svg +58 -0
- package/public/icon-192-maskable.png +0 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512-maskable.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/manifest.json +38 -0
- package/public/rev4a-logo.png +0 -0
- package/public/rev4a-logo.svg +58 -0
- package/rev4a-rules/AGENTS.md +37 -0
- package/scripts/add-auth.cjs +185 -0
- package/scripts/backup.sh +66 -0
- package/scripts/check-providers.mjs +143 -0
- package/scripts/docker/traefik/docker-compose.yml +32 -0
- package/scripts/docker/traefik/dynamic/.gitkeep +18 -0
- package/scripts/docker/traefik/traefik.yml +37 -0
- package/scripts/remove-auth-profile.js +56 -0
- package/scripts/restore.sh +82 -0
- package/terminal-ws-server.js +139 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Rev4a — Database Reference
|
|
2
|
+
|
|
3
|
+
> **Last updated:** 2026-06-30
|
|
4
|
+
|
|
5
|
+
Rev4a uses a single SQLite file (`events.db`) in WAL mode.
|
|
6
|
+
|
|
7
|
+
## Location
|
|
8
|
+
|
|
9
|
+
| Environment | Path |
|
|
10
|
+
|---|---|
|
|
11
|
+
| VPS (default) | `/path/to/rev4a/data/events.db` |
|
|
12
|
+
| Custom | Set `REV4A_DB` env var |
|
|
13
|
+
|
|
14
|
+
## WAL Mode
|
|
15
|
+
|
|
16
|
+
```sql
|
|
17
|
+
PRAGMA journal_mode = WAL;
|
|
18
|
+
PRAGMA synchronous = NORMAL;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- The daemon writes; the Next.js API routes open read-only connections
|
|
22
|
+
- `PRAGMA wal_checkpoint(PASSIVE)` runs after each daemon poll cycle
|
|
23
|
+
- WAL files: `events.db-shm`, `events.db-wal` — do not delete while daemon is running
|
|
24
|
+
|
|
25
|
+
## Tables
|
|
26
|
+
|
|
27
|
+
### `sessions` — primary session tracking
|
|
28
|
+
|
|
29
|
+
```sql
|
|
30
|
+
CREATE TABLE sessions (
|
|
31
|
+
session_id TEXT PRIMARY KEY,
|
|
32
|
+
parent_id TEXT,
|
|
33
|
+
label TEXT,
|
|
34
|
+
model TEXT,
|
|
35
|
+
tokens_in INTEGER DEFAULT 0,
|
|
36
|
+
tokens_out INTEGER DEFAULT 0,
|
|
37
|
+
cost_usd REAL DEFAULT 0,
|
|
38
|
+
status TEXT DEFAULT 'idle',
|
|
39
|
+
task_preview TEXT,
|
|
40
|
+
started_at INTEGER, -- Unix seconds
|
|
41
|
+
ended_at INTEGER, -- Unix seconds, null if active
|
|
42
|
+
updated_at INTEGER, -- Unix ms, updated only on real changes
|
|
43
|
+
trello_card_url TEXT
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE INDEX idx_sessions_updated ON sessions(updated_at);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Status values:** `idle` / `working` / `completed` / `error`
|
|
50
|
+
|
|
51
|
+
### `events` — lifecycle events
|
|
52
|
+
|
|
53
|
+
```sql
|
|
54
|
+
CREATE TABLE events (
|
|
55
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
|
+
ts INTEGER NOT NULL, -- Unix ms
|
|
57
|
+
session_id TEXT NOT NULL,
|
|
58
|
+
type TEXT NOT NULL, -- spawn | complete | error | tool_call
|
|
59
|
+
data TEXT -- JSON payload
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE INDEX idx_events_session ON events(session_id, ts);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `lineage` — explicit parent→child declarations
|
|
66
|
+
|
|
67
|
+
```sql
|
|
68
|
+
CREATE TABLE lineage (
|
|
69
|
+
child_id TEXT PRIMARY KEY,
|
|
70
|
+
parent_id TEXT,
|
|
71
|
+
agent_name TEXT,
|
|
72
|
+
declared_at INTEGER -- Unix ms
|
|
73
|
+
);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Populated by agents calling `lineage.js` at spawn time or via `POST /api/lineage`.
|
|
77
|
+
|
|
78
|
+
### `cost_override` — manual monthly billing corrections
|
|
79
|
+
|
|
80
|
+
```sql
|
|
81
|
+
CREATE TABLE cost_override (
|
|
82
|
+
month TEXT PRIMARY KEY, -- YYYY-MM
|
|
83
|
+
amount REAL,
|
|
84
|
+
note TEXT,
|
|
85
|
+
updated_at INTEGER -- Unix ms
|
|
86
|
+
);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When a `cost_override` row exists for the current month, the UI displays the override value instead of the computed sum.
|
|
90
|
+
|
|
91
|
+
### `system_metrics` — infrastructure metrics
|
|
92
|
+
|
|
93
|
+
```sql
|
|
94
|
+
CREATE TABLE system_metrics (
|
|
95
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
96
|
+
ts INTEGER NOT NULL,
|
|
97
|
+
cpu_percent REAL,
|
|
98
|
+
ram_used_mb INTEGER,
|
|
99
|
+
ram_total_mb INTEGER,
|
|
100
|
+
disk_used_gb REAL,
|
|
101
|
+
disk_total_gb REAL,
|
|
102
|
+
load_avg_1m REAL
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
CREATE INDEX idx_metrics_ts ON system_metrics(ts);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Rows older than 24 h are pruned automatically by the daemon.
|
|
109
|
+
|
|
110
|
+
## Useful Queries
|
|
111
|
+
|
|
112
|
+
```sql
|
|
113
|
+
-- Total cost this month
|
|
114
|
+
SELECT SUM(cost_usd) FROM sessions
|
|
115
|
+
WHERE started_at >= strftime('%s', date('now', 'start of month'));
|
|
116
|
+
|
|
117
|
+
-- Active sessions right now
|
|
118
|
+
SELECT session_id, label, model, status, cost_usd
|
|
119
|
+
FROM sessions WHERE status = 'working';
|
|
120
|
+
|
|
121
|
+
-- Cost by model (all time)
|
|
122
|
+
SELECT model, SUM(cost_usd) AS total, COUNT(*) AS sessions
|
|
123
|
+
FROM sessions GROUP BY model ORDER BY total DESC;
|
|
124
|
+
|
|
125
|
+
-- Last poll time (freshness check)
|
|
126
|
+
SELECT datetime(MAX(ts)/1000, 'unixepoch', 'localtime') AS last_event
|
|
127
|
+
FROM events;
|
|
128
|
+
|
|
129
|
+
-- Lineage tree for a session
|
|
130
|
+
WITH RECURSIVE tree(child_id, parent_id, agent_name, depth) AS (
|
|
131
|
+
SELECT child_id, parent_id, agent_name, 0 FROM lineage WHERE child_id = 'agent:ops:main'
|
|
132
|
+
UNION ALL
|
|
133
|
+
SELECT l.child_id, l.parent_id, l.agent_name, t.depth + 1
|
|
134
|
+
FROM lineage l JOIN tree t ON l.parent_id = t.child_id
|
|
135
|
+
)
|
|
136
|
+
SELECT * FROM tree;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Backup
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Manual snapshot
|
|
143
|
+
sqlite3 events.db ".backup events.db.bak-$(date +%s)"
|
|
144
|
+
|
|
145
|
+
# Automated (via backup.sh in repo root)
|
|
146
|
+
bash /data/.openclaw/workspace-ops/rev4a-next-ts/backup.sh
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Backups are stored in `backups/` inside the repo directory.
|
|
150
|
+
|
|
151
|
+
## Credentials Database (`credentials.db`)
|
|
152
|
+
|
|
153
|
+
The credential hub uses a **separate SQLite file** (`credentials.db`) alongside
|
|
154
|
+
events.db in the same data directory. It stores credentials that can be synced
|
|
155
|
+
to agent containers via CLI auth or env files.
|
|
156
|
+
|
|
157
|
+
**Location:** `data/credentials.db` (same directory as `events.db`)
|
|
158
|
+
**Custom path:** Set `REV4A_CREDENTIALS_DB` env var to override.
|
|
159
|
+
**WAL mode:** Enabled.
|
|
160
|
+
|
|
161
|
+
### `credential_profiles` — credential hub metadata
|
|
162
|
+
|
|
163
|
+
```sql
|
|
164
|
+
CREATE TABLE credential_profiles (
|
|
165
|
+
id TEXT PRIMARY KEY,
|
|
166
|
+
provider_id TEXT NOT NULL,
|
|
167
|
+
label TEXT NOT NULL,
|
|
168
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
169
|
+
secret_masked TEXT,
|
|
170
|
+
created_at INTEGER NOT NULL,
|
|
171
|
+
updated_at INTEGER NOT NULL,
|
|
172
|
+
last_synced_at INTEGER
|
|
173
|
+
);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### `credential_secrets` — stored secret payloads
|
|
177
|
+
|
|
178
|
+
```sql
|
|
179
|
+
CREATE TABLE credential_secrets (
|
|
180
|
+
profile_id TEXT PRIMARY KEY,
|
|
181
|
+
payload TEXT NOT NULL
|
|
182
|
+
);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Payloads are stored as JSON strings. In a future release they will be AES-256-GCM encrypted.
|
|
186
|
+
|
|
187
|
+
### `credential_audit_log` — append-only audit trail
|
|
188
|
+
|
|
189
|
+
```sql
|
|
190
|
+
CREATE TABLE credential_audit_log (
|
|
191
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
192
|
+
ts INTEGER NOT NULL,
|
|
193
|
+
actor TEXT NOT NULL,
|
|
194
|
+
action TEXT NOT NULL,
|
|
195
|
+
profile_id TEXT,
|
|
196
|
+
result TEXT
|
|
197
|
+
);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Actions: `create`, `update`, `delete`, `sync`, `reveal`.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Migrations
|
|
205
|
+
|
|
206
|
+
The daemon applies these migrations safely at startup:
|
|
207
|
+
|
|
208
|
+
```sql
|
|
209
|
+
ALTER TABLE sessions ADD COLUMN trello_card_url TEXT; -- idempotent
|
|
210
|
+
ALTER TABLE sessions ADD COLUMN ended_at INTEGER; -- idempotent
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
For future schema changes, add a `try/catch` ALTER TABLE block in `daemon.js` following the same pattern.
|
|
214
|
+
|
|
215
|
+
## Integrity Check
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
sqlite3 events.db "PRAGMA quick_check"
|
|
219
|
+
# Expected output: ok
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Current location on VPS:** `/path/to/rev4a/data/events.db`
|
|
223
|
+
|
|
224
|
+
The `REV4A_DB` env var is set in the systemd override file at `/etc/systemd/system/rev4a.service.d/env.conf`.
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# Gateway Page
|
|
2
|
+
|
|
3
|
+
> **Last updated:** 2026-07-31
|
|
4
|
+
|
|
5
|
+
The Gateway page (`/gateway`) is the central control panel for managing provider
|
|
6
|
+
configurations and agent model assignments across all Docker containers.
|
|
7
|
+
|
|
8
|
+
The Gateway aggregates multiple upstream AI providers (DeepSeek, OpenAI, Anthropic,
|
|
9
|
+
Kimi, GLM, Qwen, and others) behind a single Rev4a provider. Agent containers see
|
|
10
|
+
only `rev4a` as their provider and route all LLM traffic through the Rev4a proxy
|
|
11
|
+
at `/api/provider/v1/`.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Gateway Page
|
|
19
|
+
├── Provider Tab → Manage provider API keys, enable/disable models, push sync
|
|
20
|
+
└── Agents Tab → Change primary model per agent container
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The Gateway talks to each agent container directly via `docker exec`, reading and
|
|
24
|
+
writing to `/root/.openclaw/openclaw.json` inside the container.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Provider Tab
|
|
29
|
+
|
|
30
|
+
Lists all AI providers from `models.config.json` in the project root. Each provider
|
|
31
|
+
row shows:
|
|
32
|
+
|
|
33
|
+
- Provider name and label
|
|
34
|
+
- Configured API key (masked)
|
|
35
|
+
- Enable/disable toggles per model
|
|
36
|
+
- ADD / CHANGE / REMOVE KEY buttons
|
|
37
|
+
|
|
38
|
+
### Provider Key Storage
|
|
39
|
+
|
|
40
|
+
Provider API keys are stored in `data/provider-keys.json`:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"deepseek": "sk-...",
|
|
45
|
+
"openrouter": "sk-...",
|
|
46
|
+
"rev4a": "ciao"
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `rev4a` entry is the master gateway token. Agent containers authenticate
|
|
51
|
+
against the Rev4a provider proxy using this token. See [`PROVIDERS.md`](PROVIDERS.md).
|
|
52
|
+
|
|
53
|
+
### Sync Flow
|
|
54
|
+
|
|
55
|
+
When a provider key is saved or a model toggle is changed, the Gateway:
|
|
56
|
+
|
|
57
|
+
1. **Reads** `models.config.json` to get the full model catalogue
|
|
58
|
+
2. **Filters** enabled models for providers that have a configured API key
|
|
59
|
+
3. **Builds** a `models.providers.rev4a` config block (without `rev4a/` prefix
|
|
60
|
+
on model IDs)
|
|
61
|
+
4. **Writes** the block into `/root/.openclaw/openclaw.json` on every agent container
|
|
62
|
+
(containers with `AGENT_ID` Docker label)
|
|
63
|
+
5. **Cleans up** stale `models.json` and `auth-profiles.json` files inside each
|
|
64
|
+
container
|
|
65
|
+
6. **Writes** the block into `/root/.openclaw/openclaw.json` on every agent container
|
|
66
|
+
— **does NOT touch** `agents.defaults.model` or `agents.list[].model`
|
|
67
|
+
7. **Does NOT restart** the gateway — writes are live via file write
|
|
68
|
+
|
|
69
|
+
### Model ID Convention
|
|
70
|
+
|
|
71
|
+
Inside `models.providers.rev4a.models`, model IDs are stored **without** the
|
|
72
|
+
`rev4a/` prefix:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"models": {
|
|
77
|
+
"providers": {
|
|
78
|
+
"rev4a": {
|
|
79
|
+
"baseUrl": "http://host.docker.internal:3740/api/provider/v1",
|
|
80
|
+
"api": "openai-completions",
|
|
81
|
+
"apiKey": "***",
|
|
82
|
+
"models": [
|
|
83
|
+
{ "id": "deepseek/deepseek-v4-flash", "name": "DeepSeek V4 Flash" },
|
|
84
|
+
{ "id": "deepseek/deepseek-v4-pro", "name": "DeepSeek V4 Pro" }
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
OpenClaw automatically prefixes model IDs with the provider name at runtime,
|
|
93
|
+
producing `rev4a/deepseek/deepseek-v4-flash`. The `mode` field is **not** set —
|
|
94
|
+
OpenClaw defaults to merging config models with auto-discovered models.
|
|
95
|
+
|
|
96
|
+
### Model Catalogue
|
|
97
|
+
|
|
98
|
+
The model catalogue lives in [`models.config.json`](../models.config.json) at the project root.
|
|
99
|
+
This file is **tracked in the repository** and serves as the default model configuration
|
|
100
|
+
for anyone cloning the project. It defines all known models across all providers:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"models": [
|
|
105
|
+
{ "id": "openai/gpt-5.6-sol", "name": "GPT-5.6 Sol", "provider": "openai", "enabled": true },
|
|
106
|
+
{ "id": "openai/gpt-5.6-terra", "name": "GPT-5.6 Terra", "provider": "openai", "enabled": true },
|
|
107
|
+
{ "id": "openai/gpt-5.6-luna", "name": "GPT-5.6 Luna", "provider": "openai", "enabled": true },
|
|
108
|
+
{ "id": "openai/gpt-5.5", "name": "GPT-5.5", "provider": "openai", "enabled": true },
|
|
109
|
+
{ "id": "openai/gpt-5.4", "name": "GPT-5.4", "provider": "openai", "enabled": true },
|
|
110
|
+
{ "id": "openai/gpt-5.4-mini", "name": "GPT-5.4 Mini", "provider": "openai", "enabled": true },
|
|
111
|
+
{ "id": "anthropic/claude-fable-5", "name": "Claude Fable 5", "provider": "anthropic", "enabled": false },
|
|
112
|
+
{ "id": "anthropic/claude-opus-5", "name": "Claude Opus 5", "provider": "anthropic", "enabled": false },
|
|
113
|
+
{ "id": "anthropic/claude-sonnet-5", "name": "Claude Sonnet 5", "provider": "anthropic", "enabled": false },
|
|
114
|
+
{ "id": "groq/llama-3.3-70b-versatile", "name": "Llama 3.3 70B (Groq)", "provider": "groq", "enabled": false },
|
|
115
|
+
{ "id": "kimi/kimi-k3", "name": "Kimi K3", "provider": "kimi", "enabled": true },
|
|
116
|
+
{ "id": "glm/glm-5.2", "name": "GLM-5.2", "provider": "glm", "enabled": false },
|
|
117
|
+
{ "id": "qwen/qwen3.7-plus", "name": "Qwen 3.7 Plus", "provider": "qwen", "enabled": true }
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Only enabled models for providers with a configured API key are synced to agent
|
|
123
|
+
containers.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Agents Tab
|
|
128
|
+
|
|
129
|
+
Lists all agent containers discovered from Docker (containers with `AGENT_ID`
|
|
130
|
+
label). Each agent row shows:
|
|
131
|
+
|
|
132
|
+
- Agent name and container name
|
|
133
|
+
- Current primary model
|
|
134
|
+
- "Change Model" button
|
|
135
|
+
|
|
136
|
+
### Change Model Flow
|
|
137
|
+
|
|
138
|
+
Clicking "Change Model" opens an inline form with:
|
|
139
|
+
|
|
140
|
+
1. **Primary model select** — dropdown of all enabled models (filtered to
|
|
141
|
+
configured providers only)
|
|
142
|
+
|
|
143
|
+
On save:
|
|
144
|
+
|
|
145
|
+
1. **PUT /api/gateway/agent** writes the model config to the container's
|
|
146
|
+
`openclaw.json`:
|
|
147
|
+
- `agents.defaults.model.primary` and `agents.list[0].model.primary` written
|
|
148
|
+
with format `rev4a/<provider>/<model>`
|
|
149
|
+
- No fallbacks are set unless explicitly provided
|
|
150
|
+
2. **No restart** — writes are live via `docker exec node -e`
|
|
151
|
+
|
|
152
|
+
### Model Select Filtering
|
|
153
|
+
|
|
154
|
+
The model select in the Agents tab only shows models whose provider has a
|
|
155
|
+
configured API key in `data/provider-keys.json`. This ensures users can only
|
|
156
|
+
select models that are actually available.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## API Endpoints
|
|
161
|
+
|
|
162
|
+
### `GET /api/gateway`
|
|
163
|
+
|
|
164
|
+
Returns live Gateway status from all agent containers. Reads agent model configs
|
|
165
|
+
via `openclaw models status --json` inside each container.
|
|
166
|
+
|
|
167
|
+
**Response:**
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"agents": {
|
|
171
|
+
"total": 1,
|
|
172
|
+
"list": [
|
|
173
|
+
{
|
|
174
|
+
"containerName": "openclaw-atlas",
|
|
175
|
+
"agentId": "atlas",
|
|
176
|
+
"agentName": "Atlas",
|
|
177
|
+
"defaultModel": "rev4a/deepseek/deepseek-v4-flash",
|
|
178
|
+
"configured": true
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `PUT /api/gateway/provider`
|
|
186
|
+
|
|
187
|
+
Triggers a full provider model sync to all agent containers. Only writes
|
|
188
|
+
`models.providers.rev4a` — does NOT touch model references.
|
|
189
|
+
|
|
190
|
+
**Body:** none (reads current provider state from `models.config.json` and
|
|
191
|
+
`data/provider-keys.json`)
|
|
192
|
+
|
|
193
|
+
**Response:**
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"status": "ok",
|
|
197
|
+
"activeModels": 2,
|
|
198
|
+
"results": ["Active models: 2 across 1 agent(s)"]
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### `PUT /api/gateway/agent`
|
|
203
|
+
|
|
204
|
+
Updates model config for a single agent container (primary model only).
|
|
205
|
+
|
|
206
|
+
**Body:**
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"containerName": "openclaw-atlas",
|
|
210
|
+
"model": "deepseek/deepseek-v4-flash"
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Response:**
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"status": "ok",
|
|
218
|
+
"agent": "openclaw-atlas",
|
|
219
|
+
"model": {
|
|
220
|
+
"primary": "rev4a/deepseek/deepseek-v4-flash"
|
|
221
|
+
},
|
|
222
|
+
"verify": { "ok": true, "bytes": 2058 }
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### `GET /api/gateway/provider`
|
|
227
|
+
|
|
228
|
+
Returns current provider configuration state.
|
|
229
|
+
|
|
230
|
+
**Response:**
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"providers": [
|
|
234
|
+
{
|
|
235
|
+
"provider": "deepseek",
|
|
236
|
+
"label": "DeepSeek",
|
|
237
|
+
"configured": true,
|
|
238
|
+
"baseUrl": "https://api.deepseek.com",
|
|
239
|
+
"models": [
|
|
240
|
+
{ "id": "deepseek/deepseek-v4-flash", "name": "DeepSeek V4 Flash", "enabled": true }
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Config Page (`/config`)
|
|
250
|
+
|
|
251
|
+
A companion page at `/config` that allows editing environment variables and
|
|
252
|
+
triggering a server restart.
|
|
253
|
+
|
|
254
|
+
### `PUT /api/config/env`
|
|
255
|
+
|
|
256
|
+
Update environment variables on the VPS host.
|
|
257
|
+
|
|
258
|
+
**Body:** `{ "REV4A_PASSWORD": "newpass", ... }`
|
|
259
|
+
|
|
260
|
+
**Response:** `{ "ok": true }`
|
|
261
|
+
|
|
262
|
+
### `POST /api/config/restart`
|
|
263
|
+
|
|
264
|
+
Restart the Rev4a server (via systemd).
|
|
265
|
+
|
|
266
|
+
**Response:** `{ "ok": true }`
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Key Design Decisions
|
|
271
|
+
|
|
272
|
+
1. **No `mode: 'replace'`** — The `mode` field is not written to the provider
|
|
273
|
+
config. OpenClaw uses its default merge behavior, combining config models with
|
|
274
|
+
auto-discovered models from the provider API.
|
|
275
|
+
|
|
276
|
+
2. **Model IDs without `rev4a/` prefix in config** — Inside
|
|
277
|
+
`models.providers.rev4a.models`, model IDs do NOT include the `rev4a/`
|
|
278
|
+
prefix. OpenClaw adds it automatically at runtime.
|
|
279
|
+
|
|
280
|
+
3. **Provider keys in `data/provider-keys.json`** — Not in env vars or
|
|
281
|
+
committed code. This file is gitignored and managed exclusively through the
|
|
282
|
+
Gateway UI.
|
|
283
|
+
|
|
284
|
+
4. **No gateway restart after model sync** — The sync module writes `models.providers`
|
|
285
|
+
to the file directly without restarting the gateway.
|
|
286
|
+
|
|
287
|
+
5. **Entrypoint does not generate openclaw.json** — The entrypoint resolves the
|
|
288
|
+
auth token and starts the gateway with `--allow-unconfigured`; OpenClaw
|
|
289
|
+
generates its own default config on first boot. All post-creation config
|
|
290
|
+
(controlUi, model refs, providers) is written by the create route
|
|
291
|
+
(`POST /api/agents/create`) after the gateway is fully ready.
|
|
292
|
+
The entrypoint also runs `openclaw doctor --non-interactive` **before** the
|
|
293
|
+
gateway, but only when the OpenClaw version changed since last boot
|
|
294
|
+
(tracked in `/root/.openclaw/.last-version`) — safe migrations only, no restart.
|
|
295
|
+
|
|
296
|
+
6. **Model ref written after gateway readiness** — When the wizard creates an agent,
|
|
297
|
+
the create route waits for gateway health check, then writes
|
|
298
|
+
`agents.defaults.model.primary` + fallbacks and `gateway.controlUi.allowedOrigins`,
|
|
299
|
+
then calls `syncAgent(name)`. The Gateway sync (`PUT /api/gateway/provider`)
|
|
300
|
+
never touches model references — only `models.providers` is synced.
|