#How to route cron jobs to persistent registered agents + enable agent-to-agent messaging

1 messages · Page 1 of 1 (latest)

sick stag
#

I'm trying to set up a persistent agent workflow and have a few questions:

Setup:

• I've registered two agents: tweetle and reddle using openclaw agents add
• Both are registered with workspaces, identities, and the same model as my main agent
• They're NOT bound to any channel — purely internal orchestration agents

What I want:

  1. A cron job fires and routes its trigger to the persistent agent's existing session (so the agent stays warm between runs, no cold-start)
  2. From my main agent (Peanut), I want to sessions_send to tweetle or reddle's session directly to give them tasks or check status
  3. Alternatively, I want cron to trigger these agents via an agent_to_agent call

What I've tried:

• Cron with sessionTarget: "isolated" — this creates a new fresh isolated session each run, not routing to the persistent agent
• sessions_send from main → agent:tweetle — returns forbidden (visibility restricted to current session tree)

Config I found:

• tools.sessions.visibility — options are self | tree | agent | all
• tools.agentToAgent.enabled + tools.agentToAgent.allow — for runtime cross-agent invocation

Questions:

  1. What's the correct pattern for routing cron → persistent registered agent?
  2. Is tools.agentToAgent the right way to enable Peanut → Tweetle/Reddle messaging?
  3. Should I be using sessionTarget: "agent:tweetle" in cron instead of "isolated"?
  4. Is there a recommended pattern for keeping agents warm between cron runs vs. cold-starting each time?
night tundraBOT
obsidian burrowBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

night tundraBOT
spring epochBOT
#

Short version, sessionTarget: "agent:tweetle" is not the right shape.

  1. Cron → persistent registered agent
    Use --agent <agentId> plus a persistent session target:

    openclaw cron add \
      --name "tweetle loop" \
      --agent tweetle \
      --session "session:tweetle-worker" \
      --cron "*/15 * * * *" \
      --message "Do the scheduled tweet work." \
      --no-deliver
    

    --session only supports main, isolated, current, and session:<id>.
    So for stateful runs, use session:<stable-id>. isolated is always fresh.

  2. Peanut → Tweetle/Reddle messaging

#

Yes, tools.agentToAgent is the right gate for cross-agent sessions_send, but you also need session visibility wide enough:

{
  tools: {
    sessions: { visibility: "all" },
    agentToAgent: {
      enabled: true,
      allow: ["main", "tweetle", "reddle"], // use actual agent ids
    },
  },
}

Important:

  • visibility: "agent" is not enough for cross-agent, it only sees sessions for the current agent.
  • agentToAgent.allow is checked for both requester and target.
  1. Should cron use sessionTarget: "agent:tweetle"?
#

No.
The agent is selected separately with --agent / agentId.
The session target is only one of:

  • main
  • isolated
  • current
  • session:<id>
  1. Warm vs cold pattern
    Recommended:
    • Stateless/background taskisolated
    • Stateful worker agent--agent tweetle --session "session:tweetle-worker"
    • Bind to an already-open exact session → create/edit the cron from inside that session, then use --session current

One nuance, this keeps the session/history warm, not a permanently running in-memory worker. Cron still wakes the agent on demand.

So I’d recommend:

#
  • Direct cron → target agent/session for normal scheduled worker flows
  • Only do cron → Peanut → cross-agent send if Peanut is meant to supervise/router those workers

Docs:

First sanity check, run openclaw --version, because this area changed a bit recently. If you paste your cron JSON/config snippet, I can sanity-check the exact shape.

sick stag
#

where do I put this part:
Yes, tools.agentToAgent is the right gate for cross-agent sessions_send, but you also need session visibility wide enough:

{
tools: {
sessions: { visibility: "all" },
agentToAgent: {
enabled: true,
allow: ["main", "tweetle", "reddle"], // use actual agent ids
},
},
}

in the openclaw.json? I just don't see " tools:" in there currently

#

oh wait I currently see this in config
"tools": {
"profile": "full"
},

spring epochBOT
#

Yep, that’s normal, tools is an optional top-level block. If it isn’t there yet, just add it alongside agents, channels, etc. in ~/.openclaw/openclaw.json.

Example:

{
  agents: {
    // your existing agents config
  },

  channels: {
    // your existing channels config
  },

  tools: {
    sessions: {
#
      visibility: "all",
    },
    agentToAgent: {
      enabled: true,
      allow: ["main", "tweetle", "reddle"], // use real agent ids here
    },
  },
}

A couple of gotchas:

  • openclaw.json is JSON5, so comments and trailing commas are fine.
  • Use the actual agent id, not the display/identity name. If Peanut is really your default main agent, then main is correct. If not, check with:
#

Perfect, then just extend that existing tools block, don’t replace it.

Like this:

{
  tools: {
    profile: "full",
    sessions: {
      visibility: "all",
    },
    agentToAgent: {
      enabled: true,
      allow: ["main", "tweetle", "reddle"],
    },
  },
#
}

So yes, profile: "full" can live right next to sessions and agentToAgent.

Then restart:

openclaw gateway restart

If OpenClaw complains those keys are unknown, that’s the point where I’d check:

openclaw --version
#

because then you’re probably on an older build than the docs/runtime I was referencing.

sick stag
#

okay does this look right then:
],
"tools": {
profile: "full",
sessions: {
visibility: "all",
},
agentToAgent: {
enabled: true,
allow: ["main", "tweetle", "reddle"],
},
},
"commands": {
"native": "auto",
"nativeSkills": "auto",
"restart": true,
"ownerDisplay": "raw"
},
"session": {
"dmScope": "per-channel-peer"
},

spring epochBOT
#

Yep, that looks right structurally.

I’d just make it consistent with the rest of your file, for example:

"tools": {
  "profile": "full",
  "sessions": {
    "visibility": "all"
  },
  "agentToAgent": {
    "enabled": true,
    "allow": ["main", "tweetle", "reddle"]
  }
},