The AgentNava blog · notes on building agents that stay live.Back to all posts →
Blog/Engineering
EngineeringRuntime

Agents that keep working after you close the tab

Most AI apps stop the moment you stop typing. We built AgentNava on Cloudflare's edge so an agent can hold state, wake itself on a schedule, and keep a job moving while you sleep. Here is how the runtime does it.

Engineering · Runtime

There is a quiet assumption baked into most AI products: that the human is always there. You type, it answers, you type again. Close the tab and the whole thing evaporates. That is fine for a chatbot. It is useless for work.

Real work is not a conversation. It is a job that runs over hours and days: chase the invoice, watch the pipeline, triage the tickets, brief me in the morning. None of that fits inside a single request-and-response. So when we started building AgentNava, the first question was not “which model” or “which UI framework.” It was simpler: how does an agent keep working when nobody is watching?

The close-the-tab problem

A typical AI app is stateless by design. Each message is a fresh call to a model, with the previous turns replayed as context. That works beautifully for a fast exchange, and it scales because there is nothing to hold onto between requests. But it means the “agent” only exists for the few seconds it is generating a reply. There is no it the rest of the time.

For a proactive agent, that is the whole ballgame. If the work only advances while you have the tab open, you do not have an employee. You have a very expensive autocomplete.

An agent you have to babysit is just a tool with extra steps. The point is to hand off the job and get on with your day.

So the runtime needs two things a stateless app does not have: somewhere durable to keep the agent’s state, and a way to start running again without a person triggering it.

State that outlives the session

Every AgentNava agent is backed by a Durable Object: a single-threaded, addressable piece of compute with its own strongly-consistent SQLite storage, living on Cloudflare’s edge. That is where the agent’s memory lives. Not in your browser, not in a request that is about to end, but in a long-lived object that stays put between sessions.

Because it is durable, an agent can accumulate context across days: what it did last Monday, which deals it already followed up on, what is still waiting on you. When you reopen the workspace, you are not starting a new conversation. You are checking in on work that has been continuing without you.

Consistency matters here. A Durable Object serialises access to its own state, so two things happening at once (you sending a message while a scheduled run is mid-flight) never corrupt the agent’s memory. There is exactly one of each agent, and it is the source of truth.

Waking without a human

Durable storage solves memory. It does not, by itself, make anything happen. For that, the runtime leans on two edge primitives: alarms and the event loop that survives a closed tab.

An agent can set an alarm on its own Durable Object: “wake me at 8am,” or “check back in four hours.” When the alarm fires, Cloudflare invokes the object, the agent picks up exactly where it left off, does its work, and (usually) sets the next alarm before going quiet again. No cron server to run, no queue to babysit. The schedule lives inside the agent.

  • Scheduled work: a morning brief, a Monday pipeline sweep, an end-of-day summary.
  • Deferred work: “follow up in three days if they have not replied.”
  • Reactive work: a webhook or inbound email wakes the agent to handle something the moment it lands.

Critically, all of this runs whether or not you are online. The tab is just one way to watch the agent. It was never where the agent lived.

A worked example

Here is the shape of a proactive agent that keeps a sales pipeline warm. The interesting part is the last two lines: the agent schedules its own next run.

agent · pipeline-warmer.ts
// Runs every Monday at 8am, then re-arms itself.
export default defineAgent({
  name: "pipeline-warmer",
  async onWake(ctx) {
    const stale = await ctx.tools.crm.findDeals({ quietForDays: 7 });

    for (const deal of stale) {
      const change = await ctx.tools.research.whatChanged(deal.company);
      await ctx.draftFollowUp(deal, change);   // waits for your approval
    }

    // hand the work off and go quiet until next week
    await ctx.scheduleNext({ cron: "0 8 * * 1" });
  },
});

When Monday comes, the agent wakes on its own, does the sweep, leaves drafts waiting for your yes, and goes back to sleep. You never opened a tab. You just find the work done, staged for approval, the next time you look.

What we traded away

None of this is free. Putting a durable, single-threaded object behind every agent is a stronger commitment than a stateless function, and it comes with real constraints worth naming.

DecisionWhat we gainWhat it costs
Durable Object per agentConsistent memory, self-schedulingOne agent is one thread; heavy fan-out needs care
Edge-resident stateLow latency, runs near the userStorage model is SQLite, not a big warehouse
Self-set alarmsNo external scheduler to operateThe agent owns its own reliability

For the work AgentNava is built to do (a proactive agent per user, keeping a job moving) this is exactly the right trade. When a job genuinely needs heavy parallel compute or a filesystem, the agent hands that part off to a sandbox runtime instead. The Durable Object stays the calm, consistent brain; the heavy lifting happens elsewhere and reports back.

Key takeaways
  • An agent is not a conversation. It is a job that has to survive a closed tab.
  • Durable Objects give each agent consistent memory that outlives the session.
  • Self-set alarms let an agent wake, work, and re-arm with no external scheduler.
  • The result: you hand off the work and check in on progress, instead of driving every step.

Where this goes next

The runtime that keeps an agent alive is the foundation for everything above it: connections to the tools you already use, a canvas you can co-edit with the agent, and the phase indicator that shows you, in plain language, what the agent is doing right now. We will dig into each of those in future posts.

For now, the one idea worth keeping: the agent was never in the tab. Close it whenever you like. The work keeps moving.

RP
Raj Kiran
Founder · AgentNava

Building the workspace where non-developers describe the work and get a proactive agent that keeps it moving in production. Writes here about the runtime, the product, and the playbooks behind both.

Stay in the loop

New posts, in your inbox.

A short note when we publish something worth your time. Product releases, engineering write-ups, and playbooks. No noise.

One email per post. Unsubscribe anytime.