Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.getbindu.com/llms.txt

Use this file to discover all available pages before exploring further.

Picture this. Your agent is mid-task — a user asked it to summarize a 200-page document, it’s been thinking for 90 seconds — and the process restarts. Maybe a deploy, maybe an OOM, doesn’t matter. With in-memory storage, that task is gone. The user sees an error. The agent doesn’t even know it was working on something. That’s the trap: an agent that holds state in process memory is a demo, not a service. The moment uptime matters, you need persistence. Bindu defaults to in-memory because local laptops don’t have a Postgres handy. For production you switch to Postgres and the same code keeps running — tasks, contexts, and artifacts all land in a durable store you can query, replay, and audit.
In-memory is the default. Switch to Postgres by setting two environment variables — no code change in your handler. Details below.

How Bindu Storage Works

Bindu abstracts storage behind a consistent interface. You choose the backend in config; the rest of the system — TaskManager, workers, context handling — works the same regardless.

The Storage Model

Bindu stores three categories of data:
  • Tasks — state, messages, metadata, and lifecycle history
  • Contexts — shared conversation context across multiple tasks
  • Artifacts — outputs produced by the agent (text, files, structured data)

Tasks

Every task and its full state history, messages, and metadata.

Contexts

Shared context that spans multiple tasks in a conversation.

Artifacts

Agent outputs stored and retrievable by task ID.

Backends

Bindu supports two storage backends:
MemoryPostgreSQL
SetupNoneRequires PostgreSQL instance
PersistenceLost on restartSurvives restarts
ScalabilitySingle processMulti-instance, distributed
Use caseLocal developmentProduction
Config"type": "memory""type": "postgres"

Configuration

Storage backends are picked via environment variables. No code change, no config dict key — credentials don’t belong in a Python dict that ends up in git.

Memory (development)

# Default — no env vars needed. Just run your agent.
STORAGE_TYPE=memory
Tasks, contexts, and artifacts live in process memory. Gone when the agent stops. Fine for uv run agent.py while you’re building.

PostgreSQL (production)

STORAGE_TYPE=postgres
DATABASE_URL=postgresql://user:password@localhost:5432/bindu
Bindu creates the required tables automatically on first run. No manual schema setup, no migration step.
Put these in .env for local development, or wire them in through your container orchestrator’s secret manager in production. The config dict your agent code uses stays clean.

The Storage Lifecycle

Storage is used throughout the task lifecycle. Here is how it fits into a complete request: Every state transition is written to storage. If the agent restarts mid-task, the task can be recovered and resumed from its last known state.

Working with Tasks

Tasks are the primary unit of storage. Each task has a unique ID and carries its full history.

Retrieving a Task

curl -X POST http://localhost:3773/ \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tasks/get",
    "params": {
      "id": "task_abc123"
    },
    "id": 1
  }'
{
  "jsonrpc": "2.0",
  "result": {
    "id": "task_abc123",
    "status": {
      "state": "completed",
      "timestamp": "2026-03-30T12:00:00Z"
    },
    "history": [
      {"role": "user", "parts": [{"text": "Summarize this document"}]},
      {"role": "agent", "parts": [{"text": "Here is the summary..."}]}
    ],
    "artifacts": [
      {
        "name": "summary",
        "parts": [{"text": "The document covers..."}]
      }
    ]
  },
  "id": 1
}

Listing Tasks

curl -X POST http://localhost:3773/ \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tasks/list",
    "params": {},
    "id": 1
  }'

Contexts

Contexts allow multiple tasks to share a common conversation thread. When a caller provides a contextId, Bindu links the task to that context and preserves the shared history.
# First task in a context
response = await agent.send_message(
    "I am researching climate change",
    context_id="research-session-001"
)

# Follow-up task in the same context
response = await agent.send_message(
    "What were the key findings from the last IPCC report?",
    context_id="research-session-001"  # same context
)
# Agent has access to the full prior conversation
Contexts are stored alongside tasks and retrieved by contextId. They survive restarts when using PostgreSQL.

PostgreSQL Setup

For production deployments, you need a running PostgreSQL instance.

Docker (Quick Start)

docker run -d \
  --name bindu-postgres \
  -e POSTGRES_USER=bindu \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=bindu \
  -p 5432:5432 \
  postgres:16

Environment variables

STORAGE_TYPE=postgres
DATABASE_URL=postgresql://bindu:secret@localhost:5432/bindu

Schema

Bindu manages its own schema. On first startup with PostgreSQL configured, it creates the necessary tables:
bindu_tasks       — task state, metadata, and message history
bindu_contexts    — shared conversation contexts
bindu_artifacts   — agent output artifacts
No manual migration steps are needed for initial setup.

Real-World Use Cases

A user starts a research task, the agent asks a clarifying question, and the user responds. With persistent storage, the task resumes from input-required state with full context intact — even if the agent restarted between turns.
A data analysis task that takes several minutes. The client submits the task, gets a task_id immediately, and polls for completion. Storage keeps the task alive across the entire execution window.
Every task stores its full message history and state transitions. You can retrieve any past task by ID and inspect exactly what happened, when, and what the agent produced.
With PostgreSQL, multiple instances of the same agent share a single storage backend. Any instance can pick up a task from the queue and write results back to the same store.

Security Best Practices

Use environment variables

Database credentials don’t belong in a Python dict that ends up in git. Use DATABASE_URL and keep it in .env or your orchestrator’s secret manager.

Restrict Database Access

The Bindu agent only needs read/write access to its own tables. Use a dedicated database user with minimal permissions.

Sunflower LogoStorage is what turns a stateless script into an agent that remembers — every task, every turn, every result.