Skip to main content

Store API

The Store API provides durable key-value storage for agents. It's intended for long-term memory that needs to persist across runs, threads, and even AgentVisor restarts (see Use Cases for examples of what to store).

Items are scoped by namespace and key, can hold arbitrary JSON values plus searchable metadata, and are accessed identically from agent code via the Python SDK (from agentvisor import store) or from external clients via the REST endpoints documented below.

warning

The Store API is disabled by default and must be explicitly enabled.

Configuration

Enable the Store API:

export AGENTVISOR_STORE_PROVIDER=sqlite

Built-in Providers:

  • sqlite: Embedded SQLite database (single-instance deployments only)
  • postgresql: Networked PostgreSQL backend, suitable for multi-instance production deployments
Pick the right provider for your deployment

The built-in sqlite provider stores all data in a local SQLite database. This is suitable for development, testing, and single-instance deployments, but not for multi-instance production because the database is not shared across AgentVisor instances. For multi-instance / horizontally-scaled deployments, use the postgresql provider with a shared PostgreSQL cluster.

SQLite Configuration

VariableDefaultDescription
AGENTVISOR_STORE_SQLITE_DB_PATH<cache_dir>/store.dbPath to the SQLite database file

The default <cache_dir> is the OS user cache directory (e.g., ~/.cache/agentvisor on Linux).

PostgreSQL Configuration

The full set of PostgreSQL connection, TLS, and pool tuning variables is documented in the configuration reference. Minimum to get started:

VariableDescription
AGENTVISOR_STORE_PROVIDERSet to postgresql
AGENTVISOR_STORE_POSTGRESQL_CONNECTION_STRINGPostgreSQL connection URI (e.g. postgres://user:pass@host:5432/agentvisor)
AGENTVISOR_STORE_POSTGRESQL_TLS_MODEdisable, require, verify-ca, or verify-full

List Namespaces

POST /store/namespaces

Request Body

The body is optional — omit it (or send {}) to list all namespaces.

{
"prefix": ["myapp"],
"limit": 10,
"offset": 0
}
FieldDescription
prefixOptional. Namespace prefix segments to filter by.
limitOptional. Max results (default 100, max 1000).
offsetOptional. Pagination offset.

Response

Each namespace is itself an array of path segments:

{
"namespaces": [["myapp"], ["user-data"], ["cache", "sessions"]]
}

Example

curl -X POST http://localhost:8090/store/namespaces | jq

Put Item

PUT /store/items?namespace={namespace}&key={key}

Request Body

{
"value": {
"theme": "dark",
"language": "en"
},
"metadata": {
"type": "preferences",
"user": "alice"
}
}

The namespace query parameter accepts a dot-separated path (?namespace=myapp.settings) or repeated params (?namespace=myapp&namespace=settings) for hierarchical namespaces.

Response

Returns 204 No Content with an empty body — the stored item is not echoed back. Use Get Item to read it back.

Example

curl -X PUT "http://localhost:8090/store/items?namespace=myapp&key=user-prefs" \
-H "Content-Type: application/json" \
-d '{"value": {"theme": "dark"}, "metadata": {"type": "preferences"}}'

Get Item

GET /store/items?namespace={namespace}&key={key}

Response

namespace is serialized as an array of path segments:

{
"namespace": ["myapp"],
"key": "user-prefs",
"value": {
"theme": "dark",
"language": "en"
},
"metadata": {
"type": "preferences"
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}

Example

curl "http://localhost:8090/store/items?namespace=myapp&key=user-prefs" | jq

Delete Item

DELETE /store/items?namespace={namespace}&key={key}

Response

Returns 204 No Content with an empty body.

Example

curl -X DELETE "http://localhost:8090/store/items?namespace=myapp&key=user-prefs"

Search Items

POST /store/items/search

Request Body

namespace is required and must be a JSON array of path segments — a plain string (e.g. "namespace": "myapp") fails with 400 Bad Request.

{
"namespace": ["myapp"],
"filter": {
"type": "preferences"
},
"limit": 10,
"offset": 0
}

Response

{
"items": [
{
"namespace": ["myapp"],
"key": "user-prefs-alice",
"value": {"theme": "dark"},
"metadata": {"type": "preferences", "user": "alice"},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
},
{
"namespace": ["myapp"],
"key": "user-prefs-bob",
"value": {"theme": "light"},
"metadata": {"type": "preferences", "user": "bob"},
"created_at": "2024-01-15T09:00:00Z",
"updated_at": "2024-01-15T09:00:00Z"
}
]
}

There is no total field — page through results using limit/offset.

Example

curl -X POST http://localhost:8090/store/items/search \
-H "Content-Type: application/json" \
-d '{"namespace": ["myapp"], "filter": {"type": "preferences"}}'

Python SDK

Access the store from agent code:

from agentvisor import store

# Store a value
store.put("myapp", "user-prefs", {"theme": "dark"})

# Retrieve it
prefs = store.get("myapp", "user-prefs")

# Search
items = store.search("myapp", filter={"type": "preference"})

# Delete
store.delete("myapp", "user-prefs")

Use Cases

  • User preferences: Store per-user settings
  • Conversation summaries: Long-term memory across threads
  • Knowledge base: Agent-maintained facts
  • Caching: Expensive computation results