@flame0510/project-aether 1.3.0 → 1.4.0

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.
Files changed (76) hide show
  1. package/README.md +1 -0
  2. package/agent-templates/README.md +42 -22
  3. package/agent-templates/base-image/Dockerfile +42 -33
  4. package/agent-templates/base-image/entrypoint.sh +67 -12
  5. package/app/agents/BrowserAccessSection.tsx +510 -0
  6. package/app/agents/ChannelManager.tsx +19 -11
  7. package/app/agents/ImageDownloadBanner.tsx +53 -19
  8. package/app/agents/ModelSection.tsx +4 -1
  9. package/app/agents/PageClient.tsx +629 -167
  10. package/app/agents/UpdateSection.tsx +300 -0
  11. package/app/agents/create/PageClient.tsx +11 -49
  12. package/app/api/agents/[id]/backup/route.ts +26 -69
  13. package/app/api/agents/[id]/channels/pairing/route.ts +3 -3
  14. package/app/api/agents/[id]/channels/telegram/route.ts +2 -2
  15. package/app/api/agents/[id]/cold-backup/route.ts +56 -0
  16. package/app/api/agents/[id]/devices/route.ts +126 -0
  17. package/app/api/agents/[id]/invite-link/route.ts +53 -0
  18. package/app/api/agents/[id]/lifecycle/route.ts +3 -0
  19. package/app/api/agents/[id]/open-control-ui/route.ts +58 -0
  20. package/app/api/agents/[id]/recreate/route.ts +33 -163
  21. package/app/api/agents/[id]/restart/route.ts +5 -0
  22. package/app/api/agents/[id]/restore/route.ts +40 -70
  23. package/app/api/agents/[id]/route.ts +38 -150
  24. package/app/api/agents/[id]/update/rollback/route.ts +30 -0
  25. package/app/api/agents/[id]/update/route.ts +50 -0
  26. package/app/api/agents/activity-summary/route.ts +67 -0
  27. package/app/api/agents/create/route.ts +32 -88
  28. package/app/api/agents/devices-summary/route.ts +37 -0
  29. package/app/api/agents/download-image/route.ts +16 -9
  30. package/app/api/agents/image-status/route.ts +31 -111
  31. package/app/api/agents/route.ts +25 -49
  32. package/app/api/agents/token/route.ts +33 -10
  33. package/app/api/assistant/route.ts +2 -2
  34. package/app/api/gateway/agent/route.ts +14 -0
  35. package/app/api/gateway/provider/balance/route.ts +5 -2
  36. package/app/api/gateway/sync.ts +97 -14
  37. package/app/api/setup/agent-image/route.ts +14 -42
  38. package/app/components/DashboardToolbar.tsx +1 -1
  39. package/app/gateway/PageClient.tsx +27 -32
  40. package/bin/rev4a.js +43 -41
  41. package/daemon.js +6 -6
  42. package/docs/ARCHITECTURE.md +95 -9
  43. package/docs/FRONTEND-ARCHITECTURE.md +8 -1
  44. package/docs/REV4A.md +54 -17
  45. package/docs/dev/API-REFERENCE.md +554 -100
  46. package/docs/dev/DATABASE.md +96 -0
  47. package/docs/dev/GATEWAY.md +21 -6
  48. package/docs/rag/DATA-FRESHNESS.md +6 -4
  49. package/docs/rag/GLOSSARY.md +12 -3
  50. package/docs/rag/REV4A-OVERVIEW.md +18 -5
  51. package/docs/rag/WHAT-I-CAN-ANSWER.md +6 -2
  52. package/instrumentation.ts +43 -0
  53. package/lib/agent-busy.ts +21 -0
  54. package/lib/agent-devices.ts +361 -0
  55. package/lib/agent-edit-state.ts +108 -0
  56. package/lib/agent-edit.ts +157 -0
  57. package/lib/agent-images.ts +375 -0
  58. package/lib/agent-ports-server.ts +27 -0
  59. package/lib/agent-ports.ts +68 -0
  60. package/lib/agent-recreate-state.ts +108 -0
  61. package/lib/agent-recreate.ts +305 -0
  62. package/lib/agent-restore-state.ts +107 -0
  63. package/lib/agent-restore.ts +135 -0
  64. package/lib/agent-setup.ts +66 -17
  65. package/lib/agent-update-state.ts +122 -0
  66. package/lib/agent-update.ts +448 -0
  67. package/lib/agent-versions.json +14 -0
  68. package/lib/agent-versions.ts +80 -0
  69. package/lib/buildAgentImage.ts +88 -290
  70. package/lib/channelManager.ts +149 -102
  71. package/lib/cold-backup.ts +354 -0
  72. package/lib/credentials/delivery.ts +3 -3
  73. package/lib/db-bootstrap.mjs +76 -0
  74. package/lib/docker-utils.ts +3 -3
  75. package/lib/provider-balance.ts +33 -12
  76. package/package.json +1 -1
