Saved Queries
What are saved queries?
Saved queries let you store a CAL recipe once and execute it by name. Instead of regenerating complex RECALL or ASSEMBLE pipelines on every call, define the query once with DEFINE QUERY and invoke it with RUN.
DEFINE QUERY "user_prefs"($user, $limit = 10) AS {
RECALL beliefs WHERE subject = $user AND relation = "likes" RECENT $limit
}
RUN "user_prefs"($user = "john")
POST /api/memories/default/cal
Content-Type: text/cal
DEFINE QUERY "user_prefs"($user, $limit = 10) AS { RECALL beliefs WHERE subject = $user AND relation = "likes" RECENT $limit }
Saved queries persist across server restarts. They are scoped to the memory (database) where they are defined.
How do I define a saved query?
Use DEFINE QUERY with a name, optional parameters, and a body containing any read-tier CAL statement.
-- No parameters
DEFINE QUERY "recent_beliefs" AS {
RECALL beliefs RECENT 10
}
-- With parameters and defaults
DEFINE QUERY "user_prefs"($user, $limit = 10) AS {
RECALL beliefs WHERE subject = $user AND relation = "likes"
RECENT $limit WITH rerank
}
-- With a description
DEFINE QUERY "agent_context"($user, $budget = 4000)
DESCRIPTION "Full agent briefing for any user" AS {
ASSEMBLE "agent briefing" FROM
knowledge: (RECALL beliefs WHERE user_id = $user RECENT 20),
goals: (RECALL goals WHERE assigned_to = $user)
BUDGET $budget tokens
WITH dedup, diversity(0.5)
FORMAT markdown
}
-- COALESCE with fallback chains
DEFINE QUERY "find_preference"($user, $topic) AS {
COALESCE {
RECALL beliefs WHERE subject = $user AND relation = "likes" AND object LIKE $topic
} OR {
RECALL beliefs ABOUT $topic WHERE subject = $user
}
}
Parameter rules:
- Parameters use
$namesyntax - Optional defaults:
$limit = 10 - Parameters without defaults are required at
RUNtime - Maximum 10 parameters per query
Body rules:
- The body must contain only read-tier statements: RECALL, EXISTS, ASSEMBLE, HISTORY, COALESCE, BATCH
- Write statements (ADD, SUPERSEDE, ACCUMULATE, REVERT) are rejected
- RUN inside a body is rejected (no recursion)
How do I execute a saved query?
Use RUN with the query name and parameter bindings.
-- Basic
RUN "recent_beliefs"
-- With parameters (required params must be supplied)
RUN "user_prefs"($user = "john")
-- Override defaults
RUN "user_prefs"($user = "bob", $limit = 5)
POST /api/memories/default/cal
Content-Type: text/cal
RUN "user_prefs"($user = "john")
areev cal 'RUN "user_prefs"($user = "john")'
How do call-site overrides work?
When running a saved query, you can override the FORMAT and extend the WITH options at the call site. This lets you reuse the same retrieval logic with different output formats.
-- Same query, three different outputs
RUN "agent_context"($user = "john") FORMAT json -- dashboard
RUN "agent_context"($user = "john") FORMAT markdown -- report
RUN "agent_context"($user = "john") FORMAT TEMPLATE "email_summary" -- email
Override rules:
| Clause | Behavior |
|---|---|
FORMAT | Call-site replaces the body’s FORMAT entirely |
WITH | Call-site merges with body’s WITH options. On conflict, call-site wins |
-- Body defines: WITH dedup, diversity(0.5)
-- Call-site adds: WITH explanation, diversity(0.8)
-- Effective: WITH dedup, diversity(0.8), explanation
RUN "agent_context"($user = "john") WITH explanation, diversity(0.8)
How do I compose saved queries with output templates?
Saved queries and output templates serve different layers. DEFINE TEMPLATE controls how results look. DEFINE QUERY controls what results are retrieved. Compose them freely.
-- Step 1: Define an output template
DEFINE TEMPLATE "brief"
ELEMENT {
- [{{grain.type}}] {{grain.subject}}: {{grain.content}}
}
-- Step 2: Define a query
DEFINE QUERY "user_context"($user) AS {
RECALL beliefs WHERE subject = $user RECENT 20
}
-- Step 3: Compose at call site
RUN "user_context"($user = "john") FORMAT TEMPLATE "brief"
RUN "user_context"($user = "john") FORMAT json
RUN "user_context"($user = "john") FORMAT markdown
The same retrieval logic produces three different output formats without duplicating the query.
How do I list and inspect saved queries?
-- List all saved queries
DESCRIBE QUERIES
-- Inspect a specific query (shows params, body, description)
DESCRIBE QUERY "user_prefs"
POST /api/memories/default/cal
Content-Type: text/cal
DESCRIBE QUERIES
DESCRIBE QUERIES returns:
{
"queries": [
{ "name": "user_prefs", "description": "...", "param_count": 2, "body_size": 50 },
{ "name": "agent_context", "description": "Full agent briefing", "param_count": 2, "body_size": 180 }
]
}
DESCRIBE QUERY "user_prefs" returns the full definition including parameters, defaults, and body text.
How do I delete a saved query?
Use DROP QUERY. This requires cal_destructive_ops to be enabled on the database.
DROP QUERY "user_prefs"
What are the constraints?
| Constraint | Limit |
|---|---|
| Max queries per memory | 100 |
| Max body size | 8,192 bytes |
| Max parameters | 10 |
| Name format | Lowercase letters, digits, underscores. 1-64 chars. Must start with a letter. |
| Recursion | Forbidden (RUN inside DEFINE QUERY body is rejected) |
| Write statements in body | Forbidden (ADD, SUPERSEDE, etc. are rejected) |
Related
- CAL Guide: Full CAL statement reference including RECALL, ASSEMBLE, and LET bindings
- Search & Recall: How retrieval scoring, reranking, and WITH options work
- Supersede: How to update and version memories