Autonomy With a Brake: Scheduling, Memory, and Places to Run

LobeHub becomes genuinely “always available” only when three decisions are made together: when an Agent should run, what it should carry forward, and where its actions should occur. This chapter compares Task schedules with heartbeat loops, then compares Memory, documents, Gateway recovery, and local/cloud/remote execution as different continuity and locality choices. The practical judgment is not to maximize automation; it is to choose the smallest recurring loop, the right kind of retained context, and the safest execution boundary for the work.

A recurring Agent is not simply a chat with a timer attached. A timer can fire after a user has paused a Task, changed its configuration, or started another run. A remembered preference can be useful in one conversation and wrong in another. A reconnecting browser can recover events without recovering a process that has already failed. LobeHub’s design is strongest where it treats these as state and ownership problems rather than as conveniences hidden behind a single “automate” switch.

Choosing how a Task should recur

The current LobeHub model attaches automation to the Task that owns the work. The older per-Agent cron table remains for legacy data, but new scheduling is centered on Task fields: a mutually exclusive schedule or heartbeat mode, a cron pattern and timezone or a fixed interval, a current run Topic, execution context, and optional limits. This placement matters because the schedule and the outcome it triggers now share one durable object. A person can inspect the instruction, run history, assignee, review state, and automation state together.

There are three different intentions to keep apart. A manual run means “start this work now.” A cron schedule means “start it when calendar conditions say it is due.” A heartbeat means “check back at a fixed interval and run another tick if the Task remains active.” The distinction is more than vocabulary. A manual run should not consume a schedule’s execution quota, and a heartbeat is not a one-time completion signal. It is one turn in a loop that must be re-armed.

A cron schedule is the more natural choice for calendar-shaped work: a daily briefing, a weekly review, or a run tied to a particular local time. LobeHub’s documentation emphasizes that the prompt runs on each scheduled execution and has no assumed prior chat context, so it must contain the background, data sources, time window, and output format the Agent needs. The timezone is part of the schedule’s meaning. “09:00” without a clear zone is not a reliable instruction for a distributed team.

A heartbeat is better suited to a fixed cadence in which the Agent should periodically inspect a state or decide whether anything needs attention. The interval is stored with the Task, and the scheduler can deliver a one-shot delayed message for the next tick. After the tick reaches the lifecycle path, the next message is scheduled again. This one-shot design is less like a permanent process sleeping in memory and more like a chain of durable wake-ups. It allows the database to remain authoritative between ticks and gives the system a place to invalidate an old generation.

The difference between a safe scheduler and a fragile timer is the recheck at dispatch time. When a cron delivery arrives, LobeHub reads the Task again. It skips the run if the Task is missing, the automation mode changed, the cron pattern is gone, the Task is paused or terminal, a human decision is unresolved, or another run is already in flight. A stale delivery is ordinary in a distributed system: the message may have been delayed while the user changed the Task. The correct response is not to trust the message’s age or original intent; it is to consult current state.

Heartbeat delivery adds a token for the same reason. Each active heartbeat generation records a token in Task context. If an older delayed message arrives after the user has restarted or edited the loop, the handler compares its token with the current one and skips it when they differ. The replacement schedule is published only after the prior generation has been invalidated. This closes a race in which an old wake-up could run alongside the new loop or overwrite its scheduler state.

The schedule path also treats execution limits as a defense-in-depth concern. A maximum-execution cap counts Task Topics triggered by the schedule since the schedule was started; ad hoc manual runs do not consume that allowance. The lifecycle hook is expected to stop the loop when the final allowed run completes, while the next tick checks again for crashes, stale scheduled rows, or a cap edited downward.