Appearance
Configuration
Iris is configured through config/iris.php. All settings have sensible defaults, but understanding what they control helps you tune the system for your needs.
How Configuration Works
The base configuration lives in config/iris.php. To customize without modifying core files, create config/iris-custom.php and override specific values. See Customization for the full details on merge strategies.
php
// config/iris-custom.php
return [
'temporal' => [
'timezone' => 'America/Chicago',
],
];Agent Settings
These control the core chat behavior.
| Setting | Default | Description |
|---|---|---|
agent.model | claude-sonnet-4-5 | The Claude model used for chat |
agent.max_steps | 30 | Maximum tool iterations per request |
What max_steps controls: When Iris uses tools, it can iterate multiple times before responding. A request like "schedule a meeting and remind me later" might use 2-3 tools. The default of 30 allows for complex multi-step tasks while preventing runaway loops.
Context Settings
These control what information Iris has access to when responding.
| Setting | Default | Description |
|---|---|---|
context.history_limit | 50 | Recent messages included in context |
context.recent_summaries | 3 | Number of conversation summaries included |
How context builds: Each request includes recent messages (up to history_limit), recent summaries (providing continuity from older conversations), recalled memories, and calendar events. Larger values provide more context but increase token usage.
Truths Settings
Truths are stable, core facts about you that persist across conversations. Unlike memories that are retrieved contextually, Truths represent distilled knowledge earned through behavioral evidence.
| Setting | Default | Description |
|---|---|---|
truths.max_dynamic | 7 | Maximum non-pinned Truths included per conversation |
truths.percentile_threshold | 5 | Top N% of memories by access count are distillation candidates |
truths.min_total_memories | 20 | Minimum memories required before distillation runs |
truths.similarity_threshold | 0.40 | Minimum relevance score for a Truth to be included |
truths.duplicate_threshold | 0.80 | Similarity threshold to detect duplicate Truths |
truths.stale_days | 90 | Days without access before a Truth is considered stale |
truths.crystallization_model | claude-sonnet-4-5 | Model for refining Truths with new evidence |
truths.promotion_model | claude-sonnet-4-5 | Model for analyzing promotion candidates |
truths.jobs_per_minute | 10 | Rate limit for distillation API calls |
Pinned vs Dynamic Truths: You can pin any Truth to ensure it's always included, regardless of relevance scoring. The max_dynamic setting only limits non-pinned Truths - pinned Truths are unlimited.
Run distillation manually:
bash
php artisan iris:distill-truths --queue # Process all users
php artisan iris:distill-truths --user=1 --queue # Process specific user
php artisan iris:distill-truths --dry-run # Preview without changesMemory Settings
Memory settings control how Iris retrieves contextual information during conversations.
| Setting | Default | Description |
|---|---|---|
memory.max_results | 7 | Maximum memories from semantic search |
memory.similarity_threshold | 0.38 | Minimum similarity score to include a memory |
memory.context_turns | 20 | Conversation turns used to generate search queries |
memory.recall_model | claude-sonnet-4-5 | Model for generating memory search queries |
How memory retrieval works: When you start a conversation, Iris generates search queries based on recent messages and finds semantically similar memories. Only memories above the similarity threshold are included, keeping context focused on what's relevant.
Scoring Weights
Memories are ranked by a composite score:
(semantic × 0.60) + (recency × 0.25) + (frequency × 0.15)| Weight | Factor | What it means |
|---|---|---|
semantic | 0.60 | How relevant to the current conversation |
recency | 0.25 | Decays linearly over 90 days |
frequency | 0.15 | How often the memory has been accessed |
Certain memory types receive bonuses: relationships (+0.10), preferences and goals (+0.05), and recent events (+0.10).
TIP
If memories seem stale, increase the recency weight. If relevant memories aren't surfacing, increase semantic or lower similarity_threshold.
Extraction Settings
Extraction controls how memories are automatically created from conversations.
| Setting | Default | Description |
|---|---|---|
extraction.threshold | 10 | Messages between extraction runs |
extraction.max_memories | 6 | Maximum memories per extraction |
extraction.timeout | 120 | API timeout in seconds |
extraction.model | claude-sonnet-4-5 | Model for analyzing conversations |
The quality vs quantity tradeoff: A lower max_memories forces the extraction model to be selective, producing higher-quality memories. Increasing it may capture more information but risks storing trivial details.
Summarization Settings
Summarization compresses older messages to preserve context without consuming too many tokens.
| Setting | Default | Description |
|---|---|---|
summarization.threshold | 40 | Unsummarized messages before triggering |
summarization.keep_recent | 50 | Messages to keep in active conversation |
summarization.buffer | 35 | Recent messages excluded from summarization |
summarization.timeout | 120 | API timeout in seconds |
summarization.model | claude-sonnet-4-5 | Model for generating summaries |
How summarization triggers: When unsummarized messages exceed threshold, the system summarizes older messages while keeping the most recent buffer messages intact. The keep_recent setting determines how many total messages remain active before older ones are marked as summarized.
WARNING
Very aggressive summarization (low threshold) may lose conversational nuance. The defaults balance context preservation with token efficiency.
Consolidation Settings
Consolidation merges semantically similar memories into denser, more useful representations over time.
| Setting | Default | Description |
|---|---|---|
consolidation.similarity_threshold | 0.80 | Minimum cosine similarity to cluster |
consolidation.days_lookback | 3 | Days to look back for daily runs |
consolidation.max_memories_per_run | 100 | Rate limit per consolidation run |
consolidation.max_cluster_size | 5 | Max memories per cluster |
consolidation.min_cluster_size | 2 | Min memories to form a cluster |
consolidation.max_generation | 5 | Max consolidation generations |
consolidation.timeout | 120 | API timeout in seconds |
consolidation.model | claude-sonnet-4-5 | Model for merge decisions |
consolidation.jobs_per_minute | 10 | Rate limit for API calls |
Understanding generations: Original memories are Generation 0. When merged, the result is Generation 1. Memories can be re-consolidated up to Generation 5, allowing them to evolve as more related information is gathered. See Memory Consolidation for details.
Run consolidation manually:
bash
php artisan iris:consolidate-memories
php artisan iris:consolidate-memories --dry-run # Preview without changesTruth Consolidation Settings
Truth consolidation merges semantically similar Truths to reduce redundancy. Unlike memory consolidation which runs daily, truth consolidation runs weekly since Truths accumulate more slowly.
| Setting | Default | Description |
|---|---|---|
truth_consolidation.similarity_threshold | 0.75 | Minimum cosine similarity to cluster |
truth_consolidation.max_cluster_size | 5 | Max Truths per cluster |
truth_consolidation.min_cluster_size | 2 | Min Truths to form a cluster |
truth_consolidation.timeout | 120 | API timeout in seconds |
truth_consolidation.model | claude-sonnet-4-5 | Model for merge decisions |
truth_consolidation.jobs_per_minute | 10 | Rate limit for API calls |
Protection model: Only Promoted Truths are eligible for consolidation. User-created, agent-created, and pinned Truths are protected. Truths at the maximum generation are also excluded.
The threshold (0.75) is lower than memory consolidation (0.80) because Truths are already distilled facts - semantic overlap is more likely to be true redundancy.
Run consolidation manually:
bash
php artisan iris:consolidate-truths
php artisan iris:consolidate-truths --dry-run # Preview without changesSee Truth Consolidation for details on how it works.
Calendar Settings
| Setting | Default | Description |
|---|---|---|
calendar.cache_ttl | 15 | Cache duration in minutes |
calendar.event_horizon | 7 | Days ahead to include in context |
Why caching matters: Calendar data is fetched from Google's API and cached to avoid repeated requests. The event_horizon controls how far ahead Iris looks -a larger value gives more scheduling context but increases the data in each request.
Embeddings Settings
| Setting | Default | Description |
|---|---|---|
embeddings.model | text-embedding-3-small | OpenAI embedding model |
Embeddings power semantic search. The text-embedding-3-small model offers a good balance of quality and cost. Changing this affects how memories are stored and retrieved.
Text-to-Speech Settings
NOTE
Text-to-speech is disabled by default. Enable it by setting IRIS_TTS_ENABLED=true in your .env.
| Setting | Default | Description |
|---|---|---|
tts.enabled | false | Enable TTS audio playback |
tts.model | eleven_multilingual_v2 | ElevenLabs model |
tts.voice | (configured) | Voice ID for speech generation |
When enabled, assistant messages display a play button that generates audio using ElevenLabs. See Text-to-Speech for setup instructions.
Proactive Messages Settings
NOTE
This is a beta feature. It is enabled by default and can be configured in Settings > Proactive Messages.
| Setting | Default | Description |
|---|---|---|
heartbeat.model | claude-sonnet-4-5 | Model for heartbeat decisions |
heartbeat.max_steps | 30 | Maximum tool iterations when crafting messages |
heartbeat.history_limit | null | Conversation messages included (null = use default) |
How it works: Iris runs a heartbeat every 30 minutes, gathering context (calendar, conversations, memories) and deciding whether to proactively reach out. Users configure guidance (soft preferences) and boundaries (hard constraints like quiet hours) through the UI.
See Proactive Messages for detailed usage and configuration.
Temporal Settings
| Setting | Default | Description |
|---|---|---|
temporal.timezone | America/New_York | Timezone for date/time context |
This timezone is injected into the system prompt so Iris knows the current date and time. Set it to match your location.
Shell Settings
WARNING
Shell command execution is disabled by default. Enable only on trusted deployments.
| Setting | Default | Description |
|---|---|---|
shell.enabled | false | Enable shell command execution |
shell.default_timeout | 30 | Default timeout in seconds |
shell.max_timeout | 300 | Maximum allowed timeout (5 minutes) |
shell.max_output_length | 50000 | Maximum output size in bytes |
shell.default_working_directory | null | Default directory for commands |
shell.blocked_executables | ['sudo', ...] | Blocked command names |
shell.blocked_patterns | [...] | Regex patterns to block |
shell.inherit_env_vars | ['PATH', ...] | Environment variables to inherit |
Enable via environment variable:
bash
# .env
IRIS_SHELL_ENABLED=trueSecurity layers: Privilege escalation commands are blocked (sudo, su, doas, pkexec). Dangerous patterns like rm -rf / and direct disk writes are detected and blocked. Only safe environment variables are inherited.
See Shell Commands for detailed usage and security information.
Broadcasting Settings
Iris uses Laravel Reverb for real-time streaming. Configure via environment variables:
| Setting | Default | Description |
|---|---|---|
BROADCAST_CONNECTION | reverb | Broadcasting driver |
REVERB_APP_ID | - | Application identifier |
REVERB_APP_KEY | - | Client authentication key |
REVERB_APP_SECRET | - | Server-side secret |
REVERB_HOST | localhost | Reverb server hostname |
REVERB_PORT | 8080 | Reverb server port |
REVERB_SCHEME | http | Protocol (http or https for production) |
Event Storage
Stream events are temporarily stored in Redis for connection recovery. Events remain available for replay, allowing clients to catch up after brief disconnections.
Sub-Agent Settings
WARNING
Task delegation is disabled by default. Requires shell commands to also be enabled.
| Setting | Default | Description |
|---|---|---|
subagent.enabled | false | Enable task delegation |
subagent.model | claude-sonnet-4-5 | Model for the sub-agent |
subagent.max_steps | 30 | Maximum tool iterations per task |
subagent.default_working_directory | null | Default directory for tasks |
subagent.request_timeout | 120 | HTTP timeout per API request |
subagent.default_timeout | 300 | Default task timeout (5 minutes) |
subagent.max_timeout | 600 | Maximum task timeout (10 minutes) |
Enable via environment variables:
bash
# .env
IRIS_SUBAGENT_ENABLED=true
IRIS_SHELL_ENABLED=true
IRIS_SUBAGENT_WORKING_DIR=/home/user/projects # Optional default directoryHow it works: Task delegation spawns an autonomous sub-agent using Prism's agent loop. The sub-agent has access to shell commands and web tools, executing multi-step tasks independently before returning results.
Constraints: One active task per user to prevent resource exhaustion. Inherits all shell security settings.
See Task Delegation for detailed usage information.
Token Usage Tracking
Iris tracks API token consumption across all operations. You can monitor usage by source type:
| Source | What it tracks |
|---|---|
chat | Main conversation tokens |
summarization | Summary generation tokens |
extraction | Memory extraction tokens |
consolidation | Memory consolidation tokens |
truth_consolidation | Truth consolidation tokens |
promotion | Truth promotion analysis tokens |
crystallization | Truth crystallization tokens |
embedding | OpenAI embedding API calls |
Token data is stored in the token_usages table and can be queried for cost analysis or monitoring dashboards.
Common Configuration Scenarios
Lower API Costs
php
// config/iris-custom.php
return [
'extraction' => [
'threshold' => 20, // Extract less frequently
],
'summarization' => [
'threshold' => 60, // Summarize less often
],
'truths' => [
'max_dynamic' => 3, // Fewer dynamic Truths per conversation
],
'memory' => [
'max_results' => 5, // Fewer search results
],
];More Responsive Memory
php
// config/iris-custom.php
return [
'extraction' => [
'threshold' => 5, // Extract more frequently
],
'memory' => [
'max_results' => 10, // More search results
'similarity_threshold' => 0.10, // Lower threshold
],
];Conservative Memory Consolidation
php
// config/iris-custom.php
return [
'consolidation' => [
'similarity_threshold' => 0.90, // Only very similar memories
'max_generation' => 3, // Limit consolidation depth
],
];Conservative Truth Consolidation
php
// config/iris-custom.php
return [
'truth_consolidation' => [
'similarity_threshold' => 0.85, // Only very similar truths
],
];Aggressive Truth Promotion
php
// config/iris-custom.php
return [
'truths' => [
'percentile_threshold' => 20, // Wider candidate pool
'min_total_memories' => 10, // Start promoting sooner
],
];Enable Shell Commands
php
// config/iris-custom.php
return [
'shell' => [
'default_timeout' => 60,
'default_working_directory' => '/home/user/projects',
],
];Then set IRIS_SHELL_ENABLED=true in your .env.
Enable Task Delegation
php
// config/iris-custom.php
return [
'subagent' => [
'max_steps' => 50,
'default_timeout' => 600, // 10 minutes for complex tasks
'default_working_directory' => '/home/user/projects',
],
];Then set both IRIS_SUBAGENT_ENABLED=true and IRIS_SHELL_ENABLED=true in your .env.
Skills Settings
| Setting | Default | Description |
|---|---|---|
skills.enabled | true | Enable agent skills |
skills.directory | .agents/skills | Directory to load skills from |
Skills extend Iris with specialized knowledge and workflows. See Agent Skills for details.