Most “AI agents” are chat sessions with tool calls.
They look alive while a request is running. Then the process exits, the context evaporates, and every promise to “keep an eye on it” quietly becomes fiction.
The model is rarely the problem. The unit of computation is.
If an agent is supposed to watch, remember, follow up, or finish work over several days, a chat turn cannot be its lifecycle. It needs to be a durable process.
A useful agent has three different clocks
Long-running work usually falls into three categories:
| Intent | Primitive | Example |
|---|---|---|
| Run at a known time | Cron job | Send a weekly project digest |
| Wake when something changes | Trigger | Alert when a release appears |
| Keep pursuing an outcome | Goal | Get a refund resolved |
Combining these into one vague “background agent” abstraction is tempting, but it makes behavior harder to reason about.
A cron job should not pretend it understands outcomes. A trigger should not poll forever inside a chat loop. A goal should not need an exact timestamp to remain alive.
The runtime should own those guarantees.
The model should be replaceable
The durable architecture looks more like an operating system process than a chatbot:
Telegram / Discord / Terminal / Desktop
|
agent runtime
_____________|_____________
| | |
sessions tools durable state
|
goals / cron / triggers
|
heartbeat / event wakeup
The model handles judgment. The runtime handles continuity.
That separation has a useful consequence: the model backend can change without deleting the agent’s life. A Claude session, Codex task, or OpenAI agent can all sit behind the same scheduling, memory, tool, and frontend machinery.
“I’ll check later” needs a receipt
An agent should never promise future work unless it creates something durable in the same turn.
That can be:
- a cron record with a next-run time;
- a supervised watcher with a condition;
- a goal that background runs will revisit.
If there is no persisted mechanism, “I’ll follow up tomorrow” is not a plan. It is generated dialogue.
This is also why logs and task inspection matter. Background autonomy without observability is just a haunted server. You need to know what is running, why it woke up, what tools it used, and whether it failed.
Frontends should be mouths, not brains
Users naturally want the same assistant in several places. If each chat integration owns its own memory and scheduling, you get several disconnected assistants wearing the same name.
A better split is:
- frontends translate platform events;
- the core owns sessions and durable state;
- tools expose capabilities;
- backends provide model-specific execution;
- background machinery resumes work independently of any open chat.
That makes Telegram, Discord, a terminal, or a phone app different doors into the same system.
We built the runtime we wanted
Talon is our open-source implementation of this idea. It is a self-hosted TypeScript agent harness with:
- persistent goals, cron jobs, and condition-driven triggers;
- heartbeat and memory-consolidation workers;
- Telegram, Discord, Teams, terminal, desktop, and mobile frontends;
- Claude, Codex, OpenAI Agents, Kilo, and OpenCode backends;
- local and remote MCP tools;
- a live task table and
/proc-style filesystem views for inspection.
Install it with:
npm install -g talon-agent
talon setup
talon start
The repository is github.com/dylanneve1/talon.
If you are building assistants that need to survive longer than a demo, steal the architecture—or the code. And if Talon is useful, star it so more builders can find it.
Top comments (0)