I want to make a system where before the end of each run (what my agent does after a prompt), my agent sets a timer that after one minute, triggers and wakes up the agent to continue. So my agent can work in steps and without diluting context since one long task can dilute. and so it can continously message me about what its doing. The current idea we had is to set up a cron job per 1 minute. Each minute, wake up the agent. When the agent doesnt need to continue, the cron stays off. But the caveat is, how will we get agent towork in a specific thread? If the cron wakes it up, it will only continue in main/main chat.
#Continuous agents
1 messages · Page 1 of 1 (latest)
Yep — the caveat is real only if you wake main. You don’t have to.
The pattern I’d use is one-shot continuation jobs, not a permanently-running every-minute cron:
openclaw cron add \
--name "continue-workflow-<id>" \
--at "1m" \
--session current \
--system-event "Continue workflow <id>. Read the saved state, do the next step, then reschedule only if more remains." \
--wake now \
--delete-after-run
If that cron is created from inside the Discord thread, --session current binds to the current session at creation time, so it should continue the same routed context instead of main/main.
For Discord thread output specifically, remember a Discord thread is basically its own channel target. So for an isolated/custom cron job, deliver back to the thread with:
--announce --channel discord --to "channel:<thread_id>"
For this thread, that target shape would be:
--to "channel:1503287172847894619"
The more robust architecture is:
- Agent does one bounded step.
- Agent writes compact workflow state somewhere durable, e.g.
~/.openclaw/workflows/<id>.json. - If more remains, it schedules a one-shot
--at "1m"continuation. - If done, it does not schedule anything.
That avoids needing to “turn off” a recurring cron and avoids accidental wakeups. It also avoids context dilution because the cron prompt can say “read the state file and continue from step N” instead of carrying the whole previous transcript.
If you want the thread to stay bound for normal follow-ups too, enable Discord thread bindings and use /focus or thread-bound spawned sessions. Relevant docs:
https://docs.openclaw.ai/automation/cron-jobs
https://docs.openclaw.ai/channels/discord
But if the state is in a cron job, how would it know to read that chat exactly? what you answered is how to send it to a chat, how about the context?
Good catch — there are two separate things:
Delivery target = where the final message goes.
Run context = which session transcript/state the agent loads.
--announce --to "channel:<thread_id>" only solves delivery. It does not make the cron magically read that Discord thread.
For context, you want one of these:
Best path: create the continuation cron from inside the active thread with --session current.
That snapshots the current routed session key when the job is created. When it fires, cron wakes that same OpenClaw session transcript, not a fresh main chat. So the agent continues from the session context it already had.
If you instead use:
--session main
then yes, it wakes main/main and loses the thread-specific context.
More robust path: don’t rely on chat transcript as the source of truth.
Have the agent store a workflow record like:
{
"workflowId": "abc123",
"session": "current session key / thread-bound session",
"channel": "discord",
"to": "channel:1503287172847894619",
"lastMessageId": "...",
"nextStep": "...",
"summarySoFar": "..."
}
Then the cron prompt says: “Read workflow abc123, continue nextStep, use message/read if you need recent Discord messages.”
So the answer is: cron should not “know the chat” from --to; it should either:
- wake the same session via
--session current, or - read a durable workflow state file that includes the Discord thread/channel/message ids.
I’d combine both: --session current for continuity, plus a small workflow state file so context stays compact and recoverable. 🦞
ok, im not exactly the most technical with buttons and config. Can you give me the instructions i can copy straight to my builder agent so it can set such a system up?
Absolutely. Copy/paste this whole thing to your builder agent:
Build me a “continuous step runner” for OpenClaw.
Goal:
When I ask the agent to do a long task, it should work in small steps. At the end of each step, if more work remains, it should schedule a one-shot continuation for 1 minute later. The continuation must resume the same OpenClaw session/thread context, not main/main. It should also keep a compact durable state file so the transcript does not need to carry the whole task forever.
Important OpenClaw behavior to use:
- Use Gateway cron, not `sleep`, not polling, and not an external OS cron.
- Use one-shot cron jobs, not a permanent every-minute recurring cron.
- For continuation jobs, use `sessionTarget="current"` if using the cron tool, or `--session current` if using the CLI.
- `current` means: bind the cron job to the OpenClaw session where the cron is created, resolved at creation time.
- Do not use `--session main` for this continuation flow.
- If delivering to Discord, delivery target is separate from context. Delivery can use `channel:<discord_thread_id>`, but context comes from `sessionTarget="current"` / `--session current` and the state file.
First checks:
1. Run `openclaw --version` and note the version.
2. Check `openclaw cron --help` / local docs for current cron syntax before implementing.
3. Confirm cron supports `--session current` or the agent cron tool supports `sessionTarget: "current"`.
Implement this workflow:
1. Create a workflow state directory:
`~/.openclaw/workflows/continuous-runs/`
2. For each long task, create one JSON state file:
`~/.openclaw/workflows/continuous-runs/<workflowId>.json`
State file shape:
```json
{
"workflowId": "unique-id",
"status": "running",
"createdAt": "ISO timestamp",
"updatedAt": "ISO timestamp",
"channel": "discord",
"to": "channel:<discord_thread_or_channel_id>",
"source": "short human-readable origin",
"originalRequest": "the user's original task",
"summarySoFar": "compact summary of progress",
"nextStep": "what the next continuation should do",
"completedSteps": [],
"openQuestions": [],
"artifacts": [],
"continuationCount": 0,
"maxContinuations": 50
}
3. Add a reusable instruction/prompt for the agent:
When handling a continuous workflow:
- Read the workflow JSON first.
- Do exactly one bounded unit of work.
- Update `summarySoFar`, `completedSteps`, `nextStep`, `artifacts`, and `openQuestions`.
- Send the user a short progress update if useful.
- If done, set `status: "done"` and do not schedule another cron.
- If blocked on the user, set `status: "blocked"`, explain the question to the user, and do not schedule another cron.
- If more work remains, schedule exactly one one-shot continuation 1 minute later.
- Never create a recurring every-minute cron for this.
- Avoid multiple active continuation jobs for the same workflow.
4. Schedule continuations using the OpenClaw cron tool if available. Preferred tool-style shape:
```json
{
"action": "add",
"job": {
"name": "continue-workflow-<workflowId>",
"schedule": {
"kind": "at",
"at": "<ISO timestamp 1 minute from now>"
},
"sessionTarget": "current",
"payload": {
"kind": "agentTurn",
"message": "Continue workflow <workflowId>. Read ~/.openclaw/workflows/continuous-runs/<workflowId>.json first. Do one bounded next step, update the state file, message progress if useful, and reschedule only if more work remains."
},
"delivery": {
"mode": "announce",
"channel": "discord",
"to": "channel:<discord_thread_or_channel_id>",
"bestEffort": true
},
"enabled": true
}
}
5. If using CLI instead of the cron tool, use this shape:
```bash
openclaw cron add \
--name "continue-workflow-<workflowId>" \
--at "1m" \
--session current \
--message "Continue workflow <workflowId>. Read ~/.openclaw/workflows/continuous-runs/<workflowId>.json first. Do one bounded next step, update the state file, message progress if useful, and reschedule only if more work remains."
--announce
--channel discord
--to "channel:<discord_thread_or_channel_id>"
--delete-after-run
6. Add safeguards:
- Before scheduling a new continuation, check whether there is already an enabled pending cron named `continue-workflow-<workflowId>`. If yes, update/reuse it or skip creating a duplicate.
- Stop after `maxContinuations` and ask the user whether to continue.
- If the same workflow errors repeatedly, set status to `blocked` and notify the user.
- Keep the state file compact. Do not dump huge transcripts into it.
- Store links/paths to artifacts instead of embedding large content.
7. Acceptance test:
- Start a test workflow from inside a Discord thread.
- It creates a workflow JSON file.
- It schedules a one-shot cron with `sessionTarget="current"` / `--session current`.
- One minute later, the agent wakes in the same session context, reads the JSON, performs the next step, and posts progress back into the same Discord thread.
- When the test workflow finishes, no further cron is scheduled.
- `openclaw cron list` should not show an endlessly recurring every-minute job.
Docs to check:
- https://docs.openclaw.ai/automation/cron-jobs
- https://docs.openclaw.ai/cli/cron
- https://docs.openclaw.ai/channels/discord
Key thing to watch: your builder agent should use --message with --session current, not --system-event. Current/custom/isolated cron runs require an agentTurn message, while main-session cron uses system events.
d
It applied these as a skill. When it tries to use this however, it routes to the main agent (i gave it to another agent)
Ah — that’s the missing piece. --session current preserves the session context, but cron can still default the agent id to main unless you pin it.
So for another agent, the continuation cron needs both:
--agent <that-agent-id>
--session current
Example:
openclaw cron add \
--agent "<your-other-agent-id>" \
--name "continue-workflow-<workflowId>" \
--at "1m" \
--session current \
--message "Continue workflow <workflowId>. Read ~/.openclaw/workflows/continuous-runs/<workflowId>.json first. Do one bounded next step, update state, and reschedule only if more remains." \
--announce \
--channel discord \
--to "channel:<discord_thread_id>" \
--delete-after-run
If it’s using the cron tool JSON instead of CLI, add the agent id at job creation too. Shape should be conceptually:
{
"action": "add",
"job": {
"agentId": "<your-other-agent-id>",
"sessionTarget": "current",
"payload": {
"kind": "agentTurn",
"message": "Continue workflow <workflowId>..."
}
}
}
The docs/code behavior I’d expect is: if --agent is omitted on agent-turn cron jobs, OpenClaw falls back to the default agent, usually main. So tell your builder agent to update the skill: every continuation job must pin both agentId and sessionTarget: current.
Also worth checking with:
openclaw cron show <job-id> --json
Look for the stored/effective agent id. If it says main, that’s the bug in the skill implementation.
How what's the minimum timing of a cron job? I'm seeing 5 minutes right now but I want 1.
Cron can do 1 minute. The 5 minutes you’re seeing is probably stagger, not the minimum.
Use one of these:
For a one-shot continuation 1 minute later:
openclaw cron add \
--agent "<agent-id>" \
--name "continue-workflow-<workflowId>" \
--at "1m" \
--session current \
--message "Continue workflow <workflowId>..." \
--announce \
--channel discord \
--to "channel:<thread_id>" \
--delete-after-run
For a recurring every-minute job, if you really want recurring:
openclaw cron add \
--agent "<agent-id>" \
--name "every-minute-test" \
--every "1m" \
--session current \
--message "Run the next step..."
Or cron syntax:
--cron "* * * * *"
The 5-minute thing is likely because OpenClaw applies a default 5-minute stagger to top-of-hour cron schedules like:
--cron "0 * * * *"
That’s to avoid every job firing exactly on the hour. If you need exact timing, add:
--exact
So for your continuation system: don’t use --cron. Use --at "1m" for each one-shot continuation. That should wake after ~1 minute.
I checked the skill, this are the rules mentioned for scheduling. Is this right?
- Prefer Gateway cron for timed self-wakes.
- Prefer one-shot schedules, never recurring every-minute continuation jobs.
- Bind the continuation to both the current session/thread context and the current agent identity.
- For agent-turn continuation jobs, pin both values at creation time: explicit agent id plus
--session current(or JSONagentIdplussessionTarget: "current"). - On this stack,
openclaw cron add --session currentonly preserves the session binding from shell/exec once the exec runtime exports the live session key into the child environment; after the local fix, that means the patched runtime must be loaded (restart the Gateway if the old process is still serving). - If the agent id is omitted on an agent-turn continuation, cron may fall back to the default agent, usually
main, even when the session target is correct. - Verify the stored job after creation when the binding matters:
openclaw cron show <job-id> --jsonand confirm the effective agent/session are notmainunlessmainis intended. - Use agent-turn/message payloads for continuation runs, not main-session system events.
- Before creating a continuation, ensure there is not already another enabled pending continuation for the same workflow.
- Schedule at most one future continuation per workflow.