Knowledge/AgentStudio/07-platform-features.md
07 — Platform Features
Agent Studio includes built-in features for memory, suggestions, caching, conversation persistence, and security that we currently re-implement in custom code. This section catalogs each feature, what it costs to use, and when to choose it over a custom equivalent.
Quick comparison: what we have vs what the platform offers
| Capability | Today (custom) | Platform feature | Effort to switch |
|---|---|---|---|
| Conversation history | Redis-based session state in lib/search/orchestrator.ts |
config.memory.enabled: true + id: "alg_cnv_..." per request |
Medium — replace Redis read/writes with conversation ID handling |
| Follow-up suggestions | Maverick prompt produces inline discovery questions | config.suggestions.enabled: true |
Easy — flip flag, remove prompt section |
| First-message caching | None | config.useCache: true (default) |
Free — already on by default |
| User identity / row-level security | Custom session tokens | X-Algolia-Secure-User-Token JWT |
Medium — generate JWTs server-side |
| Personalization signals | Custom 8-signal extraction in signal_extractor.ts |
searchParameters.userToken + enablePersonalization |
Medium — depends on whether we want to keep custom signals |
Memory (conversation persistence)
How it works (per 03-capabilities.md §2)
When you pass id and per-message id in the completions request body, Agent Studio automatically:
- Saves the conversation
- Generates a title from the first user message (60 char max)
- Persists for 0/30/60/90 days based on app's maxRetentionDays
- Stores: metadata (ID, timestamps, user token), message content, assistant responses, tool calls
- Allows retrieval via GET /1/agents/{agentId}/conversations and GET /1/agents/{agentId}/conversations/{conversationId}
Required identifiers
{
"id": "alg_cnv_abc123", // conversation ID (any string, prefix recommended)
"messages": [
{
"id": "alg_msg_1", // unique per message
"role": "user",
"content": "..."
}
]
}
Both IDs are MANDATORY. Missing either prevents saving.
Two access modes
Unauthenticated:
- Requires API key with logs ACL
- No user association; conversations are standalone
- No user-scoped retrieval (cannot filter by user)
- Suitable for: testing, internal tools, single-tenant apps
Authenticated:
- Uses X-Algolia-Secure-User-Token header with JWT (HS256)
- Requires API key with search ACL
- Links conversations to authenticated users via JWT sub claim
- Enables user-scoped retrieval and management
- Recommended for production multi-user applications
- User identity extracted EXCLUSIVELY from JWT sub — cannot be manipulated via request body
Per-request bypass
?memory=false query parameter disables persistence for a single completion call. Use for ephemeral testing, anonymous queries.
Retention
maxRetentionDays |
Behavior |
|---|---|
90 (default) |
90-day retention |
60 |
60-day retention |
30 |
30-day retention |
0 |
Privacy mode — disables caching AND content storage; metadata only |
When to use vs custom Redis
Use Agent Studio memory when: - Conversation continuity is the only state you need - You want auto-generated titles, exports, retention policies - You want users to retrieve past conversations - Multi-user / authenticated scenario with user-scoped retrieval
Keep custom (Redis) when: - You need rich state beyond conversation history (8-signal discovery state, qualification scores, custom session metadata) - You need cross-agent state (one Redis key shared across Maverick + Elena + Bruno turns) that platform memory doesn't replicate - You need sub-100ms reads from session state (Redis is faster than the Agent Studio API)
For our case: Maverick's 8-signal extraction state is the only thing that genuinely needs custom storage. Conversation history can move to platform memory. The two can co-exist — Redis for signals, Agent Studio for conversation continuity.
Suggestions (auto follow-up prompts)
Per 03-capabilities.md and 05-api-reference.md §4 "Prompt Suggestions Configuration":
{
"config": {
"suggestions": {
"enabled": true,
"model": "gpt-5-mini",
"system_prompt": "Based on the conversation, suggest 3 follow-up questions...",
"generation": {
"max_count": 3, // 1-5
"max_words": 8, // 5-15
"timeout_seconds": 10 // 1-30
},
"context": {
"max_messages": 10, // 1-50
"include_tool_outputs": false
}
}
}
}
Response includes:
{
"type": "suggestions-chunk",
"suggestions": ["How do I filter by price?", "Show me trending products"]
}
When to enable
- The frontend wants to render clickable follow-up chips after each agent response
- The use case is exploratory (user benefits from being shown what to ask next)
- You're OK paying for an additional LLM call per response (configurable model — use a fast/cheap one)
Why we should enable it on Elena/Bruno
Today Maverick generates discovery questions inline in its prompt (<discovery_pivot> tag). This is custom prompt engineering for a feature the platform offers natively. Elena and Bruno don't have follow-up suggestions at all.
After refactor: enable suggestions on all three agents. Replace Maverick's <discovery_pivot> with platform suggestions. Tune the suggestions system_prompt per agent to match the agent's tone.
Caching
How it works (per 03-capabilities.md §3)
- Caching only applies to the FIRST message in a conversation. Multi-turn conversations always call the LLM directly. This is critical — caching is for cold-start, not turn-by-turn.
- Cache key derived from: message content (whitespace-trimmed), tool call IDs+names+arguments+outputs, tool configurations, agent configuration, date/time awareness settings
- Default retention: 90 days (based on app's
maxRetentionDays) - Configurable via
config.useCache: true|false - Per-request bypass via
?cache=false - Privacy mode (
maxRetentionDays: 0) auto-disables caching
Response headers
| Header | Values |
|---|---|
X-Cache |
HIT or MISS |
Cache-Status |
RFC 9211 (e.g., AgentStudio; hit) |
Multi-turn conversations don't include these headers (no caching beyond first message).
Date/time awareness
Cache reset frequency:
- None (default): full retention period
- date_aware: daily reset
- datetime_aware: every minute
Cache invalidation API
DELETE /1/agents/{agentId}/cache # full
DELETE /1/agents/{agentId}/cache?before=2026-01-01 # before a date
Returns { "deleted": <count> }. Requires editSettings ACL.
When this matters for us
For cold-start questions ("What is Algolia?", "How do I get started?"), the first message hits the cache. For follow-up turns ("And what about retrieval-augmented generation?"), no caching — every turn pays full LLM cost. Don't budget for "caching reduces our LLM bill"; budget for "caching helps cold start latency."
Playground note
The Agent Studio dashboard playground ALWAYS bypasses cache (per 03-capabilities.md §3 "Playground Behavior"). Useful for testing — you'll see real LLM behavior, not cached. But confusing if you forget about it.
Conversation IDs
The id field in completions requests serves two purposes:
- Memory persistence (above) — when
memory.enabledis true. - Continuity across requests — even without persistence, the same
idacross multiple completions is treated as the same conversation by the LLM (multi-turn context).
Use prefix conventions: alg_cnv_ for conversations, alg_msg_ for messages. These are recommendations, not enforced.
Secured user tokens (row-level security)
Per 02-tools.md §5.2:
When a user has different access permissions to different records, generate a SECURED API key with embedded filters. The Search API tool will then automatically apply those filters to all queries.
const securedAPIKey = client.generateSecuredApiKey({
parentApiKey: SEARCH_API_KEY,
restrictions: {
filters: `userId:${currentUser.id}`
}
});
// Pass via X-Algolia-API-Key header
The agent never sees the filter; it just queries. Algolia enforces the filter server-side based on the secured key.
When to use
Multi-tenant apps where each user can only see their own records. Enterprise-grade row-level security.
When NOT to use
Public content where everyone sees the same records. Adds JWT generation complexity for no benefit.
For Algolia Central: probably not needed for v1 — the content is public-ish. May matter for per-customer pilot deployments later (Sherwin Williams users vs MasterCard users seeing different data).
Personalization
Per 02-tools.md §2.6 query-time override fields:
{
"algolia": {
"searchParameters": {
"products": {
"userToken": "user-123",
"enablePersonalization": true,
"personalizationImpact": 75
}
}
}
}
personalizationImpact is 0-100. The user's prior behavior (queries, clicks, conversions, tracked via Insights API) influences ranking. Algolia's Personalization product handles the model.
When to use
You're already tracking user behavior via the Insights API. You have multiple user segments with distinct patterns. The default ranking doesn't align with individual user preferences.
When NOT to use
Anonymous users. New product without enough behavioral data. Concerns about "filter bubble" effects.
For our case: not relevant for v1. The 8-signal discovery extraction we do today is a different mechanism (discovery state, not behavioral personalization).
widgetType config
Binds an agent to a frontend widget:
| Value | Frontend pairing |
|---|---|
"chat" |
<Chat> widget (react-instantsearch) or chat() (instantsearch.js) |
"filterSuggestions" |
<FilterSuggestions> widget |
Setting this declaratively documents the intended frontend integration. The widgets work without it (just pass agentId), but the field is useful for tooling and dashboard UI.
templateType
Algolia provides agent templates that pre-fill instructions, tool config, and platform features:
| Template | Purpose |
|---|---|
shopping-assistant |
10-tool shopping assistant skeleton |
askai |
AskAI / DocSearch skeleton with multi-index search |
filter-suggestions |
FilterSuggestions agent skeleton |
blank |
Empty starting point |
Setting templateType is optional but documents intent and may unlock dashboard-specific tooling.
Things we should turn on for Elena/Bruno during refactor
Concrete recommendations:
- Enable
memory.enabled: true— adopt platform memory for conversation continuity. Keep Redis for 8-signal state. - Enable
suggestions.enabled: true— replace Maverick's custom discovery questions and add to Elena/Bruno where missing. Usegemini-2.5-flash-litefor the suggestions model (cheap, fast). - Set
widgetType: "chat"— declarative, supports the planned<Chat>widget integration. - Set
templateType: "askai"— Elena and Bruno are AskAI-archetype agents. Use the platform's hint. - Leave
useCache: true(default) — first-message cache is free latency. No reason to disable. - Skip secured user tokens for v1 — not needed until per-customer pilot deployments require row-level access control.
- Skip personalization for v1 — different mechanism than discovery, not aligned with current goals.
What this section does NOT cover
- Tool types — see 02-tool-types
- Frontend widgets that consume
widgetType— see 08-frontend-integration - Authentication patterns end-to-end — see 12-ui-and-instantsearch