From 98aecab7bdc028953ce8249c43e2d1c06029f9bd Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Thu, 5 Mar 2026 17:05:21 -0500 Subject: [PATCH] Docs: cover heartbeat, cron, and plugin route updates --- docs/automation/cron-jobs.md | 12 ++++++++- docs/cli/cron.md | 20 +++++++++++++++ docs/gateway/configuration-reference.md | 2 ++ docs/gateway/heartbeat.md | 6 ++++- docs/tools/plugin.md | 33 ++++++++++++++++++++++++- 5 files changed, 70 insertions(+), 3 deletions(-) diff --git a/docs/automation/cron-jobs.md b/docs/automation/cron-jobs.md index bb12570bd2b..1421480a7a0 100644 --- a/docs/automation/cron-jobs.md +++ b/docs/automation/cron-jobs.md @@ -176,6 +176,7 @@ Common `agentTurn` fields: - `message`: required text prompt. - `model` / `thinking`: optional overrides (see below). - `timeoutSeconds`: optional timeout override. +- `lightContext`: optional lightweight bootstrap mode for jobs that do not need workspace bootstrap file injection. Delivery config: @@ -235,6 +236,14 @@ Resolution priority: 2. Hook-specific defaults (e.g., `hooks.gmail.model`) 3. Agent config default +### Lightweight bootstrap context + +Isolated jobs (`agentTurn`) can set `lightContext: true` to run with lightweight bootstrap context. + +- Use this for scheduled chores that do not need workspace bootstrap file injection. +- In practice, the embedded runtime runs with `bootstrapContextMode: "lightweight"`, which keeps cron bootstrap context empty on purpose. +- CLI equivalents: `openclaw cron add --light-context ...` and `openclaw cron edit --light-context`. + ### Delivery (channel + target) Isolated jobs can deliver output to a channel via the top-level `delivery` config: @@ -298,7 +307,8 @@ Recurring, isolated job with delivery: "wakeMode": "next-heartbeat", "payload": { "kind": "agentTurn", - "message": "Summarize overnight updates." + "message": "Summarize overnight updates.", + "lightContext": true }, "delivery": { "mode": "announce", diff --git a/docs/cli/cron.md b/docs/cli/cron.md index 9c129518e21..5f5be713de1 100644 --- a/docs/cli/cron.md +++ b/docs/cli/cron.md @@ -42,8 +42,28 @@ Disable delivery for an isolated job: openclaw cron edit --no-deliver ``` +Enable lightweight bootstrap context for an isolated job: + +```bash +openclaw cron edit --light-context +``` + Announce to a specific channel: ```bash openclaw cron edit --announce --channel slack --to "channel:C1234567890" ``` + +Create an isolated job with lightweight bootstrap context: + +```bash +openclaw cron add \ + --name "Lightweight morning brief" \ + --cron "0 7 * * *" \ + --session isolated \ + --message "Summarize overnight updates." \ + --light-context \ + --no-deliver +``` + +`--light-context` applies to isolated agent-turn jobs only. For cron runs, lightweight mode keeps bootstrap context empty instead of injecting the full workspace bootstrap set. diff --git a/docs/gateway/configuration-reference.md b/docs/gateway/configuration-reference.md index 83ea09dcb34..1ba60bee31d 100644 --- a/docs/gateway/configuration-reference.md +++ b/docs/gateway/configuration-reference.md @@ -971,6 +971,7 @@ Periodic heartbeat runs. every: "30m", // 0m disables model: "openai/gpt-5.2-mini", includeReasoning: false, + lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files session: "main", to: "+15555550123", directPolicy: "allow", // allow (default) | block @@ -987,6 +988,7 @@ Periodic heartbeat runs. - `every`: duration string (ms/s/m/h). Default: `30m`. - `suppressToolErrorWarnings`: when true, suppresses tool error warning payloads during heartbeat runs. - `directPolicy`: direct/DM delivery policy. `allow` (default) permits direct-target delivery. `block` suppresses direct-target delivery and emits `reason=dm-blocked`. +- `lightContext`: when true, heartbeat runs use lightweight bootstrap context and keep only `HEARTBEAT.md` from workspace bootstrap files. - Per-agent: set `agents.list[].heartbeat`. When any agent defines `heartbeat`, **only those agents** run heartbeats. - Heartbeats run full agent turns — shorter intervals burn more tokens. diff --git a/docs/gateway/heartbeat.md b/docs/gateway/heartbeat.md index a4f4aa64ea9..90c5d9d3c75 100644 --- a/docs/gateway/heartbeat.md +++ b/docs/gateway/heartbeat.md @@ -21,7 +21,8 @@ Troubleshooting: [/automation/troubleshooting](/automation/troubleshooting) 2. Create a tiny `HEARTBEAT.md` checklist in the agent workspace (optional but recommended). 3. Decide where heartbeat messages should go (`target: "none"` is the default; set `target: "last"` to route to the last contact). 4. Optional: enable heartbeat reasoning delivery for transparency. -5. Optional: restrict heartbeats to active hours (local time). +5. Optional: use lightweight bootstrap context if heartbeat runs only need `HEARTBEAT.md`. +6. Optional: restrict heartbeats to active hours (local time). Example config: @@ -33,6 +34,7 @@ Example config: every: "30m", target: "last", // explicit delivery to last contact (default is "none") directPolicy: "allow", // default: allow direct/DM targets; set "block" to suppress + lightContext: true, // optional: only inject HEARTBEAT.md from bootstrap files // activeHours: { start: "08:00", end: "24:00" }, // includeReasoning: true, // optional: send separate `Reasoning:` message too }, @@ -88,6 +90,7 @@ and logged; a message that is only `HEARTBEAT_OK` is dropped. every: "30m", // default: 30m (0m disables) model: "anthropic/claude-opus-4-6", includeReasoning: false, // default: false (deliver separate Reasoning: message when available) + lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files target: "last", // default: none | options: last | none | (core or plugin, e.g. "bluebubbles") to: "+15551234567", // optional channel-specific override accountId: "ops-bot", // optional multi-account channel id @@ -208,6 +211,7 @@ Use `accountId` to target a specific account on multi-account channels like Tele - `every`: heartbeat interval (duration string; default unit = minutes). - `model`: optional model override for heartbeat runs (`provider/model`). - `includeReasoning`: when enabled, also deliver the separate `Reasoning:` message when available (same shape as `/reasoning on`). +- `lightContext`: when true, heartbeat runs use lightweight bootstrap context and keep only `HEARTBEAT.md` from workspace bootstrap files. - `session`: optional session key for heartbeat runs. - `main` (default): agent main session. - Explicit session key (copy from `openclaw sessions --json` or the [sessions CLI](/cli/sessions)). diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index d55d7e43742..32c33838642 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -62,7 +62,7 @@ Schema instead. See [Plugin manifest](/plugins/manifest). Plugins can register: - Gateway RPC methods -- Gateway HTTP handlers +- Gateway HTTP routes - Agent tools - CLI commands - Background services @@ -106,6 +106,37 @@ Notes: - Uses core media-understanding audio configuration (`tools.media.audio`) and provider fallback order. - Returns `{ text: undefined }` when no transcription output is produced (for example skipped/unsupported input). +## Gateway HTTP routes + +Plugins can expose HTTP endpoints with `api.registerHttpRoute(...)`. + +```ts +api.registerHttpRoute({ + path: "/acme/webhook", + auth: "plugin", + match: "exact", + handler: async (_req, res) => { + res.statusCode = 200; + res.end("ok"); + return true; + }, +}); +``` + +Route fields: + +- `path`: route path under the gateway HTTP server. +- `auth`: required. Use `"gateway"` to require normal gateway auth, or `"plugin"` for plugin-managed auth/webhook verification. +- `match`: optional. `"exact"` (default) or `"prefix"`. +- `replaceExisting`: optional. Allows the same plugin to replace its own existing route registration. +- `handler`: return `true` when the route handled the request. + +Notes: + +- `api.registerHttpHandler(...)` is obsolete. Use `api.registerHttpRoute(...)`. +- Plugin routes must declare `auth` explicitly. +- Exact `path + match` conflicts are rejected unless `replaceExisting: true`, and one plugin cannot replace another plugin's route. + ## Plugin SDK import paths Use SDK subpaths instead of the monolithic `openclaw/plugin-sdk` import when