package/docs/REV4A.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rev4a — VPS Dashboard
2
2
 
3
- > **Last updated:** 2026-09-14
3
+ > **Last updated:** 2026-09-15
4
4
 
5
5
  A Next.js 16 dashboard for monitoring and managing the OpenClaw ecosystem.
6
6
 
@@ -68,6 +68,7 @@ Rev4a reads the following environment variables. Set them in `/config` (UI) or d
68
68
  | `REV4A_ROOT` | No | Installation root, used by `rev4a update` to detect a git checkout |
69
69
  | `REV4A_TIMEZONE` | No | IANA timezone used for scheduling and timestamps |
70
70
  | `REV4A_FORCE_INSECURE_COOKIE` | No | Allow a non-Secure session cookie — plain-HTTP deployments only |
71
+ | `REV4A_AGENT_IMAGE_REGISTRY` | No | Registry repository agent images are pulled from (default: `ghcr.io/flame0510/rev4a/openclaw-agent-base`); a `localhost` registry is reached over plain HTTP |
71
72
 
72
73
  See [Alerts](#alerts-telegram) below for the Telegram alert variables.
73
74
 
@@ -76,9 +77,9 @@ See [Alerts](#alerts-telegram) below for the Telegram alert variables.
76
77
  Every agent is created with:
77
78
 
78
79
  - A host port mapping (`-p <port>:3000`) for direct access
79
- - URL format: `http://<host-public-ip>:<port>#token=...`
80
+ - Control UI at `http://<host>:<port>`, opened from the Agents page through `GET /api/agents/[id]/open-control-ui`
80
81
  - The provider gateway at `http://host.docker.internal:3740/api/provider/v1`
81
- - `allowedOrigins: ['*']` for browser Control UI access
82
+ - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback: true`, so the Control UI opens on whatever host the agent is reached on, and pages from other origins are refused
82
83
 
83
84
  The port is auto-assigned starting from 3000 (or user-specified).
84
85
 
@@ -302,9 +303,10 @@ Lists all agents (Docker containers with `AGENT_ID` label), with:
302
303
  - Name, image, template, status, ports, IP
303
304
  - TG channel status chip (green = connected, hidden if not configured)
304
305
  - **Shared gateway token** — text input with Save & Sync. Changing the token saves it to `data/agents-token.json` and pushes it to all running containers.
305
- - **Control UI link** — direct Traefik URL with `#token=<token>` hash, reads the token from `agents-token.json` (source of truth), not from the container's local config.
306
+ - **Control UI link** — the **Open** buttons go through `GET /api/agents/[id]/open-control-ui`, which redirects to the agent's published port on the host the dashboard was reached on: a one-time link on OpenClaw 9.x, the plain `#token=` link otherwise, with the token read inside the container.
306
307
  - **Agent creation wizard** — multi-step form at `/agents/create`.
307
- - **Channel Manager** — each agent detail panel has a Channels section with Telegram configuration and pairing management.
308
+ - **Channel Manager** — each agent detail panel has a Channels section with Telegram configuration and pairing management. Pending requests (a sender's `/start` creates one) show an **Approve** button; approved senders show **Revoke** with a confirmation. Approved senders are OpenClaw's pairing store, not the agent config: on 2026.9.x the SQLite store, read and revoked through OpenClaw's own store functions (see [ARCHITECTURE.md](ARCHITECTURE.md)).
309
+ - **Browser access** — the detail panel section right after Channels. From OpenClaw 9.x each new browser must be approved once before the Control UI connects: the section lists requests waiting for approval (Approve / Reject) and approved browsers (Rename / Revoke), and the agent card shows a "browser waiting" badge. The **Open** buttons first ask the agent for a one-time link that pairs the browser with no approval, and open the plain token link when none can be issued (every 2026.7.x agent). **Invite link** (9.x agents only) gives a link to send to someone else: their browser passes gateway auth and waits in the approval list until approved. The link carries the gateway token every agent shares; changing the agents token invalidates every link sent. All of it runs the OpenClaw CLI inside the container asynchronously.
308
310
 
309
311
  ### Agent Creation Wizard (`/agents/create`)
310
312
 
@@ -318,20 +320,20 @@ Available templates:
318
320
 
319
321
  **Step 2 — Config:** Enter agent name, optional port, select a primary model from the available providers (pre-filtered by configured provider keys). The first model is pre-selected.
320
322
 
321
- **Step 3 — Deploy:** `POST /api/agents/create` creates the Docker container and returns the Traefik URL with the shared gateway token.
323
+ **Step 3 — Deploy:** `POST /api/agents/create` creates the Docker container and returns its port and the shared gateway token; the wizard links to `http://<host>:<port>#token=<token>`.
322
324
 
323
325
  **Post-creation pipeline:**
324
- 1. The container boots with the **openclaw-agent-base:latest** image — see [Agent Templates](#agent-templates) below.
326
+ 1. The container boots with the newest supported OpenClaw version downloaded here, `openclaw-agent-base:<version>`; the create answers `409` when none is — see [Agent Templates](#agent-templates) below.
325
327
  2. OpenClaw gateway starts automatically with `--allow-unconfigured`, generating its own default config.
326
328
  3. The route waits for the gateway to finish starting with `waitForGatewayReady()`, up
327
329
  to 60 s. On OpenClaw 9.x it waits for `/startupz` to report `started`. The
328
330
  2026.7.1-2 image has no `/startupz`, so there it waits for `/health`, which only
329
331
  shows the server is listening.
330
332
  4. Once ready, the route writes:
331
- - `gateway.controlUi.allowedOrigins` — Rev4a dashboard URL + Traefik hostname (required for browser Control UI access)
333
+ - `gateway.controlUi` with the browser-origin policy (`withControlUiPolicy()` in `lib/agent-setup.ts`): the Host-header fallback on, so the Control UI is accepted from the host the browser connected to — a public IP is refused without it — while pages from other origins are refused; an `allowedOrigins: ["*"]` list and the retired `dangerouslyDisableDeviceAuth` are dropped, any other allowlist is kept. Recreate re-applies the policy. Each new browser still needs a one-time device approval
332
334
  - `agents.defaults.model.primary` + fallbacks — the primary model selected in the wizard
333
335
  5. The route builds `models.providers.rev4a` with `buildRev4aProviderConfig()` and writes it with `openclaw config patch --stdin`.
334
- 6. The agent's control UI is immediately accessible at `https://<name>.<your-domain>.com#token=<gateway-token>`.
336
+ 6. The agent's Control UI is reachable at `http://<host>:<port>#token=<gateway-token>`. For HTTPS or a domain, put your own reverse proxy in front of the published port: Rev4a sets no reverse-proxy labels on agent containers.
335
337
 
336
338
  ---
337
339
 
@@ -341,8 +343,9 @@ Each agent is created with a **persistent Docker volume** `agent-<name>-data`
341
343
  mounted at `/root`. This cleanly separates two planes:
342
344
 
343
345
  - **Software → image.** OpenClaw, `gh`, `vercel`, `supabase`, `trello`, Node — all
344
- live in `openclaw-agent-base:latest` (outside `/root`). Updated by rebuilding the
345
- image and recreating the container.
346
+ live in the agent image `openclaw-agent-base:<version>` (outside `/root`). A recreate
347
+ keeps the agent's OpenClaw version; moving an agent to a newer version is a separate
348
+ update.
346
349
  - **Data → volume.** Config (`openclaw.json`), state DB (`openclaw.sqlite`),
347
350
  workspace files, and CLI credentials (`.config/gh`, `.local/share/com.vercel.cli`,
348
351
  `.supabase`, …) live in `/root` and survive container removal.
@@ -354,9 +357,12 @@ a re-created agent keeps the workspace the user edited.
354
357
 
355
358
  | Action | What it does |
356
359
  |---|---|
357
- | **Backup** | `tar` of `/root` (excl. npm cache) → `.tar.gz` in the `rev4a-backups` volume |
360
+ | **Backup** | `tar` of `/root` (excl. npm cache) → `.tar.gz` in the `rev4a-backups` volume, while the agent runs |
361
+ | **Cold backup** | stop → archive `/root` (excl. npm cache) as `.partial` in a helper container → read the archive back → rename → start again if it was running. Other operations on the agent answer 409 meanwhile. Survives a Rev4a restart. API only for now (`/api/agents/[id]/cold-backup`) |
362
+ | **Update** | the agent panel's OPENCLAW VERSION section, when a newer supported version is downloaded: count transcript events and cron jobs → cold pre-update backup → recreate on the new version (its data migrates one way) → wait for that version → check nothing went missing. Unused agent images are removed afterwards |
363
+ | **Rollback** | after an update: stop → restore the pre-update backup → recreate on the previous version. Everything since the backup is lost |
358
364
  | **Restore** | stop → replace `/root` with the backup (real wipe incl. dotfiles) → restart. Software/image untouched — only data goes back in time |
359
- | **Recreate** | auto-backup first (aborts if it fails) → rebuild from `openclaw-agent-base:latest` keeping the volume → picks up image/OpenClaw/CLI updates |
365
+ | **Recreate** | auto-backup first (aborts if it fails) → rebuild on the agent's own OpenClaw version (`openclaw-agent-base:<version>`, tagged or pulled when missing) keeping the volume. Never changes version |
360
366
  | **Restart** | `docker restart`, nothing else |
361
367
  | **Delete** | **destructive**: removes container **+ volume + all backups**. Cannot be undone |
362
368
 
@@ -368,19 +374,50 @@ agent means rebuilding the image + Recreate, never `update` inside the container
368
374
 
369
375
  ## Agent Templates
370
376
 
371
- ### Base Image (`openclaw-agent-base:latest`)
377
+ ### Base Image (`openclaw-agent-base:<version>`)
372
378
 
373
379
  **Dockerfile:** `agent-templates/base-image/Dockerfile`
374
380
 
381
+ **Versions.** Images are kept locally per OpenClaw version, `openclaw-agent-base:<version>`;
382
+ `:latest` is not used. The versions this release supports, newest first, and the model
383
+ `input` list for each, are in `lib/agent-versions.json`, read by the server and the
384
+ `rev4a` CLI. The Agents page banner offers the newest supported version the registry
385
+ publishes (`ghcr.io/flame0510/rev4a/openclaw-agent-base`, or `REV4A_AGENT_IMAGE_REGISTRY`);
386
+ downloading touches no agent. Create uses the newest supported version downloaded; recreate
387
+ keeps the agent's version. An agent card shows **UPDATE AVAILABLE** when a newer supported
388
+ version is downloaded.
389
+
375
390
  Built from `node:24-bookworm-slim`, includes:
376
- - OpenClaw CLI + DeepSeek provider plugin
391
+ - OpenClaw, pinned by the `OPENCLAW_VERSION` build argument and recorded as the
392
+ `org.opencontainers.image.version` label
393
+ - `gh`, `vercel`, `trello`, `supabase`
394
+ - Plugins under `/opt/openclaw-plugins`, outside the agent volume and pinned to the same
395
+ OpenClaw release: DuckDuckGo web search
377
396
  - `openssl` (for local token generation)
378
397
  - Custom entrypoint `/agent-entrypoint.sh`
379
398
 
399
+ See also [agent-templates/README.md](../agent-templates/README.md).
400
+
380
401
  **Entrypoint behavior:**
381
402
  - Resolves the auth token (file > env > local random)
382
403
  - Does NOT generate `openclaw.json` — OpenClaw creates its own default config on first boot
383
- - **Version-gated migration:** if the OpenClaw version differs from the one recorded in `/root/.openclaw/.last-version` (i.e. the image was rebuilt to a newer OpenClaw), runs `openclaw doctor --non-interactive` **before** starting the gateway. This applies only safe migrations (config normalization + on-disk state moves), skips service restarts, and aligns the persistent volume's state/config to the new binary. Best-effort — never blocks boot. Runs at most once per version change, not on every restart.
404
+ - **Version-gated migration:** if the OpenClaw version differs from the one recorded in
405
+ `/root/.openclaw/.last-version` (a newer image, or a new volume), runs
406
+ `openclaw doctor --fix --non-interactive` **before** starting the gateway. `--fix` is
407
+ required from OpenClaw 9.x: the agent database schema is migrated only with the gateway
408
+ stopped, and the gateway refuses the old schema rather than migrating it. The version is
409
+ recorded only after a successful run, so a failed migration is retried on the next boot.
410
+ A failure does not block boot.
411
+ - **Image defaults**, before the gateway starts, written only where missing:
412
+ - the image's plugin directories in `plugins.load.paths`
413
+ - `tools.web.search.provider: "duckduckgo"` when no provider is set
414
+ - `agents.defaults.heartbeat.every: "0m"` when unset: every heartbeat tick is a
415
+ model-calling turn, so the recurring cadence is opt-in
416
+
417
+ An explicit value, such as a heartbeat turned on for one agent, is never overwritten.
418
+ The config is read with one node process and written through `openclaw config patch`,
419
+ which validates; if `openclaw.json` cannot be read as JSON, the defaults are skipped and
420
+ the log says so.
384
421
  - Starts OpenClaw gateway with `--allow-unconfigured`: `openclaw gateway --bind lan --port 3000 --auth token --token "<token>" --allow-unconfigured`
385
422
  - Everything else (controlUi, model refs, providers) is handled by the create route and the Gateway sync module
386
423
 
@@ -437,7 +474,7 @@ Only models whose provider has a key in `data/provider-keys.json` are synced.
437
474
 
438
475
  | Property | Value |
439
476
  |---|---|
440
- | Image | `openclaw-agent-base:latest` (Node 24-bookworm-slim + OpenClaw) |
477
+ | Image | `openclaw-agent-base:<version>` (Node 24-bookworm-slim + OpenClaw) |
441
478
  | Port | `0.0.0.0:3731 → 3000` |
442
479
  | IP | `172.19.0.3` |
443
480
  | AGENT_ID | `atlas` |