Stores
Stores are typed collections the agent reads and writes during sessions. Each file in amodal/stores/*.json defines one store, and the runtime generates its tools.
Store Definition
{
"name": "research-notes",
"entity": {
"name": "ResearchNote",
"key": "{company_id}:{topic}",
"schema": {
"company_id": { "type": "string" },
"topic": { "type": "string" },
"summary": { "type": "string" },
"confidence": { "type": "number", "min": 0, "max": 1 },
"updated_at": { "type": "datetime" },
"tags": { "type": "array", "item": { "type": "string" } },
"metadata": {
"type": "object",
"fields": {
"source": { "type": "string" },
"analyst": { "type": "string", "nullable": true }
}
}
}
},
"history": { "versions": 3 }
}| Field | Description |
|---|---|
name | Lowercase letters, digits, -, and _, starting with a letter. Defaults to the file name; a different name is a load error. |
entity.name | Entity type name. |
entity.key | Key template built from document fields, such as {company_id}:{topic}. |
entity.schema | Field definitions. A flat key and schema at the top level are also accepted in place of entity. |
history.versions | Number of previous versions kept per document. |
ttl | Expiry in seconds, or { "default": 86400, "override": [{ "condition": "status = 'done'", "ttl": 3600 }] }. Conditions support field = 'v', field != 'v', and field IN ['a', 'b']. |
deletable | true registers the remove tool. Default false. |
shared | true makes one collection readable by every scope. See Scoped vs. Shared Stores. |
Field Types
| Type | Extra fields |
|---|---|
string | nullable |
number | min, max, nullable |
boolean | nullable |
datetime | nullable |
enum | values (required) |
array | item (required) |
object | fields (required) |
ref | store (required) |
Every type accepts nullable.
Generated Tools
For a store named research-notes, the runtime registers store__research_notes__get, __set, __query, __list, and, with "deletable": true, __remove. Hyphens in the store name become underscores. See Built-in Tools.
Custom tools write with ctx.store(name, payload), which resolves the key from the payload.
Per-Agent Access
A named agent lists the stores its sessions can use, with "read" or "rw" access:
// agents/research/agent.json
{
"name": "Research",
"stores": {
"company-profiles": "read",
"research-notes": "rw"
}
}read grants get, query, and list. rw adds set and remove.
Storage Backend
Hosted deployments supply the backing database. amodal dev uses an in-memory store, so local data is lost when the dev server restarts.
Scoped vs. Shared Stores
Store data is partitioned by the request's scope_id; the hosted runtime does not require one (see Scope). "shared": true makes one collection that every scope reads:
{
"name": "company-profiles",
"shared": true,
"entity": {
"name": "CompanyProfile",
"key": "{company_id}",
"schema": {
"company_id": { "type": "string" },
"name": { "type": "string" }
}
}
}The runtime rejects writes and deletions to a shared store, including when an agent declares "rw". Populate reference catalogs outside the agent, and use scoped stores for records the agent updates.