fix(channels): use platform message IDs to prevent duplicate memories
Fixes #430 - Prevents duplicate memories after restart by using platform message IDs instead of random UUIDs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c3cc835346
commit
e8553a800a
9 changed files with 217 additions and 82 deletions
|
|
@ -76,7 +76,10 @@ pub fn create_memory(
|
|||
// Auto-hydration: if brain.db is missing but MEMORY_SNAPSHOT.md exists,
|
||||
// restore the "soul" from the snapshot before creating the backend.
|
||||
if config.auto_hydrate
|
||||
&& matches!(classify_memory_backend(&config.backend), MemoryBackendKind::Sqlite | MemoryBackendKind::Lucid)
|
||||
&& matches!(
|
||||
classify_memory_backend(&config.backend),
|
||||
MemoryBackendKind::Sqlite | MemoryBackendKind::Lucid
|
||||
)
|
||||
&& snapshot::should_hydrate(workspace_dir)
|
||||
{
|
||||
tracing::info!("🧬 Cold boot detected — hydrating from MEMORY_SNAPSHOT.md");
|
||||
|
|
@ -143,10 +146,7 @@ pub fn create_memory_for_migration(
|
|||
}
|
||||
|
||||
/// Factory: create an optional response cache from config.
|
||||
pub fn create_response_cache(
|
||||
config: &MemoryConfig,
|
||||
workspace_dir: &Path,
|
||||
) -> Option<ResponseCache> {
|
||||
pub fn create_response_cache(config: &MemoryConfig, workspace_dir: &Path) -> Option<ResponseCache> {
|
||||
if !config.response_cache_enabled {
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,9 +90,7 @@ impl ResponseCache {
|
|||
WHERE prompt_hash = ?1 AND created_at > ?2",
|
||||
)?;
|
||||
|
||||
let result: Option<String> = stmt
|
||||
.query_row(params![key, cutoff], |row| row.get(0))
|
||||
.ok();
|
||||
let result: Option<String> = stmt.query_row(params![key, cutoff], |row| row.get(0)).ok();
|
||||
|
||||
if result.is_some() {
|
||||
// Bump hit count and accessed_at
|
||||
|
|
@ -109,13 +107,7 @@ impl ResponseCache {
|
|||
}
|
||||
|
||||
/// Store a response in the cache.
|
||||
pub fn put(
|
||||
&self,
|
||||
key: &str,
|
||||
model: &str,
|
||||
response: &str,
|
||||
token_count: u32,
|
||||
) -> Result<()> {
|
||||
pub fn put(&self, key: &str, model: &str, response: &str, token_count: u32) -> Result<()> {
|
||||
let conn = self
|
||||
.conn
|
||||
.lock()
|
||||
|
|
@ -162,19 +154,17 @@ impl ResponseCache {
|
|||
let count: i64 =
|
||||
conn.query_row("SELECT COUNT(*) FROM response_cache", [], |row| row.get(0))?;
|
||||
|
||||
let hits: i64 = conn
|
||||
.query_row(
|
||||
"SELECT COALESCE(SUM(hit_count), 0) FROM response_cache",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
let hits: i64 = conn.query_row(
|
||||
"SELECT COALESCE(SUM(hit_count), 0) FROM response_cache",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
|
||||
let tokens_saved: i64 = conn
|
||||
.query_row(
|
||||
"SELECT COALESCE(SUM(token_count * hit_count), 0) FROM response_cache",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
let tokens_saved: i64 = conn.query_row(
|
||||
"SELECT COALESCE(SUM(token_count * hit_count), 0) FROM response_cache",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
Ok((count as usize, hits as u64, tokens_saved as u64))
|
||||
|
|
@ -363,7 +353,9 @@ mod tests {
|
|||
let (_tmp, cache) = temp_cache(60);
|
||||
let key = ResponseCache::cache_key("gpt-4", None, "日本語のテスト 🦀");
|
||||
|
||||
cache.put(&key, "gpt-4", "はい、Rustは素晴らしい", 30).unwrap();
|
||||
cache
|
||||
.put(&key, "gpt-4", "はい、Rustは素晴らしい", 30)
|
||||
.unwrap();
|
||||
|
||||
let result = cache.get(&key).unwrap();
|
||||
assert_eq!(result.as_deref(), Some("はい、Rustは素晴らしい"));
|
||||
|
|
|
|||
|
|
@ -64,7 +64,10 @@ pub fn export_snapshot(workspace_dir: &Path) -> Result<usize> {
|
|||
|
||||
let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
||||
output.push_str(&format!("**Last exported:** {now}\n\n"));
|
||||
output.push_str(&format!("**Total core memories:** {}\n\n---\n\n", rows.len()));
|
||||
output.push_str(&format!(
|
||||
"**Total core memories:** {}\n\n---\n\n",
|
||||
rows.len()
|
||||
));
|
||||
|
||||
for (key, content, _category, created_at, updated_at) in &rows {
|
||||
output.push_str(&format!("### 🔑 `{key}`\n\n"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue