antaris-memory 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 Antaris Analytics LLC
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+
19
+ PATENT NOTICE: The methods implemented in this software are the subject
20
+ of US Patent Application #63/983,397 (pending). Use of this software
21
+ under the Apache 2.0 license includes an implied patent license for
22
+ personal and non-commercial use. Commercial products that implement
23
+ the patented methods independently (outside of this codebase) require
24
+ a separate commercial license from Antaris Analytics.
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.4
2
+ Name: antaris-memory
3
+ Version: 0.1.0
4
+ Summary: Human-like memory for AI agents. Patent pending.
5
+ Author-email: Antaris Analytics <moro@antarisanalytics.ai>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/Antaris1337/antaris-memory
8
+ Project-URL: Documentation, https://memory.antarisanalytics.ai
9
+ Project-URL: Repository, https://github.com/Antaris1337/antaris-memory
10
+ Keywords: ai,memory,agents,llm,persistence,recall
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Provides-Extra: embeddings
25
+ Requires-Dist: openai>=1.0; extra == "embeddings"
26
+ Provides-Extra: all
27
+ Requires-Dist: openai>=1.0; extra == "all"
28
+ Dynamic: license-file
29
+
30
+ # 🧠 Antaris Memory
31
+
32
+ **Human-like memory for AI agents. Patent pending.**
33
+
34
+ Give your AI agents persistent memory that decays, reinforces, feels, reasons about time, detects its own contradictions, and cleans up after itself. For under $5/year.
35
+
36
+ [![Patent Pending](https://img.shields.io/badge/Patent-Pending-blue)](https://antarisanalytics.ai)
37
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-green.svg)](https://python.org)
38
+ [![License](https://img.shields.io/badge/license-Apache%202.0-orange.svg)](LICENSE)
39
+
40
+ ## The Problem
41
+
42
+ Every AI agent forgets everything between sessions. GPT, Claude, Gemini — they all start from zero every time. Enterprise memory solutions cost $5,000-$50,000/year and provide basic retrieval at best.
43
+
44
+ ## The Solution
45
+
46
+ ```python
47
+ from antaris_memory import MemorySystem
48
+
49
+ # Initialize
50
+ mem = MemorySystem("./my-agent-workspace")
51
+
52
+ # Ingest conversations, notes, anything
53
+ mem.ingest_file("conversation.md", category="tactical")
54
+ mem.ingest_directory("./memory", pattern="*.md", category="tactical")
55
+
56
+ # Search with decay-weighted relevance
57
+ results = mem.search("what did we decide about pricing?")
58
+
59
+ # Ask about time
60
+ memories = mem.on_date("2026-02-14")
61
+ story = mem.narrative(topic="patent filing")
62
+
63
+ # Forget things (GDPR-ready)
64
+ mem.forget(entity="John Doe")
65
+ mem.forget(before_date="2025-01-01")
66
+
67
+ # Run dream-state consolidation
68
+ report = mem.consolidate()
69
+
70
+ # Save
71
+ mem.save()
72
+ ```
73
+
74
+ ## Features
75
+
76
+ | Feature | Description | Patent Claim |
77
+ |---------|-------------|-------------|
78
+ | **Memory Decay** | Ebbinghaus-inspired forgetting curves with reinforcement on access | Claim 16 |
79
+ | **Sentiment Tagging** | Auto-detect emotional context (positive, negative, urgent, strategic, financial) | Claim 17 |
80
+ | **Temporal Reasoning** | Query by date, date ranges, build chronological narratives | Claim 22 |
81
+ | **Confidence Scoring** | Track reliability, increase on corroboration | Claim 23 |
82
+ | **Contradiction Detection** | Flag when memories conflict with each other | Claim 23 |
83
+ | **Memory Compression** | Auto-summarize old files, preserve key points | Claim 20 |
84
+ | **Selective Forgetting** | GDPR-ready deletion by topic, entity, or date with audit trail | Claim 21 |
85
+ | **Dream State** | Background consolidation: find duplicates, cluster topics, generate insights | Claim 24 |
86
+
87
+ ## Install
88
+
89
+ ```bash
90
+ pip install antaris-memory
91
+ ```
92
+
93
+ Or from source:
94
+
95
+ ```bash
96
+ git clone https://github.com/Antaris1337/antaris-memory.git
97
+ cd antaris-memory
98
+ pip install -e .
99
+ ```
100
+
101
+ ## Quick Start
102
+
103
+ ```python
104
+ from antaris_memory import MemorySystem
105
+
106
+ # Create a memory system
107
+ mem = MemorySystem("./workspace", half_life=7.0)
108
+
109
+ # Load existing state (if any)
110
+ mem.load()
111
+
112
+ # Ingest some content
113
+ mem.ingest("Today we decided to use PostgreSQL for the database.",
114
+ source="meeting-notes", category="strategic")
115
+
116
+ mem.ingest("The API costs $500/month which is too expensive.",
117
+ source="review", category="financial")
118
+
119
+ # Search
120
+ results = mem.search("database decision")
121
+ for r in results:
122
+ print(f"[{r.confidence:.1f}] {r.content}")
123
+
124
+ # Check stats
125
+ print(mem.stats())
126
+
127
+ # Save state
128
+ mem.save()
129
+ ```
130
+
131
+ ## How It Works
132
+
133
+ ### Memory Decay (Ebbinghaus Curves)
134
+
135
+ Memories naturally fade over time, just like human memory:
136
+
137
+ ```
138
+ Score = Importance × 2^(-age / half_life) + reinforcement
139
+ ```
140
+
141
+ - **Fresh memories** score high
142
+ - **Old unused memories** fade toward zero
143
+ - **Accessed memories** get reinforced — the more you recall something, the stronger it stays
144
+ - Memories below the archive threshold are candidates for compression
145
+
146
+ ### Sentiment Analysis
147
+
148
+ Every memory is auto-tagged with emotional context:
149
+
150
+ ```python
151
+ entry.sentiment = {"positive": 0.8, "financial": 0.5}
152
+ ```
153
+
154
+ Search by emotion: `mem.search("budget", sentiment_filter="financial")`
155
+
156
+ ### Dream State Consolidation
157
+
158
+ Run periodically (cron job, background task) to:
159
+ - Find and merge near-duplicate memories
160
+ - Discover topic clusters
161
+ - Detect contradictions
162
+ - Suggest memories for archival
163
+
164
+ ```python
165
+ report = mem.consolidate()
166
+ # Returns: duplicates found, clusters, contradictions, archive suggestions
167
+ ```
168
+
169
+ ## Architecture
170
+
171
+ ```
172
+ ┌─────────────────────────────────────────────┐
173
+ │ MemorySystem │
174
+ │ │
175
+ │ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
176
+ │ │ Decay │ │ Sentiment │ │ Temporal │ │
177
+ │ │ Engine │ │ Tagger │ │ Engine │ │
178
+ │ └──────────┘ └───────────┘ └────────────┘ │
179
+ │ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
180
+ │ │Confidence│ │Compression│ │ Forgetting │ │
181
+ │ │ Engine │ │ Engine │ │ Engine │ │
182
+ │ └──────────┘ └───────────┘ └────────────┘ │
183
+ │ ┌──────────────────────────────────────┐ │
184
+ │ │ Consolidation Engine │ │
185
+ │ │ (Dream State Processing) │ │
186
+ │ └──────────────────────────────────────┘ │
187
+ │ │
188
+ │ Storage: JSON file (zero dependencies) │
189
+ └─────────────────────────────────────────────┘
190
+ ```
191
+
192
+ ## Configuration
193
+
194
+ ```python
195
+ mem = MemorySystem(
196
+ workspace="./workspace", # Where to store metadata
197
+ half_life=7.0, # Memory decay half-life in days
198
+ tag_terms=["custom", "terms"], # Additional auto-tag keywords
199
+ )
200
+ ```
201
+
202
+ ## Zero Dependencies
203
+
204
+ Antaris Memory uses only Python standard library. No numpy, no torch, no API keys required.
205
+
206
+ **Optional:** Install `openai` for embedding-based semantic search (coming in v0.2).
207
+
208
+ ## Comparison
209
+
210
+ | Feature | Antaris Memory | LangChain Memory | Mem0 | Zep |
211
+ |---------|---------------|-----------------|------|-----|
212
+ | Memory decay curves | ✅ | ❌ | ❌ | ❌ |
213
+ | Emotional tagging | ✅ | ❌ | ❌ | ❌ |
214
+ | Temporal reasoning | ✅ | ❌ | ❌ | ❌ |
215
+ | Contradiction detection | ✅ | ❌ | ❌ | ❌ |
216
+ | Selective forgetting | ✅ | ❌ | ❌ | ❌ |
217
+ | Dream state consolidation | ✅ | ❌ | ❌ | ❌ |
218
+ | Zero dependencies | ✅ | ❌ | ❌ | ❌ |
219
+ | Cost per year | <$5 | $500+ | $500+ | $1000+ |
220
+ | Patent protected | ✅ | ❌ | ❌ | ❌ |
221
+
222
+ ## License
223
+
224
+ Apache 2.0 — free for personal and commercial use.
225
+
226
+ The underlying technology is protected by US Patent Application #63/983,397 (pending). Commercial products that implement the patented methods require a commercial license from Antaris Analytics.
227
+
228
+ ## Built by
229
+
230
+ **Antaris Analytics** — AI memory intelligence
231
+ 📧 moro@antarisanalytics.ai
232
+ 🌐 [antarisanalytics.ai](https://antarisanalytics.ai)
233
+
234
+ ---
235
+
236
+ *"We gave AI agents human-like memory for $5/year."*
@@ -0,0 +1,207 @@
1
+ # 🧠 Antaris Memory
2
+
3
+ **Human-like memory for AI agents. Patent pending.**
4
+
5
+ Give your AI agents persistent memory that decays, reinforces, feels, reasons about time, detects its own contradictions, and cleans up after itself. For under $5/year.
6
+
7
+ [![Patent Pending](https://img.shields.io/badge/Patent-Pending-blue)](https://antarisanalytics.ai)
8
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-green.svg)](https://python.org)
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-orange.svg)](LICENSE)
10
+
11
+ ## The Problem
12
+
13
+ Every AI agent forgets everything between sessions. GPT, Claude, Gemini — they all start from zero every time. Enterprise memory solutions cost $5,000-$50,000/year and provide basic retrieval at best.
14
+
15
+ ## The Solution
16
+
17
+ ```python
18
+ from antaris_memory import MemorySystem
19
+
20
+ # Initialize
21
+ mem = MemorySystem("./my-agent-workspace")
22
+
23
+ # Ingest conversations, notes, anything
24
+ mem.ingest_file("conversation.md", category="tactical")
25
+ mem.ingest_directory("./memory", pattern="*.md", category="tactical")
26
+
27
+ # Search with decay-weighted relevance
28
+ results = mem.search("what did we decide about pricing?")
29
+
30
+ # Ask about time
31
+ memories = mem.on_date("2026-02-14")
32
+ story = mem.narrative(topic="patent filing")
33
+
34
+ # Forget things (GDPR-ready)
35
+ mem.forget(entity="John Doe")
36
+ mem.forget(before_date="2025-01-01")
37
+
38
+ # Run dream-state consolidation
39
+ report = mem.consolidate()
40
+
41
+ # Save
42
+ mem.save()
43
+ ```
44
+
45
+ ## Features
46
+
47
+ | Feature | Description | Patent Claim |
48
+ |---------|-------------|-------------|
49
+ | **Memory Decay** | Ebbinghaus-inspired forgetting curves with reinforcement on access | Claim 16 |
50
+ | **Sentiment Tagging** | Auto-detect emotional context (positive, negative, urgent, strategic, financial) | Claim 17 |
51
+ | **Temporal Reasoning** | Query by date, date ranges, build chronological narratives | Claim 22 |
52
+ | **Confidence Scoring** | Track reliability, increase on corroboration | Claim 23 |
53
+ | **Contradiction Detection** | Flag when memories conflict with each other | Claim 23 |
54
+ | **Memory Compression** | Auto-summarize old files, preserve key points | Claim 20 |
55
+ | **Selective Forgetting** | GDPR-ready deletion by topic, entity, or date with audit trail | Claim 21 |
56
+ | **Dream State** | Background consolidation: find duplicates, cluster topics, generate insights | Claim 24 |
57
+
58
+ ## Install
59
+
60
+ ```bash
61
+ pip install antaris-memory
62
+ ```
63
+
64
+ Or from source:
65
+
66
+ ```bash
67
+ git clone https://github.com/Antaris1337/antaris-memory.git
68
+ cd antaris-memory
69
+ pip install -e .
70
+ ```
71
+
72
+ ## Quick Start
73
+
74
+ ```python
75
+ from antaris_memory import MemorySystem
76
+
77
+ # Create a memory system
78
+ mem = MemorySystem("./workspace", half_life=7.0)
79
+
80
+ # Load existing state (if any)
81
+ mem.load()
82
+
83
+ # Ingest some content
84
+ mem.ingest("Today we decided to use PostgreSQL for the database.",
85
+ source="meeting-notes", category="strategic")
86
+
87
+ mem.ingest("The API costs $500/month which is too expensive.",
88
+ source="review", category="financial")
89
+
90
+ # Search
91
+ results = mem.search("database decision")
92
+ for r in results:
93
+ print(f"[{r.confidence:.1f}] {r.content}")
94
+
95
+ # Check stats
96
+ print(mem.stats())
97
+
98
+ # Save state
99
+ mem.save()
100
+ ```
101
+
102
+ ## How It Works
103
+
104
+ ### Memory Decay (Ebbinghaus Curves)
105
+
106
+ Memories naturally fade over time, just like human memory:
107
+
108
+ ```
109
+ Score = Importance × 2^(-age / half_life) + reinforcement
110
+ ```
111
+
112
+ - **Fresh memories** score high
113
+ - **Old unused memories** fade toward zero
114
+ - **Accessed memories** get reinforced — the more you recall something, the stronger it stays
115
+ - Memories below the archive threshold are candidates for compression
116
+
117
+ ### Sentiment Analysis
118
+
119
+ Every memory is auto-tagged with emotional context:
120
+
121
+ ```python
122
+ entry.sentiment = {"positive": 0.8, "financial": 0.5}
123
+ ```
124
+
125
+ Search by emotion: `mem.search("budget", sentiment_filter="financial")`
126
+
127
+ ### Dream State Consolidation
128
+
129
+ Run periodically (cron job, background task) to:
130
+ - Find and merge near-duplicate memories
131
+ - Discover topic clusters
132
+ - Detect contradictions
133
+ - Suggest memories for archival
134
+
135
+ ```python
136
+ report = mem.consolidate()
137
+ # Returns: duplicates found, clusters, contradictions, archive suggestions
138
+ ```
139
+
140
+ ## Architecture
141
+
142
+ ```
143
+ ┌─────────────────────────────────────────────┐
144
+ │ MemorySystem │
145
+ │ │
146
+ │ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
147
+ │ │ Decay │ │ Sentiment │ │ Temporal │ │
148
+ │ │ Engine │ │ Tagger │ │ Engine │ │
149
+ │ └──────────┘ └───────────┘ └────────────┘ │
150
+ │ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
151
+ │ │Confidence│ │Compression│ │ Forgetting │ │
152
+ │ │ Engine │ │ Engine │ │ Engine │ │
153
+ │ └──────────┘ └───────────┘ └────────────┘ │
154
+ │ ┌──────────────────────────────────────┐ │
155
+ │ │ Consolidation Engine │ │
156
+ │ │ (Dream State Processing) │ │
157
+ │ └──────────────────────────────────────┘ │
158
+ │ │
159
+ │ Storage: JSON file (zero dependencies) │
160
+ └─────────────────────────────────────────────┘
161
+ ```
162
+
163
+ ## Configuration
164
+
165
+ ```python
166
+ mem = MemorySystem(
167
+ workspace="./workspace", # Where to store metadata
168
+ half_life=7.0, # Memory decay half-life in days
169
+ tag_terms=["custom", "terms"], # Additional auto-tag keywords
170
+ )
171
+ ```
172
+
173
+ ## Zero Dependencies
174
+
175
+ Antaris Memory uses only Python standard library. No numpy, no torch, no API keys required.
176
+
177
+ **Optional:** Install `openai` for embedding-based semantic search (coming in v0.2).
178
+
179
+ ## Comparison
180
+
181
+ | Feature | Antaris Memory | LangChain Memory | Mem0 | Zep |
182
+ |---------|---------------|-----------------|------|-----|
183
+ | Memory decay curves | ✅ | ❌ | ❌ | ❌ |
184
+ | Emotional tagging | ✅ | ❌ | ❌ | ❌ |
185
+ | Temporal reasoning | ✅ | ❌ | ❌ | ❌ |
186
+ | Contradiction detection | ✅ | ❌ | ❌ | ❌ |
187
+ | Selective forgetting | ✅ | ❌ | ❌ | ❌ |
188
+ | Dream state consolidation | ✅ | ❌ | ❌ | ❌ |
189
+ | Zero dependencies | ✅ | ❌ | ❌ | ❌ |
190
+ | Cost per year | <$5 | $500+ | $500+ | $1000+ |
191
+ | Patent protected | ✅ | ❌ | ❌ | ❌ |
192
+
193
+ ## License
194
+
195
+ Apache 2.0 — free for personal and commercial use.
196
+
197
+ The underlying technology is protected by US Patent Application #63/983,397 (pending). Commercial products that implement the patented methods require a commercial license from Antaris Analytics.
198
+
199
+ ## Built by
200
+
201
+ **Antaris Analytics** — AI memory intelligence
202
+ 📧 moro@antarisanalytics.ai
203
+ 🌐 [antarisanalytics.ai](https://antarisanalytics.ai)
204
+
205
+ ---
206
+
207
+ *"We gave AI agents human-like memory for $5/year."*
@@ -0,0 +1,41 @@
1
+ """
2
+ Antaris Memory — Human-like memory for AI agents.
3
+ Patent Pending: US Application #63/983,397
4
+
5
+ Give your AI agents persistent memory that decays, reinforces,
6
+ feels, reasons about time, and cleans up after itself.
7
+ For under $5/year.
8
+
9
+ Usage:
10
+ from antaris_memory import MemorySystem
11
+
12
+ mem = MemorySystem("/path/to/workspace")
13
+ mem.ingest_file("conversation.md", category="tactical")
14
+ results = mem.search("what did we decide about pricing?")
15
+ mem.save()
16
+ """
17
+
18
+ __version__ = "0.1.0"
19
+ __patent__ = "US Application #63/983,397 (Patent Pending)"
20
+
21
+ from antaris_memory.core import MemorySystem
22
+ from antaris_memory.entry import MemoryEntry
23
+ from antaris_memory.decay import DecayEngine
24
+ from antaris_memory.sentiment import SentimentTagger
25
+ from antaris_memory.temporal import TemporalEngine
26
+ from antaris_memory.confidence import ConfidenceEngine
27
+ from antaris_memory.compression import CompressionEngine
28
+ from antaris_memory.forgetting import ForgettingEngine
29
+ from antaris_memory.consolidation import ConsolidationEngine
30
+
31
+ __all__ = [
32
+ "MemorySystem",
33
+ "MemoryEntry",
34
+ "DecayEngine",
35
+ "SentimentTagger",
36
+ "TemporalEngine",
37
+ "ConfidenceEngine",
38
+ "CompressionEngine",
39
+ "ForgettingEngine",
40
+ "ConsolidationEngine",
41
+ ]
@@ -0,0 +1,65 @@
1
+ """Claim 20: Memory compression & summarization."""
2
+
3
+ import re
4
+ from datetime import datetime, timedelta
5
+ from pathlib import Path
6
+ from typing import Dict, List
7
+
8
+
9
+ class CompressionEngine:
10
+ """Compress old memories into condensed summaries."""
11
+
12
+ @staticmethod
13
+ def compress_file(file_path: str) -> Dict:
14
+ """Read a memory file and produce a compressed summary."""
15
+ try:
16
+ content = Path(file_path).read_text()
17
+ except (FileNotFoundError, UnicodeDecodeError):
18
+ return {"error": f"Cannot read: {file_path}"}
19
+
20
+ lines = content.strip().split("\n")
21
+ headers = [l for l in lines if l.startswith("#")]
22
+ bullets = [l.strip() for l in lines if l.strip().startswith("- ")]
23
+ markers = ["✅", "🎯", "💰", "🚀", "Decision:", "Key:", "Result:"]
24
+ key_lines = [
25
+ l.strip() for l in lines
26
+ if any(m in l for m in markers)
27
+ ]
28
+
29
+ seen = set()
30
+ unique = []
31
+ for b in bullets + key_lines:
32
+ norm = b.lower().strip("- ").strip()
33
+ if norm not in seen and len(norm) > 10:
34
+ seen.add(norm)
35
+ unique.append(b)
36
+
37
+ return {
38
+ "source": file_path,
39
+ "original_lines": len(lines),
40
+ "compressed_lines": len(headers) + len(unique),
41
+ "compression_ratio": round(
42
+ 1 - (len(headers) + len(unique)) / max(len(lines), 1), 2
43
+ ),
44
+ "headers": headers,
45
+ "key_points": unique[:30],
46
+ "compressed_at": datetime.now().isoformat(),
47
+ }
48
+
49
+ @staticmethod
50
+ def compress_old_files(memory_dir: str, days_old: int = 7) -> List[Dict]:
51
+ """Compress daily memory files older than *days_old*."""
52
+ path = Path(memory_dir)
53
+ if not path.exists():
54
+ return []
55
+
56
+ cutoff = datetime.now() - timedelta(days=days_old)
57
+ results = []
58
+ for f in sorted(path.glob("*.md")):
59
+ match = re.search(r"(\d{4}-\d{2}-\d{2})", f.name)
60
+ if not match:
61
+ continue
62
+ file_date = datetime.strptime(match.group(1), "%Y-%m-%d")
63
+ if file_date < cutoff:
64
+ results.append(CompressionEngine.compress_file(str(f)))
65
+ return results
@@ -0,0 +1,45 @@
1
+ """Claim 23: Confidence scoring & contradiction detection."""
2
+
3
+ from typing import List, Tuple
4
+ from .entry import MemoryEntry
5
+
6
+ NEGATION_PAIRS = [
7
+ ("working", "broken"), ("stable", "crashed"), ("complete", "incomplete"),
8
+ ("fixed", "broken"), ("success", "failed"), ("approved", "rejected"),
9
+ ("cheap", "expensive"), ("fast", "slow"), ("available", "unavailable"),
10
+ ("secure", "vulnerable"), ("online", "offline"), ("enabled", "disabled"),
11
+ ]
12
+
13
+
14
+ class ConfidenceEngine:
15
+ """Track memory reliability and detect contradictions."""
16
+
17
+ @staticmethod
18
+ def corroborate(entry: MemoryEntry, boost: float = 0.1) -> None:
19
+ """Increase confidence when info is confirmed by another source."""
20
+ entry.confidence = min(entry.confidence + boost, 1.0)
21
+
22
+ @staticmethod
23
+ def find_contradictions(
24
+ memories: List[MemoryEntry],
25
+ ) -> List[Tuple[MemoryEntry, MemoryEntry, str]]:
26
+ """Detect potential contradictions via opposing keyword pairs on shared topics."""
27
+ contradictions = []
28
+ for i, m1 in enumerate(memories):
29
+ m1_lower = m1.content.lower()
30
+ for m2 in memories[i + 1:]:
31
+ if m1.source == m2.source and abs(m1.line - m2.line) < 5:
32
+ continue
33
+ m2_lower = m2.content.lower()
34
+ for pos, neg in NEGATION_PAIRS:
35
+ if (pos in m1_lower and neg in m2_lower) or \
36
+ (neg in m1_lower and pos in m2_lower):
37
+ shared = set(m1.tags) & set(m2.tags)
38
+ if shared:
39
+ reason = (
40
+ f"Conflicting states ({pos}/{neg}) "
41
+ f"on topic: {', '.join(shared)}"
42
+ )
43
+ contradictions.append((m1, m2, reason))
44
+ break
45
+ return contradictions