AI agents

Agents that run for hours and still finish

Run the agent loop as a durable function that checkpoints every model and tool call, with tools as functions, memory in Postgres, and the signed-in user's permissions on every query.

agent-backend
volcano cloud durable deploy --allagent-run        python3.14   durablevolcano cloud functions deploy --allsearch-orders    python3.12   deployedissue-refund     python3.12   deployedvolcano cloud databases migration up --all -d app001_threads.sql  002_policies.sql  ok✓ runs checkpointed · tools live · policies on every table# a failed tool or a crash resumes the run; it never starts over
Overview

The model is the easy part. Finishing the run is not.

A prototype agent is a loop inside one request. A real one runs for minutes or hours, calls tools that time out, waits for a person to approve a refund, and crashes halfway through a plan. Restart it from the top and you pay for every model call again, and repeat every tool call that already went through.

On Volcano the loop is a durable function. Every model call and tool call is a checkpointed step, so a failed or interrupted step can retry, completed steps replay without rerunning, and a wait for approval holds nothing running. Tools deploy as functions, memory is ordinary Postgres under row-level security, and whatever the agent does for a user can only reach that user's rows.

Runs

A run that survives a failed tool call

Write the loop as a durable function and each model call and tool call is a step. A tool that times out is retried on its own, completed model calls replay from their checkpoints after a crash, and ctx.wait_until holds the run until a person approves the action it is about to take. Use provider idempotency keys when an interrupted attempt must not repeat a call.

  • Every model and tool call checkpointed
  • Hours of work, or days of waiting, in one run
  • Human sign-off before anything irreversible
agent-run · execution r-4102
step  model-1        plan: find the order, then refundstep  tool-1         search-orders → 1 matchstep  model-2        wants issue_refund · $42.00wait  approve-2      pending → approved by supportstep  refund-2       issue_refund → refunded✓ succeeded · completed model steps replayed from checkpoints
Tools

A tool is a deployed function

Write it in Python, Node or Ruby and deploy it with one command. There is no gateway to configure and no extra process to keep running, so adding a capability is a file and a deploy.

  • Python 3.10 through 3.14, Node 22/24, Ruby 3.3+
  • Called over HTTP or through the SDK
  • Up to 30 seconds per tool call on Hobby or 180 on Superagent
volcano cloud functions list
# Superagent project · 180s timeoutsearch-orders    python3.12   public   180s  invoke: https://3cd3e058.functions.volcano.run/issue-refund     python3.12   private  180s  invoke: https://7a1f92b4.functions.volcano.run/lookup-customer  python3.12   private  180s  invoke: https://b48c0d17.functions.volcano.run/# private tools refuse the anon key a browser ships with
Authorization

The agent inherits the caller

Every invocation carries a verified identity on the event, so a tool queries as the person who asked rather than with a key that can read everything. A prompt injection cannot widen what the database will return.

  • event.__volcano_auth holds the verified user
  • Their access token rides along, so a tool can call a tool
  • Blast radius is one user's data
volcano.dev/dashboard/edge-function
Agent tools deployed as functions, with their runtime and visibility
Path to production

How it works

  1. 01

    Model the threads

    Threads, messages and tool calls as tables, with a user_id on each and row-level security switched on.

  2. 02

    A function per tool

    One function per capability. Read the identity off the event and let the database decide what it returns.

  3. 03

    Run the loop

    A durable function that calls your model, runs each tool call as a step, and appends every turn to the thread.

  4. 04

    Give it a face

    A Next.js app on Volcano, streaming progress over a realtime channel while the loop works.

Code

Memory, a tool, the run, and the deploy

SQL
create table if not exists threads ( id uuid primary key default gen_random_uuid(), user_id uuid not null, title text, created_at timestamptz not null default now() ); create table if not exists messages ( id uuid primary key default gen_random_uuid(), thread_id uuid not null references threads(id) on delete cascade, user_id uuid not null, role text not null check (role in ('user', 'assistant', 'tool')), content text not null, tool_name text, created_at timestamptz not null default now() ); create index if not exists messages_thread_idx on messages (thread_id, created_at); alter table threads enable row level security; alter table messages enable row level security; -- The agent runs as the user. These policies are the whole security model. drop policy if exists own_threads on threads; create policy own_threads on threads for all to authenticated using (user_id = auth.uid()) with check (user_id = auth.uid()); drop policy if exists own_messages on messages; create policy own_messages on messages for all to authenticated using (user_id = auth.uid()) with check (user_id = auth.uid());
Return

What you skip

One identityfrom client to row

The user's token reaches the tool and the policy, so no tool needs its own auth logic.

3 runtimesfor tools

Python, Node and Ruby, so a tool can live wherever the library you need already is.

366 daysfor one agent run

Checkpointed per step, so a run can wait for approval or retry a tool without starting over.

What you get

Scoped by default

A tool can only reach what the asking user could reach.

Runs that finish

A failed tool or a crash resumes the run instead of restarting it.

Nothing to operate

No queue, no worker fleet, nothing running between turns.

Platform

Built on Volcano

Functions and agents
  • The tools

    Functions in Python, Node or Ruby, each one receiving the caller's verified identity.

Durable functions
  • Runs that outlast a request

    Durable functions that checkpoint every model and tool call, retry what fails and wait for approval.

Databases and vector
  • Memory and retrieval

    Threads and messages as tables, embeddings in a pgvector column, and row-level security over both.

Authentication
  • Who the agent acts for

    Sessions that reach the database as auth.uid(), so the agent inherits a real user instead of an admin key.

Frequently asked questions

Read the docs
Does Volcano run the model?

No. You call whichever provider you use from inside a function, with the key stored as a project variable. Volcano runs the tools, the loop and the memory around it.

How do I stop a prompt injection reading another customer's data?

Connect as the caller instead of as an admin. The tool inherits that user's row-level policies, so a convincing prompt still cannot make Postgres return rows the user was never allowed to see.

Why run the agent loop as a durable function?

Because agent runs fail in the middle. Each model call and tool call becomes a checkpointed step, so one run can take hours, wait days for an approval, and replay completed steps after a failure. An interrupted attempt can retry, so use provider idempotency keys for calls that must not repeat. An execution can run for up to 366 days, and each step gets up to 300 seconds on Hobby or 900 seconds on Superagent.

Can tools call other tools?

Yes, over HTTP. Forward the caller's token so the second tool runs as the same user instead of escalating partway through the chain. Marking a tool private stops a bare anon key reaching it, while a real session still can.

How do several agents avoid working on the same task?

Give each task a lock. An agent that calls volcano.locks.withLock('ticket:4821', { ttl: 60 }, work) holds the task while it works, every other agent gets acquired: false and moves on, and a task whose agent crashed is free again when its lease runs out.

How do I show the user what the agent is doing?

Broadcast each step on a realtime channel while the loop runs. The page updates as tools are called, and nobody has to poll a status endpoint.

Ready to run your agent?

Build, deploy, and scale on Volcano's global platform — free to start, with no infrastructure to manage.

Explore more solutions