intentmind 0.2.0__tar.gz → 0.2.1__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.
- {intentmind-0.2.0/src/intentmind.egg-info → intentmind-0.2.1}/PKG-INFO +22 -14
- {intentmind-0.2.0 → intentmind-0.2.1}/README.md +21 -13
- {intentmind-0.2.0 → intentmind-0.2.1}/pyproject.toml +1 -1
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/builders/prompt_builder.py +1 -1
- intentmind-0.2.1/src/intentmind/engines/__init__.py +5 -0
- intentmind-0.2.1/src/intentmind/engines/cognitive_state_engine.py +36 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/engines/recall_engine.py +11 -11
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/models.py +2 -2
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/runtime.py +9 -9
- {intentmind-0.2.0 → intentmind-0.2.1/src/intentmind.egg-info}/PKG-INFO +22 -14
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind.egg-info/SOURCES.txt +1 -1
- intentmind-0.2.0/src/intentmind/engines/__init__.py +0 -5
- intentmind-0.2.0/src/intentmind/engines/emotion_engine.py +0 -36
- {intentmind-0.2.0 → intentmind-0.2.1}/LICENSE +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/setup.cfg +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/benchmark/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/benchmark/runner.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/benchmark/utils.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/builders/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/embeddings/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/embeddings/base.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/embeddings/fake.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/embeddings/sentence_transformer.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/engines/energy_engine.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/engines/intent_engine.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/indices/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/indices/base.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/indices/exact.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/indices/faiss.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/integrations/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/integrations/langchain.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/persistence/__init__.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/persistence/json_persistence.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/store.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind/vis.py +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind.egg-info/dependency_links.txt +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind.egg-info/requires.txt +0 -0
- {intentmind-0.2.0 → intentmind-0.2.1}/src/intentmind.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intentmind
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Language-agnostic associative memory runtime for persistent AI systems
|
|
5
5
|
Author: Intentmind Contributors
|
|
6
6
|
License: Intentmind Fair-Code License (Non-Commercial)
|
|
@@ -76,7 +76,7 @@ If you are building an autonomous system or an AI agent that lives for more than
|
|
|
76
76
|
|
|
77
77
|
## 🌟 The Solution: Why Intentmind?
|
|
78
78
|
|
|
79
|
-
Intentmind doesn't just store documents; it builds a **
|
|
79
|
+
Intentmind doesn't just store documents; it builds a **dynamic associative memory graph with energy-based activation, decay, reinforcement, and traceable recall paths**.
|
|
80
80
|
|
|
81
81
|
### 1. Associative Recall (Semantic Drift Recovery)
|
|
82
82
|
When data is ingested, Intentmind extracts core concepts (nodes) and connects them (edges). When a user mentions a concept, the system doesn't just do a vector search—it **traverses the graph**.
|
|
@@ -107,15 +107,17 @@ GraphRAG is fantastic for static document analysis, but it fails for **persisten
|
|
|
107
107
|
|
|
108
108
|
## 📊 Performance Benchmarks
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
*Synthetic Semantic Drift Benchmark*
|
|
111
|
+
- **Dataset:** 1,000 memory facts
|
|
112
|
+
- **Noise:** 30%
|
|
113
|
+
- **Query type:** delayed indirect recall
|
|
111
114
|
|
|
112
|
-
|
|
|
113
|
-
| :--- | :--- |
|
|
114
|
-
|
|
|
115
|
-
| **
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
| **Contradiction Resolution** | Low | Low | **High** (Energy-based priority) |
|
|
115
|
+
| System | Accuracy |
|
|
116
|
+
| :--- | :--- |
|
|
117
|
+
| Vanilla vector search | 42% |
|
|
118
|
+
| **Intentmind** | **68%** |
|
|
119
|
+
|
|
120
|
+
*Note: These are local regression benchmarks, not independent research claims. Intentmind is built to be resilient to long-session degradation where other systems degrade.*
|
|
119
121
|
|
|
120
122
|
---
|
|
121
123
|
|
|
@@ -141,14 +143,20 @@ pip install "intentmind[all]"
|
|
|
141
143
|
|
|
142
144
|
### 1-Minute Integration
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
While the core graph logic is language-agnostic, extraction quality is **embedding-model dependent**. We recommend using multilingual models for non-English data.
|
|
145
147
|
|
|
146
148
|
```python
|
|
147
149
|
from intentmind import IntentmindMemory
|
|
148
150
|
from intentmind.embeddings import SentenceTransformerEmbedder
|
|
149
151
|
|
|
150
|
-
#
|
|
151
|
-
mem = IntentmindMemory(
|
|
152
|
+
# Option A: Local deterministic demo (fastest, no LLM needed)
|
|
153
|
+
mem = IntentmindMemory(is_test=True, core_extractor="deterministic")
|
|
154
|
+
|
|
155
|
+
# Option B: Production embeddings with deterministic extraction
|
|
156
|
+
# mem = IntentmindMemory(embedder=SentenceTransformerEmbedder(), core_extractor="deterministic")
|
|
157
|
+
|
|
158
|
+
# Option C: Production with full LLM-assisted extraction (requires OPENAI_API_KEY)
|
|
159
|
+
# mem = IntentmindMemory(embedder=SentenceTransformerEmbedder(), core_extractor="llm")
|
|
152
160
|
|
|
153
161
|
# 2. Teach it concepts (Happens naturally during conversation)
|
|
154
162
|
mem.add("I need car insurance but I have no money.")
|
|
@@ -186,7 +194,7 @@ mem = IntentmindMemory.load("my_agent_brain.json")
|
|
|
186
194
|
|
|
187
195
|
## 📊 Visualizing the "Brain"
|
|
188
196
|
|
|
189
|
-
Intentmind isn't a black box. You can export the entire Cognitive Graph to an interactive HTML map to
|
|
197
|
+
Intentmind isn't a black box. You can export the entire Cognitive Graph to an interactive HTML map to visualize the graph structure, energy levels, and synaptic connections.
|
|
190
198
|
|
|
191
199
|
```python
|
|
192
200
|
mem.visualize("memory_map.html")
|
|
@@ -20,7 +20,7 @@ If you are building an autonomous system or an AI agent that lives for more than
|
|
|
20
20
|
|
|
21
21
|
## 🌟 The Solution: Why Intentmind?
|
|
22
22
|
|
|
23
|
-
Intentmind doesn't just store documents; it builds a **
|
|
23
|
+
Intentmind doesn't just store documents; it builds a **dynamic associative memory graph with energy-based activation, decay, reinforcement, and traceable recall paths**.
|
|
24
24
|
|
|
25
25
|
### 1. Associative Recall (Semantic Drift Recovery)
|
|
26
26
|
When data is ingested, Intentmind extracts core concepts (nodes) and connects them (edges). When a user mentions a concept, the system doesn't just do a vector search—it **traverses the graph**.
|
|
@@ -51,15 +51,17 @@ GraphRAG is fantastic for static document analysis, but it fails for **persisten
|
|
|
51
51
|
|
|
52
52
|
## 📊 Performance Benchmarks
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
*Synthetic Semantic Drift Benchmark*
|
|
55
|
+
- **Dataset:** 1,000 memory facts
|
|
56
|
+
- **Noise:** 30%
|
|
57
|
+
- **Query type:** delayed indirect recall
|
|
55
58
|
|
|
56
|
-
|
|
|
57
|
-
| :--- | :--- |
|
|
58
|
-
|
|
|
59
|
-
| **
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
| **Contradiction Resolution** | Low | Low | **High** (Energy-based priority) |
|
|
59
|
+
| System | Accuracy |
|
|
60
|
+
| :--- | :--- |
|
|
61
|
+
| Vanilla vector search | 42% |
|
|
62
|
+
| **Intentmind** | **68%** |
|
|
63
|
+
|
|
64
|
+
*Note: These are local regression benchmarks, not independent research claims. Intentmind is built to be resilient to long-session degradation where other systems degrade.*
|
|
63
65
|
|
|
64
66
|
---
|
|
65
67
|
|
|
@@ -85,14 +87,20 @@ pip install "intentmind[all]"
|
|
|
85
87
|
|
|
86
88
|
### 1-Minute Integration
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
While the core graph logic is language-agnostic, extraction quality is **embedding-model dependent**. We recommend using multilingual models for non-English data.
|
|
89
91
|
|
|
90
92
|
```python
|
|
91
93
|
from intentmind import IntentmindMemory
|
|
92
94
|
from intentmind.embeddings import SentenceTransformerEmbedder
|
|
93
95
|
|
|
94
|
-
#
|
|
95
|
-
mem = IntentmindMemory(
|
|
96
|
+
# Option A: Local deterministic demo (fastest, no LLM needed)
|
|
97
|
+
mem = IntentmindMemory(is_test=True, core_extractor="deterministic")
|
|
98
|
+
|
|
99
|
+
# Option B: Production embeddings with deterministic extraction
|
|
100
|
+
# mem = IntentmindMemory(embedder=SentenceTransformerEmbedder(), core_extractor="deterministic")
|
|
101
|
+
|
|
102
|
+
# Option C: Production with full LLM-assisted extraction (requires OPENAI_API_KEY)
|
|
103
|
+
# mem = IntentmindMemory(embedder=SentenceTransformerEmbedder(), core_extractor="llm")
|
|
96
104
|
|
|
97
105
|
# 2. Teach it concepts (Happens naturally during conversation)
|
|
98
106
|
mem.add("I need car insurance but I have no money.")
|
|
@@ -130,7 +138,7 @@ mem = IntentmindMemory.load("my_agent_brain.json")
|
|
|
130
138
|
|
|
131
139
|
## 📊 Visualizing the "Brain"
|
|
132
140
|
|
|
133
|
-
Intentmind isn't a black box. You can export the entire Cognitive Graph to an interactive HTML map to
|
|
141
|
+
Intentmind isn't a black box. You can export the entire Cognitive Graph to an interactive HTML map to visualize the graph structure, energy levels, and synaptic connections.
|
|
134
142
|
|
|
135
143
|
```python
|
|
136
144
|
mem.visualize("memory_map.html")
|
|
@@ -50,7 +50,7 @@ class PromptBuilder:
|
|
|
50
50
|
# PUBLIC API #
|
|
51
51
|
# ================================================================== #
|
|
52
52
|
|
|
53
|
-
def build(self, user_query, recall_result,
|
|
53
|
+
def build(self, user_query, recall_result, cognitive_state):
|
|
54
54
|
role = self._build_role()
|
|
55
55
|
graph = self._build_graph_state(recall_result)
|
|
56
56
|
memories = self._build_memories(recall_result)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ..models import CognitiveState
|
|
4
|
+
from ..embeddings import BaseEmbedder, cosine_similarity
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CognitiveStateEngine:
|
|
8
|
+
def __init__(self, embedder: BaseEmbedder):
|
|
9
|
+
self.embedder = embedder
|
|
10
|
+
self.prototypes = {
|
|
11
|
+
"neutral": embedder.embed("I am providing or requesting information."),
|
|
12
|
+
"curious": embedder.embed("I am curious and want to explore this idea."),
|
|
13
|
+
"urgent": embedder.embed("This is critical, urgent, and needs immediate attention."),
|
|
14
|
+
"confident": embedder.embed("This makes sense and is solid."),
|
|
15
|
+
"skeptical": embedder.embed("I am unsure and this needs verification."),
|
|
16
|
+
"cautious": embedder.embed("This is risky and requires careful attention."),
|
|
17
|
+
}
|
|
18
|
+
self.override_priority = ["urgent", "cautious", "skeptical", "curious", "confident", "neutral"]
|
|
19
|
+
self.override_threshold = 0.80
|
|
20
|
+
|
|
21
|
+
def detect(self, message_embedding) -> CognitiveState:
|
|
22
|
+
scores = {emotion: cosine_similarity(message_embedding, proto) for emotion, proto in self.prototypes.items()}
|
|
23
|
+
ranked = sorted(scores.items(), key=lambda x: x[1], reverse=True)
|
|
24
|
+
top_emotion, top_score = ranked[0]
|
|
25
|
+
second_score = ranked[1][1]
|
|
26
|
+
delta = top_score - second_score
|
|
27
|
+
for priority_emotion in self.override_priority[:2]:
|
|
28
|
+
if scores[priority_emotion] > self.override_threshold:
|
|
29
|
+
top_emotion = priority_emotion
|
|
30
|
+
top_score = scores[priority_emotion]
|
|
31
|
+
break
|
|
32
|
+
if top_score < 0.55 or delta < 0.07:
|
|
33
|
+
state = "neutral"
|
|
34
|
+
else:
|
|
35
|
+
state = top_emotion
|
|
36
|
+
return CognitiveState(current=state, confidence=round(top_score, 3), weak_echo=state in ["curious", "urgent"])
|
|
@@ -11,7 +11,7 @@ class RecallEngine:
|
|
|
11
11
|
self.store = store
|
|
12
12
|
self.intent_match_threshold = intent_match_threshold
|
|
13
13
|
|
|
14
|
-
def activation_score(self, query_embedding, intent,
|
|
14
|
+
def activation_score(self, query_embedding, intent, cognitive_state):
|
|
15
15
|
query_similarity = cosine_similarity(query_embedding, intent.embedding)
|
|
16
16
|
edges = self.store.get_neighbors(intent.intent_id)
|
|
17
17
|
edge_energy = sum(e.energy for _, e in edges) / len(edges) if edges else 0.40
|
|
@@ -28,11 +28,11 @@ class RecallEngine:
|
|
|
28
28
|
- intent.noise_score * 0.20
|
|
29
29
|
)
|
|
30
30
|
multipliers = {
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
"neutral": 1.00, "curious": 1.00,
|
|
32
|
+
"confident": 1.15, "skeptical": 1.10, "urgent": 1.25, "cautious": 1.20,
|
|
33
33
|
}
|
|
34
|
-
m = multipliers.get(
|
|
35
|
-
factor = 1.0 + ((m - 1.0) *
|
|
34
|
+
m = multipliers.get(cognitive_state.current, 1.00)
|
|
35
|
+
factor = 1.0 + ((m - 1.0) * cognitive_state.confidence)
|
|
36
36
|
return round(base * factor, 4)
|
|
37
37
|
|
|
38
38
|
def chunk_score(self, query_embedding, chunk, intent, path_strength):
|
|
@@ -58,7 +58,7 @@ class RecallEngine:
|
|
|
58
58
|
def build_layers(
|
|
59
59
|
self,
|
|
60
60
|
query_embedding,
|
|
61
|
-
|
|
61
|
+
cognitive_state,
|
|
62
62
|
query_intent_labels=None,
|
|
63
63
|
query_token_embeddings=None,
|
|
64
64
|
field_seed_ids=None,
|
|
@@ -78,7 +78,7 @@ class RecallEngine:
|
|
|
78
78
|
for intent in self.store.intents.values():
|
|
79
79
|
if intent.state == "archived":
|
|
80
80
|
continue
|
|
81
|
-
score = self.activation_score(query_embedding, intent,
|
|
81
|
+
score = self.activation_score(query_embedding, intent, cognitive_state)
|
|
82
82
|
|
|
83
83
|
# Query intent matching is resolved once up front. This avoids
|
|
84
84
|
# scanning every query-token embedding against every graph node.
|
|
@@ -175,7 +175,7 @@ class RecallEngine:
|
|
|
175
175
|
})
|
|
176
176
|
layers[1] = self._dedupe_layer(layers[1])[:12]
|
|
177
177
|
|
|
178
|
-
if
|
|
178
|
+
if cognitive_state.weak_echo:
|
|
179
179
|
seen_l1 = {item["intent"].intent_id for item in layers[1]}
|
|
180
180
|
seen_all = seen_l0 | seen_l1
|
|
181
181
|
|
|
@@ -248,7 +248,7 @@ class RecallEngine:
|
|
|
248
248
|
self,
|
|
249
249
|
query,
|
|
250
250
|
query_embedding,
|
|
251
|
-
|
|
251
|
+
cognitive_state,
|
|
252
252
|
query_intent_labels=None,
|
|
253
253
|
query_token_embeddings=None,
|
|
254
254
|
energy_engine=None,
|
|
@@ -259,7 +259,7 @@ class RecallEngine:
|
|
|
259
259
|
query_match_intent_ids = self._matching_intent_ids(query_intent_labels, query_token_embeddings)
|
|
260
260
|
layers = self.build_layers(
|
|
261
261
|
query_embedding,
|
|
262
|
-
|
|
262
|
+
cognitive_state,
|
|
263
263
|
query_intent_labels,
|
|
264
264
|
query_token_embeddings,
|
|
265
265
|
query_match_intent_ids=query_match_intent_ids,
|
|
@@ -379,7 +379,7 @@ class RecallEngine:
|
|
|
379
379
|
candidates = sorted(self.remove_duplicates(candidates), key=lambda x: x["score"], reverse=True)
|
|
380
380
|
direct = self._select_direct(candidates)
|
|
381
381
|
associated = self._select_associated(candidates, direct, query_intent_set)
|
|
382
|
-
weak_echo = [c for c in candidates if c["layer"] == 3][:2] if
|
|
382
|
+
weak_echo = [c for c in candidates if c["layer"] == 3][:2] if cognitive_state.weak_echo else []
|
|
383
383
|
|
|
384
384
|
return {
|
|
385
385
|
"direct_memories": direct,
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from .store import MemoryStore
|
|
5
5
|
from .embeddings import BaseEmbedder, FakeEmbedder
|
|
6
|
-
from .engines import IntentEngine,
|
|
6
|
+
from .engines import IntentEngine, CognitiveStateEngine, RecallEngine, EnergyEngine
|
|
7
7
|
from .builders import PromptBuilder
|
|
8
8
|
from .persistence import JsonPersistence
|
|
9
9
|
|
|
@@ -61,7 +61,7 @@ class IntentmindMemory:
|
|
|
61
61
|
model=model,
|
|
62
62
|
extractor=extractor,
|
|
63
63
|
)
|
|
64
|
-
self.
|
|
64
|
+
self._cognitive_state = CognitiveStateEngine(self.embedder)
|
|
65
65
|
self._recall = RecallEngine(self._store)
|
|
66
66
|
self._energy = EnergyEngine(self._store)
|
|
67
67
|
self._prompt = PromptBuilder()
|
|
@@ -77,8 +77,8 @@ class IntentmindMemory:
|
|
|
77
77
|
query_emb = self.embedder.embed(user_query)
|
|
78
78
|
t_embed = _time.perf_counter()
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
cognitive_state = self._cognitive_state.detect(query_emb)
|
|
81
|
+
t_state = _time.perf_counter()
|
|
82
82
|
|
|
83
83
|
query_token_embeddings = self._intent_engine.extract_query_intents(user_query)
|
|
84
84
|
t_extract = _time.perf_counter()
|
|
@@ -88,14 +88,14 @@ class IntentmindMemory:
|
|
|
88
88
|
recall_result = self._recall.recall(
|
|
89
89
|
query=user_query,
|
|
90
90
|
query_embedding=query_emb,
|
|
91
|
-
|
|
91
|
+
cognitive_state=cognitive_state,
|
|
92
92
|
query_intent_labels=query_intent_labels,
|
|
93
93
|
query_token_embeddings=query_token_embeddings,
|
|
94
94
|
energy_engine=self._energy,
|
|
95
95
|
)
|
|
96
96
|
t_recall = _time.perf_counter()
|
|
97
97
|
|
|
98
|
-
prompt = self._prompt.build(user_query=user_query, recall_result=recall_result,
|
|
98
|
+
prompt = self._prompt.build(user_query=user_query, recall_result=recall_result, cognitive_state=cognitive_state)
|
|
99
99
|
t_prompt = _time.perf_counter()
|
|
100
100
|
|
|
101
101
|
self.metadata["total_queries"] = self.metadata.get("total_queries", 0) + 1
|
|
@@ -103,8 +103,8 @@ class IntentmindMemory:
|
|
|
103
103
|
total_ms = (t_prompt - t0) * 1000
|
|
104
104
|
latency_breakdown = {
|
|
105
105
|
"embed_query_ms": round((t_embed - t0) * 1000, 2),
|
|
106
|
-
"
|
|
107
|
-
"extractor_ms": round((t_extract -
|
|
106
|
+
"cognitive_state_ms": round((t_state - t_embed) * 1000, 2),
|
|
107
|
+
"extractor_ms": round((t_extract - t_state) * 1000, 2),
|
|
108
108
|
"recall_ms": round((t_recall - t_extract) * 1000, 2),
|
|
109
109
|
"prompt_ms": round((t_prompt - t_recall) * 1000, 2),
|
|
110
110
|
"total_ms": round(total_ms, 2),
|
|
@@ -112,7 +112,7 @@ class IntentmindMemory:
|
|
|
112
112
|
|
|
113
113
|
return {
|
|
114
114
|
"prompt": prompt,
|
|
115
|
-
"
|
|
115
|
+
"cognitive_state": cognitive_state.to_dict(),
|
|
116
116
|
"memories": {
|
|
117
117
|
"direct": len(recall_result["direct_memories"]),
|
|
118
118
|
"associated": len(recall_result["associated_memories"]),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intentmind
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Language-agnostic associative memory runtime for persistent AI systems
|
|
5
5
|
Author: Intentmind Contributors
|
|
6
6
|
License: Intentmind Fair-Code License (Non-Commercial)
|
|
@@ -76,7 +76,7 @@ If you are building an autonomous system or an AI agent that lives for more than
|
|
|
76
76
|
|
|
77
77
|
## 🌟 The Solution: Why Intentmind?
|
|
78
78
|
|
|
79
|
-
Intentmind doesn't just store documents; it builds a **
|
|
79
|
+
Intentmind doesn't just store documents; it builds a **dynamic associative memory graph with energy-based activation, decay, reinforcement, and traceable recall paths**.
|
|
80
80
|
|
|
81
81
|
### 1. Associative Recall (Semantic Drift Recovery)
|
|
82
82
|
When data is ingested, Intentmind extracts core concepts (nodes) and connects them (edges). When a user mentions a concept, the system doesn't just do a vector search—it **traverses the graph**.
|
|
@@ -107,15 +107,17 @@ GraphRAG is fantastic for static document analysis, but it fails for **persisten
|
|
|
107
107
|
|
|
108
108
|
## 📊 Performance Benchmarks
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
*Synthetic Semantic Drift Benchmark*
|
|
111
|
+
- **Dataset:** 1,000 memory facts
|
|
112
|
+
- **Noise:** 30%
|
|
113
|
+
- **Query type:** delayed indirect recall
|
|
111
114
|
|
|
112
|
-
|
|
|
113
|
-
| :--- | :--- |
|
|
114
|
-
|
|
|
115
|
-
| **
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
| **Contradiction Resolution** | Low | Low | **High** (Energy-based priority) |
|
|
115
|
+
| System | Accuracy |
|
|
116
|
+
| :--- | :--- |
|
|
117
|
+
| Vanilla vector search | 42% |
|
|
118
|
+
| **Intentmind** | **68%** |
|
|
119
|
+
|
|
120
|
+
*Note: These are local regression benchmarks, not independent research claims. Intentmind is built to be resilient to long-session degradation where other systems degrade.*
|
|
119
121
|
|
|
120
122
|
---
|
|
121
123
|
|
|
@@ -141,14 +143,20 @@ pip install "intentmind[all]"
|
|
|
141
143
|
|
|
142
144
|
### 1-Minute Integration
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
While the core graph logic is language-agnostic, extraction quality is **embedding-model dependent**. We recommend using multilingual models for non-English data.
|
|
145
147
|
|
|
146
148
|
```python
|
|
147
149
|
from intentmind import IntentmindMemory
|
|
148
150
|
from intentmind.embeddings import SentenceTransformerEmbedder
|
|
149
151
|
|
|
150
|
-
#
|
|
151
|
-
mem = IntentmindMemory(
|
|
152
|
+
# Option A: Local deterministic demo (fastest, no LLM needed)
|
|
153
|
+
mem = IntentmindMemory(is_test=True, core_extractor="deterministic")
|
|
154
|
+
|
|
155
|
+
# Option B: Production embeddings with deterministic extraction
|
|
156
|
+
# mem = IntentmindMemory(embedder=SentenceTransformerEmbedder(), core_extractor="deterministic")
|
|
157
|
+
|
|
158
|
+
# Option C: Production with full LLM-assisted extraction (requires OPENAI_API_KEY)
|
|
159
|
+
# mem = IntentmindMemory(embedder=SentenceTransformerEmbedder(), core_extractor="llm")
|
|
152
160
|
|
|
153
161
|
# 2. Teach it concepts (Happens naturally during conversation)
|
|
154
162
|
mem.add("I need car insurance but I have no money.")
|
|
@@ -186,7 +194,7 @@ mem = IntentmindMemory.load("my_agent_brain.json")
|
|
|
186
194
|
|
|
187
195
|
## 📊 Visualizing the "Brain"
|
|
188
196
|
|
|
189
|
-
Intentmind isn't a black box. You can export the entire Cognitive Graph to an interactive HTML map to
|
|
197
|
+
Intentmind isn't a black box. You can export the entire Cognitive Graph to an interactive HTML map to visualize the graph structure, energy levels, and synaptic connections.
|
|
190
198
|
|
|
191
199
|
```python
|
|
192
200
|
mem.visualize("memory_map.html")
|
|
@@ -21,7 +21,7 @@ src/intentmind/embeddings/base.py
|
|
|
21
21
|
src/intentmind/embeddings/fake.py
|
|
22
22
|
src/intentmind/embeddings/sentence_transformer.py
|
|
23
23
|
src/intentmind/engines/__init__.py
|
|
24
|
-
src/intentmind/engines/
|
|
24
|
+
src/intentmind/engines/cognitive_state_engine.py
|
|
25
25
|
src/intentmind/engines/energy_engine.py
|
|
26
26
|
src/intentmind/engines/intent_engine.py
|
|
27
27
|
src/intentmind/engines/recall_engine.py
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from ..models import EmotionalState
|
|
4
|
-
from ..embeddings import BaseEmbedder, cosine_similarity
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class EmotionEngine:
|
|
8
|
-
def __init__(self, embedder: BaseEmbedder):
|
|
9
|
-
self.embedder = embedder
|
|
10
|
-
self.prototypes = {
|
|
11
|
-
"nötr": embedder.embed("bilgi istiyorum"),
|
|
12
|
-
"merak": embedder.embed("bunu merak ediyorum keşfetmek istiyorum"),
|
|
13
|
-
"heyecan": embedder.embed("bu fikir beni heyecanlandırıyor"),
|
|
14
|
-
"güven": embedder.embed("bu mantıklı sağlam görünüyor"),
|
|
15
|
-
"şüphe": embedder.embed("emin değilim doğrulanması gerekiyor"),
|
|
16
|
-
"korku": embedder.embed("riskli olabilir dikkatli olmak lazım"),
|
|
17
|
-
}
|
|
18
|
-
self.override_priority = ["korku", "şüphe", "heyecan", "merak", "güven", "nötr"]
|
|
19
|
-
self.override_threshold = 0.80
|
|
20
|
-
|
|
21
|
-
def detect(self, message_embedding) -> EmotionalState:
|
|
22
|
-
scores = {emotion: cosine_similarity(message_embedding, proto) for emotion, proto in self.prototypes.items()}
|
|
23
|
-
ranked = sorted(scores.items(), key=lambda x: x[1], reverse=True)
|
|
24
|
-
top_emotion, top_score = ranked[0]
|
|
25
|
-
second_score = ranked[1][1]
|
|
26
|
-
delta = top_score - second_score
|
|
27
|
-
for priority_emotion in self.override_priority[:2]:
|
|
28
|
-
if scores[priority_emotion] > self.override_threshold:
|
|
29
|
-
top_emotion = priority_emotion
|
|
30
|
-
top_score = scores[priority_emotion]
|
|
31
|
-
break
|
|
32
|
-
if top_score < 0.55 or delta < 0.07:
|
|
33
|
-
emotion = "nötr"
|
|
34
|
-
else:
|
|
35
|
-
emotion = top_emotion
|
|
36
|
-
return EmotionalState(current=emotion, confidence=round(top_score, 3), weak_echo=emotion in ["merak", "heyecan"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|