Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion prompts/en/branch.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ Depending on why the channel branched, you might:
## Tools

### memory_recall
Search for relevant memories. Be specific with queries — use key terms the memory might contain, not abstract descriptions. You'll get curated results ranked by relevance. Use these to inform your conclusion.
Search for relevant memories. Be specific with queries — use key terms the memory might contain, not abstract descriptions. You'll get curated results ranked by relevance. Use these to inform your conclusion. For recency-oriented asks ("what did we discuss recently?", "last talk"), prefer `mode: "recent"` instead of hybrid.

### memory_save
Save something important that came up during your thinking. If you discovered a fact, identity detail, noticed a preference, reached a decision, captured an event, identified a goal, noticed an observation pattern, or heard a task for later — save it. The channel doesn't save memories — that's your job.

### memory_delete
Forget a memory by ID. Use this when the user wants something removed, or when you find memories that are wrong or outdated. Get memory IDs from memory_recall results. When asked to forget something, recall first to find the relevant memories, then delete them.

### channel_recall
Recall transcript history from any channel, including this one. Use this for "what did we talk about last time?" and similar requests where exact conversation history matters. This reads persisted conversation messages, not long-term memory summaries.

### spacebot_docs
Read embedded Spacebot docs, including `AGENTS.md`, `CHANGELOG.md`, and product docs from `docs/content/`. Use `action: "list"` to discover IDs, then `action: "read"` for the specific document.

Expand Down
2 changes: 1 addition & 1 deletion prompts/en/tools/memory_recall_description.md.j2
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Search and recall memories from the memory store. Supports multiple search modes: "hybrid" (semantic + keyword + graph search, requires a query), "recent" (most recent memories by time), "important" (highest importance memories), and "typed" (filter by memory type). Default mode is hybrid.
Search and recall memories from the memory store. Supports multiple search modes: "hybrid" (semantic + keyword + graph search, requires a query), "recent" (most recent memories by time), "important" (highest importance memories), and "typed" (filter by memory type). Default mode is hybrid. For "what did we discuss recently?" style queries, prefer "recent" mode.
40 changes: 40 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1854,4 +1854,44 @@ command = "/usr/bin/test"
// The mcp_servers data is silently dropped — verify it's not accessible
assert!(parsed.defaults.mcp.is_empty());
}

#[test]
fn top_level_memory_persistence_is_still_honored() {
let _guard = env_test_lock().lock();
let guard = EnvGuard::new();

let toml_content = r#"
[memory_persistence]
enabled = true
message_interval = 7
"#;
let config_path = guard.test_dir.join("config.toml");
std::fs::write(&config_path, toml_content).unwrap();

let config = Config::load_from_path(&config_path).unwrap();
assert!(config.defaults.memory_persistence.enabled);
assert_eq!(config.defaults.memory_persistence.message_interval, 7);
}

#[test]
fn defaults_memory_persistence_overrides_top_level_legacy() {
let _guard = env_test_lock().lock();
let guard = EnvGuard::new();

let toml_content = r#"
[memory_persistence]
enabled = false
message_interval = 99

[defaults.memory_persistence]
enabled = true
message_interval = 5
"#;
let config_path = guard.test_dir.join("config.toml");
std::fs::write(&config_path, toml_content).unwrap();

let config = Config::load_from_path(&config_path).unwrap();
assert!(config.defaults.memory_persistence.enabled);
assert_eq!(config.defaults.memory_persistence.message_interval, 5);
}
}
11 changes: 11 additions & 0 deletions src/config/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub fn set_resolve_secrets_store(store: std::sync::Arc<crate::secrets::store::Se
const KNOWN_TOP_LEVEL_KEYS: &[&str] = &[
"llm",
"defaults",
"memory_persistence",
"agents",
"links",
"groups",
Expand All @@ -90,6 +91,15 @@ pub(super) fn warn_unknown_config_keys(content: &str) {
};

for key in table.keys() {
if key == "memory_persistence" {
tracing::warn!(
"config.toml contains top-level key `memory_persistence`. \
This legacy location is still supported, but prefer \
[defaults.memory_persistence] for new configs."
);
continue;
}

if KNOWN_TOP_LEVEL_KEYS.contains(&key.as_str()) {
continue;
}
Expand Down Expand Up @@ -1403,6 +1413,7 @@ impl Config {
memory_persistence: toml
.defaults
.memory_persistence
.or(toml.memory_persistence)
Comment on lines 1415 to +1416

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Merge legacy memory_persistence fields instead of whole table

Using Option::or here makes [defaults.memory_persistence] win as an all-or-nothing table, so when both locations are present and the new table is only partially populated, values from legacy [memory_persistence] are silently dropped and replaced by hardcoded defaults (for example, message_interval reverts to 50). This breaks backward-compatibility during incremental migrations; precedence should be applied per field (enabled/message_interval) rather than by selecting one entire table.

Useful? React with 👍 / 👎.

.map(|mp| MemoryPersistenceConfig {
enabled: mp
.enabled
Expand Down
2 changes: 2 additions & 0 deletions src/config/toml_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub(super) struct TomlConfig {
#[serde(default)]
pub(super) defaults: TomlDefaultsConfig,
#[serde(default)]
pub(super) memory_persistence: Option<TomlMemoryPersistenceConfig>,
#[serde(default)]
pub(super) agents: Vec<TomlAgentConfig>,
#[serde(default)]
pub(super) links: Vec<TomlLinkDef>,
Expand Down