alma-memory 0.4.0__py3-none-any.whl → 0.5.1__py3-none-any.whl
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.
- alma/__init__.py +121 -45
- alma/confidence/__init__.py +1 -1
- alma/confidence/engine.py +92 -58
- alma/confidence/types.py +34 -14
- alma/config/loader.py +3 -2
- alma/consolidation/__init__.py +23 -0
- alma/consolidation/engine.py +678 -0
- alma/consolidation/prompts.py +84 -0
- alma/core.py +136 -28
- alma/domains/__init__.py +6 -6
- alma/domains/factory.py +12 -9
- alma/domains/schemas.py +17 -3
- alma/domains/types.py +8 -4
- alma/events/__init__.py +75 -0
- alma/events/emitter.py +284 -0
- alma/events/storage_mixin.py +246 -0
- alma/events/types.py +126 -0
- alma/events/webhook.py +425 -0
- alma/exceptions.py +49 -0
- alma/extraction/__init__.py +31 -0
- alma/extraction/auto_learner.py +265 -0
- alma/extraction/extractor.py +420 -0
- alma/graph/__init__.py +106 -0
- alma/graph/backends/__init__.py +32 -0
- alma/graph/backends/kuzu.py +624 -0
- alma/graph/backends/memgraph.py +432 -0
- alma/graph/backends/memory.py +236 -0
- alma/graph/backends/neo4j.py +417 -0
- alma/graph/base.py +159 -0
- alma/graph/extraction.py +198 -0
- alma/graph/store.py +860 -0
- alma/harness/__init__.py +4 -4
- alma/harness/base.py +18 -9
- alma/harness/domains.py +27 -11
- alma/initializer/__init__.py +1 -1
- alma/initializer/initializer.py +51 -43
- alma/initializer/types.py +25 -17
- alma/integration/__init__.py +9 -9
- alma/integration/claude_agents.py +32 -20
- alma/integration/helena.py +32 -22
- alma/integration/victor.py +57 -33
- alma/learning/__init__.py +27 -27
- alma/learning/forgetting.py +198 -148
- alma/learning/heuristic_extractor.py +40 -24
- alma/learning/protocols.py +65 -17
- alma/learning/validation.py +7 -2
- alma/mcp/__init__.py +4 -4
- alma/mcp/__main__.py +2 -1
- alma/mcp/resources.py +17 -16
- alma/mcp/server.py +102 -44
- alma/mcp/tools.py +180 -45
- alma/observability/__init__.py +84 -0
- alma/observability/config.py +302 -0
- alma/observability/logging.py +424 -0
- alma/observability/metrics.py +583 -0
- alma/observability/tracing.py +440 -0
- alma/progress/__init__.py +3 -3
- alma/progress/tracker.py +26 -20
- alma/progress/types.py +8 -12
- alma/py.typed +0 -0
- alma/retrieval/__init__.py +11 -11
- alma/retrieval/cache.py +20 -21
- alma/retrieval/embeddings.py +4 -4
- alma/retrieval/engine.py +179 -39
- alma/retrieval/scoring.py +73 -63
- alma/session/__init__.py +2 -2
- alma/session/manager.py +5 -5
- alma/session/types.py +5 -4
- alma/storage/__init__.py +70 -0
- alma/storage/azure_cosmos.py +414 -133
- alma/storage/base.py +215 -4
- alma/storage/chroma.py +1443 -0
- alma/storage/constants.py +103 -0
- alma/storage/file_based.py +59 -28
- alma/storage/migrations/__init__.py +21 -0
- alma/storage/migrations/base.py +321 -0
- alma/storage/migrations/runner.py +323 -0
- alma/storage/migrations/version_stores.py +337 -0
- alma/storage/migrations/versions/__init__.py +11 -0
- alma/storage/migrations/versions/v1_0_0.py +373 -0
- alma/storage/pinecone.py +1080 -0
- alma/storage/postgresql.py +1559 -0
- alma/storage/qdrant.py +1306 -0
- alma/storage/sqlite_local.py +504 -60
- alma/testing/__init__.py +46 -0
- alma/testing/factories.py +301 -0
- alma/testing/mocks.py +389 -0
- alma/types.py +62 -14
- alma_memory-0.5.1.dist-info/METADATA +939 -0
- alma_memory-0.5.1.dist-info/RECORD +93 -0
- {alma_memory-0.4.0.dist-info → alma_memory-0.5.1.dist-info}/WHEEL +1 -1
- alma_memory-0.4.0.dist-info/METADATA +0 -488
- alma_memory-0.4.0.dist-info/RECORD +0 -52
- {alma_memory-0.4.0.dist-info → alma_memory-0.5.1.dist-info}/top_level.txt +0 -0
alma/__init__.py
CHANGED
|
@@ -12,84 +12,135 @@ The Harness Pattern:
|
|
|
12
12
|
|
|
13
13
|
This makes any tool-using agent appear to "learn" by injecting relevant
|
|
14
14
|
memory slices before each run and updating memory after.
|
|
15
|
+
|
|
16
|
+
Testing Support:
|
|
17
|
+
For testing ALMA integrations, use the `alma.testing` module:
|
|
18
|
+
|
|
19
|
+
from alma.testing import MockStorage, create_test_heuristic
|
|
20
|
+
|
|
21
|
+
def test_my_integration():
|
|
22
|
+
storage = MockStorage()
|
|
23
|
+
heuristic = create_test_heuristic(agent="test-agent")
|
|
24
|
+
storage.save_heuristic(heuristic)
|
|
25
|
+
|
|
26
|
+
Available utilities:
|
|
27
|
+
- MockStorage: In-memory storage backend
|
|
28
|
+
- MockEmbedder: Deterministic fake embeddings
|
|
29
|
+
- create_test_heuristic(), create_test_outcome(), etc.
|
|
15
30
|
"""
|
|
16
31
|
|
|
17
|
-
__version__ = "0.
|
|
32
|
+
__version__ = "0.5.1"
|
|
18
33
|
|
|
19
34
|
# Core
|
|
35
|
+
# Confidence Engine (Phase 12)
|
|
36
|
+
from alma.confidence import (
|
|
37
|
+
ConfidenceEngine,
|
|
38
|
+
ConfidenceSignal,
|
|
39
|
+
OpportunitySignal,
|
|
40
|
+
RiskSignal,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Consolidation Engine (Phase 13)
|
|
44
|
+
from alma.consolidation import (
|
|
45
|
+
ConsolidationEngine,
|
|
46
|
+
ConsolidationResult,
|
|
47
|
+
)
|
|
20
48
|
from alma.core import ALMA
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
49
|
+
|
|
50
|
+
# Domain Memory Factory (Phase 10)
|
|
51
|
+
from alma.domains import (
|
|
52
|
+
DomainMemoryFactory,
|
|
53
|
+
DomainSchema,
|
|
54
|
+
EntityType,
|
|
55
|
+
RelationshipType,
|
|
56
|
+
get_coding_schema,
|
|
57
|
+
get_general_schema,
|
|
58
|
+
get_research_schema,
|
|
59
|
+
get_sales_schema,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Event System (Phase 19)
|
|
63
|
+
from alma.events import (
|
|
64
|
+
EventEmitter,
|
|
65
|
+
MemoryEvent,
|
|
66
|
+
MemoryEventType,
|
|
67
|
+
WebhookConfig,
|
|
68
|
+
WebhookManager,
|
|
69
|
+
get_emitter,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Exceptions
|
|
73
|
+
from alma.exceptions import (
|
|
74
|
+
ALMAError,
|
|
75
|
+
ConfigurationError,
|
|
76
|
+
EmbeddingError,
|
|
77
|
+
ExtractionError,
|
|
78
|
+
RetrievalError,
|
|
79
|
+
ScopeViolationError,
|
|
80
|
+
StorageError,
|
|
29
81
|
)
|
|
30
82
|
|
|
31
83
|
# Harness Pattern
|
|
32
84
|
from alma.harness.base import (
|
|
33
|
-
Setting,
|
|
34
|
-
Context,
|
|
35
85
|
Agent,
|
|
36
|
-
|
|
86
|
+
Context,
|
|
37
87
|
Harness,
|
|
88
|
+
MemorySchema,
|
|
89
|
+
RunResult,
|
|
90
|
+
Setting,
|
|
38
91
|
Tool,
|
|
39
92
|
ToolType,
|
|
40
|
-
RunResult,
|
|
41
93
|
)
|
|
42
94
|
from alma.harness.domains import (
|
|
43
95
|
CodingDomain,
|
|
44
|
-
ResearchDomain,
|
|
45
96
|
ContentDomain,
|
|
46
97
|
OperationsDomain,
|
|
98
|
+
ResearchDomain,
|
|
47
99
|
create_harness,
|
|
48
100
|
)
|
|
49
101
|
|
|
102
|
+
# Session Initializer (Phase 11)
|
|
103
|
+
from alma.initializer import (
|
|
104
|
+
CodebaseOrientation,
|
|
105
|
+
InitializationResult,
|
|
106
|
+
RulesOfEngagement,
|
|
107
|
+
SessionInitializer,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Observability (Phase 20)
|
|
111
|
+
from alma.observability import (
|
|
112
|
+
ALMAMetrics,
|
|
113
|
+
configure_observability,
|
|
114
|
+
get_logger,
|
|
115
|
+
get_metrics,
|
|
116
|
+
get_tracer,
|
|
117
|
+
trace_method,
|
|
118
|
+
)
|
|
119
|
+
|
|
50
120
|
# Progress Tracking (Phase 10)
|
|
51
121
|
from alma.progress import (
|
|
52
|
-
WorkItem,
|
|
53
|
-
WorkItemStatus,
|
|
54
122
|
ProgressLog,
|
|
55
123
|
ProgressSummary,
|
|
56
124
|
ProgressTracker,
|
|
125
|
+
WorkItem,
|
|
126
|
+
WorkItemStatus,
|
|
57
127
|
)
|
|
58
128
|
|
|
59
129
|
# Session Management (Phase 10)
|
|
60
130
|
from alma.session import (
|
|
61
|
-
SessionHandoff,
|
|
62
131
|
SessionContext,
|
|
63
|
-
|
|
132
|
+
SessionHandoff,
|
|
64
133
|
SessionManager,
|
|
134
|
+
SessionOutcome,
|
|
65
135
|
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
get_research_schema,
|
|
75
|
-
get_sales_schema,
|
|
76
|
-
get_general_schema,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
# Session Initializer (Phase 11)
|
|
80
|
-
from alma.initializer import (
|
|
81
|
-
CodebaseOrientation,
|
|
82
|
-
InitializationResult,
|
|
83
|
-
RulesOfEngagement,
|
|
84
|
-
SessionInitializer,
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
# Confidence Engine (Phase 12)
|
|
88
|
-
from alma.confidence import (
|
|
89
|
-
ConfidenceEngine,
|
|
90
|
-
ConfidenceSignal,
|
|
91
|
-
OpportunitySignal,
|
|
92
|
-
RiskSignal,
|
|
136
|
+
from alma.types import (
|
|
137
|
+
AntiPattern,
|
|
138
|
+
DomainKnowledge,
|
|
139
|
+
Heuristic,
|
|
140
|
+
MemoryScope,
|
|
141
|
+
MemorySlice,
|
|
142
|
+
Outcome,
|
|
143
|
+
UserPreference,
|
|
93
144
|
)
|
|
94
145
|
|
|
95
146
|
__all__ = [
|
|
@@ -147,4 +198,29 @@ __all__ = [
|
|
|
147
198
|
"ConfidenceSignal",
|
|
148
199
|
"OpportunitySignal",
|
|
149
200
|
"RiskSignal",
|
|
201
|
+
# Consolidation Engine
|
|
202
|
+
"ConsolidationEngine",
|
|
203
|
+
"ConsolidationResult",
|
|
204
|
+
# Event System
|
|
205
|
+
"MemoryEvent",
|
|
206
|
+
"MemoryEventType",
|
|
207
|
+
"EventEmitter",
|
|
208
|
+
"get_emitter",
|
|
209
|
+
"WebhookConfig",
|
|
210
|
+
"WebhookManager",
|
|
211
|
+
# Exceptions
|
|
212
|
+
"ALMAError",
|
|
213
|
+
"ConfigurationError",
|
|
214
|
+
"ScopeViolationError",
|
|
215
|
+
"StorageError",
|
|
216
|
+
"EmbeddingError",
|
|
217
|
+
"RetrievalError",
|
|
218
|
+
"ExtractionError",
|
|
219
|
+
# Observability
|
|
220
|
+
"configure_observability",
|
|
221
|
+
"get_tracer",
|
|
222
|
+
"get_logger",
|
|
223
|
+
"get_metrics",
|
|
224
|
+
"ALMAMetrics",
|
|
225
|
+
"trace_method",
|
|
150
226
|
]
|
alma/confidence/__init__.py
CHANGED
|
@@ -30,13 +30,13 @@ Usage:
|
|
|
30
30
|
)
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
+
from alma.confidence.engine import ConfidenceEngine
|
|
33
34
|
from alma.confidence.types import (
|
|
34
35
|
ConfidenceSignal,
|
|
35
36
|
OpportunitySignal,
|
|
36
37
|
Recommendation,
|
|
37
38
|
RiskSignal,
|
|
38
39
|
)
|
|
39
|
-
from alma.confidence.engine import ConfidenceEngine
|
|
40
40
|
|
|
41
41
|
__all__ = [
|
|
42
42
|
"ConfidenceSignal",
|
alma/confidence/engine.py
CHANGED
|
@@ -95,11 +95,13 @@ class ConfidenceEngine:
|
|
|
95
95
|
|
|
96
96
|
# 1. Load historical data from heuristic
|
|
97
97
|
if heuristic:
|
|
98
|
-
signal.occurrence_count = getattr(heuristic,
|
|
99
|
-
success_count = getattr(heuristic,
|
|
98
|
+
signal.occurrence_count = getattr(heuristic, "occurrence_count", 0)
|
|
99
|
+
success_count = getattr(heuristic, "success_count", 0)
|
|
100
100
|
if signal.occurrence_count > 0:
|
|
101
101
|
signal.historical_success_rate = success_count / signal.occurrence_count
|
|
102
|
-
signal.metadata["heuristic_confidence"] = getattr(
|
|
102
|
+
signal.metadata["heuristic_confidence"] = getattr(
|
|
103
|
+
heuristic, "confidence", 0.5
|
|
104
|
+
)
|
|
103
105
|
|
|
104
106
|
# 2. Analyze context similarity
|
|
105
107
|
signal.context_similarity = self._compute_context_similarity(
|
|
@@ -214,30 +216,43 @@ class ConfidenceEngine:
|
|
|
214
216
|
top_k=10,
|
|
215
217
|
)
|
|
216
218
|
|
|
217
|
-
if memories and hasattr(memories,
|
|
219
|
+
if memories and hasattr(memories, "anti_patterns"):
|
|
218
220
|
for ap in memories.anti_patterns[:3]:
|
|
219
221
|
# Check if this anti-pattern relates to our strategy
|
|
220
222
|
if self._is_similar(strategy, ap.strategy):
|
|
221
|
-
risks.append(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
223
|
+
risks.append(
|
|
224
|
+
RiskSignal(
|
|
225
|
+
signal_type="similar_to_failure",
|
|
226
|
+
description=f"Similar to known anti-pattern: {ap.reason[:100]}",
|
|
227
|
+
severity=0.7,
|
|
228
|
+
source=f"anti_pattern:{ap.id}",
|
|
229
|
+
related_memories=[ap.id],
|
|
230
|
+
)
|
|
231
|
+
)
|
|
228
232
|
except Exception as e:
|
|
229
233
|
logger.warning(f"Failed to check anti-patterns: {e}")
|
|
230
234
|
|
|
231
235
|
# Check for complexity indicators
|
|
232
|
-
complexity_keywords = [
|
|
233
|
-
|
|
236
|
+
complexity_keywords = [
|
|
237
|
+
"complex",
|
|
238
|
+
"multiple",
|
|
239
|
+
"all",
|
|
240
|
+
"every",
|
|
241
|
+
"entire",
|
|
242
|
+
"complete",
|
|
243
|
+
]
|
|
244
|
+
complexity_score = sum(
|
|
245
|
+
1 for kw in complexity_keywords if kw in strategy.lower()
|
|
246
|
+
)
|
|
234
247
|
if complexity_score >= 2:
|
|
235
|
-
risks.append(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
risks.append(
|
|
249
|
+
RiskSignal(
|
|
250
|
+
signal_type="high_complexity",
|
|
251
|
+
description="Strategy appears complex - consider breaking into smaller steps",
|
|
252
|
+
severity=0.4,
|
|
253
|
+
source="context_analysis",
|
|
254
|
+
)
|
|
255
|
+
)
|
|
241
256
|
|
|
242
257
|
# Check for risky patterns
|
|
243
258
|
risky_patterns = [
|
|
@@ -248,12 +263,14 @@ class ConfidenceEngine:
|
|
|
248
263
|
]
|
|
249
264
|
for pattern, description, severity in risky_patterns:
|
|
250
265
|
if pattern in strategy.lower():
|
|
251
|
-
risks.append(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
266
|
+
risks.append(
|
|
267
|
+
RiskSignal(
|
|
268
|
+
signal_type="risky_pattern",
|
|
269
|
+
description=description,
|
|
270
|
+
severity=severity,
|
|
271
|
+
source="pattern_match",
|
|
272
|
+
)
|
|
273
|
+
)
|
|
257
274
|
|
|
258
275
|
return risks
|
|
259
276
|
|
|
@@ -291,34 +308,43 @@ class ConfidenceEngine:
|
|
|
291
308
|
top_k=10,
|
|
292
309
|
)
|
|
293
310
|
|
|
294
|
-
if memories and hasattr(memories,
|
|
311
|
+
if memories and hasattr(memories, "heuristics"):
|
|
295
312
|
for h in memories.heuristics[:3]:
|
|
296
313
|
# Check success rate
|
|
297
314
|
if h.occurrence_count >= self.min_occurrences_for_confidence:
|
|
298
|
-
success_rate =
|
|
315
|
+
success_rate = (
|
|
316
|
+
h.success_count / h.occurrence_count
|
|
317
|
+
if h.occurrence_count > 0
|
|
318
|
+
else 0
|
|
319
|
+
)
|
|
299
320
|
if success_rate >= 0.8:
|
|
300
|
-
opportunities.append(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
321
|
+
opportunities.append(
|
|
322
|
+
OpportunitySignal(
|
|
323
|
+
signal_type="proven_pattern",
|
|
324
|
+
description=f"Proven strategy with {success_rate:.0%} success rate over {h.occurrence_count} uses",
|
|
325
|
+
strength=min(0.9, success_rate),
|
|
326
|
+
source=f"heuristic:{h.id}",
|
|
327
|
+
related_memories=[h.id],
|
|
328
|
+
)
|
|
329
|
+
)
|
|
307
330
|
|
|
308
331
|
# Check for recent successes in outcomes
|
|
309
|
-
if hasattr(memories,
|
|
332
|
+
if hasattr(memories, "outcomes"):
|
|
310
333
|
recent_successes = [
|
|
311
|
-
o
|
|
312
|
-
|
|
334
|
+
o
|
|
335
|
+
for o in memories.outcomes
|
|
336
|
+
if getattr(o, "outcome", "") == "success"
|
|
313
337
|
][:3]
|
|
314
338
|
if recent_successes:
|
|
315
|
-
opportunities.append(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
339
|
+
opportunities.append(
|
|
340
|
+
OpportunitySignal(
|
|
341
|
+
signal_type="recent_success",
|
|
342
|
+
description=f"Similar approach succeeded recently ({len(recent_successes)} recent successes)",
|
|
343
|
+
strength=0.6,
|
|
344
|
+
source="outcome_analysis",
|
|
345
|
+
related_memories=[o.id for o in recent_successes],
|
|
346
|
+
)
|
|
347
|
+
)
|
|
322
348
|
|
|
323
349
|
except Exception as e:
|
|
324
350
|
logger.warning(f"Failed to check opportunities: {e}")
|
|
@@ -332,12 +358,14 @@ class ConfidenceEngine:
|
|
|
332
358
|
]
|
|
333
359
|
for pattern, description, strength in best_practices:
|
|
334
360
|
if pattern in strategy.lower():
|
|
335
|
-
opportunities.append(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
361
|
+
opportunities.append(
|
|
362
|
+
OpportunitySignal(
|
|
363
|
+
signal_type="best_practice",
|
|
364
|
+
description=description,
|
|
365
|
+
strength=strength,
|
|
366
|
+
source="pattern_match",
|
|
367
|
+
)
|
|
368
|
+
)
|
|
341
369
|
|
|
342
370
|
return opportunities
|
|
343
371
|
|
|
@@ -363,19 +391,21 @@ class ConfidenceEngine:
|
|
|
363
391
|
return 0.3 # Low similarity for novel contexts
|
|
364
392
|
|
|
365
393
|
# Check if any outcomes match our strategy
|
|
366
|
-
if hasattr(memories,
|
|
394
|
+
if hasattr(memories, "outcomes"):
|
|
367
395
|
matching_outcomes = [
|
|
368
|
-
o
|
|
369
|
-
|
|
396
|
+
o
|
|
397
|
+
for o in memories.outcomes
|
|
398
|
+
if self._is_similar(strategy, getattr(o, "strategy_used", ""))
|
|
370
399
|
]
|
|
371
400
|
if matching_outcomes:
|
|
372
401
|
return 0.8 # High similarity
|
|
373
402
|
|
|
374
403
|
# Check heuristics
|
|
375
|
-
if hasattr(memories,
|
|
404
|
+
if hasattr(memories, "heuristics"):
|
|
376
405
|
matching_heuristics = [
|
|
377
|
-
h
|
|
378
|
-
|
|
406
|
+
h
|
|
407
|
+
for h in memories.heuristics
|
|
408
|
+
if self._is_similar(strategy, getattr(h, "strategy", ""))
|
|
379
409
|
]
|
|
380
410
|
if matching_heuristics:
|
|
381
411
|
return 0.7
|
|
@@ -489,7 +519,9 @@ class ConfidenceEngine:
|
|
|
489
519
|
|
|
490
520
|
# Context similarity
|
|
491
521
|
if signal.context_similarity >= 0.7:
|
|
492
|
-
parts.append(
|
|
522
|
+
parts.append(
|
|
523
|
+
"Current context is highly similar to past successful applications."
|
|
524
|
+
)
|
|
493
525
|
elif signal.context_similarity <= 0.3:
|
|
494
526
|
parts.append("Current context is quite different from past applications.")
|
|
495
527
|
|
|
@@ -501,6 +533,8 @@ class ConfidenceEngine:
|
|
|
501
533
|
# Key opportunities
|
|
502
534
|
strong_opps = [o for o in signal.opportunity_signals if o.strength >= 0.6]
|
|
503
535
|
if strong_opps:
|
|
504
|
-
parts.append(
|
|
536
|
+
parts.append(
|
|
537
|
+
f"POSITIVE: {len(strong_opps)} strong opportunity signal(s) detected."
|
|
538
|
+
)
|
|
505
539
|
|
|
506
540
|
return " ".join(parts)
|
alma/confidence/types.py
CHANGED
|
@@ -5,10 +5,10 @@ Forward-looking confidence signals for strategies.
|
|
|
5
5
|
Inspired by Ilya Sutskever's insight: emotions are forward-looking value functions.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import uuid
|
|
8
9
|
from dataclasses import dataclass, field
|
|
9
10
|
from datetime import datetime, timezone
|
|
10
11
|
from typing import Any, Dict, List, Literal, Optional
|
|
11
|
-
import uuid
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@dataclass
|
|
@@ -27,7 +27,9 @@ class RiskSignal:
|
|
|
27
27
|
id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
28
28
|
|
|
29
29
|
# Type of risk
|
|
30
|
-
signal_type: str =
|
|
30
|
+
signal_type: str = (
|
|
31
|
+
"" # "similar_to_failure", "untested_context", "high_complexity", etc.
|
|
32
|
+
)
|
|
31
33
|
|
|
32
34
|
# Human-readable description
|
|
33
35
|
description: str = ""
|
|
@@ -139,7 +141,9 @@ class ConfidenceSignal:
|
|
|
139
141
|
|
|
140
142
|
# Forward-looking predictions (computed for current context)
|
|
141
143
|
predicted_success: float = 0.5 # Expected success in THIS context
|
|
142
|
-
uncertainty: float =
|
|
144
|
+
uncertainty: float = (
|
|
145
|
+
0.5 # How uncertain is the prediction (0=certain, 1=very uncertain)
|
|
146
|
+
)
|
|
143
147
|
context_similarity: float = 0.0 # How similar is current context to past successes
|
|
144
148
|
|
|
145
149
|
# Risk signals
|
|
@@ -225,26 +229,28 @@ class ConfidenceSignal:
|
|
|
225
229
|
# Aggregate opportunity
|
|
226
230
|
if self.opportunity_signals:
|
|
227
231
|
# Use max opportunity as the dominant signal
|
|
228
|
-
self.total_opportunity_score = max(
|
|
232
|
+
self.total_opportunity_score = max(
|
|
233
|
+
o.strength for o in self.opportunity_signals
|
|
234
|
+
)
|
|
229
235
|
else:
|
|
230
236
|
self.total_opportunity_score = 0.0
|
|
231
237
|
|
|
232
238
|
# Combined confidence score
|
|
233
239
|
# Weighs historical success, predicted success, and risk/opportunity balance
|
|
234
240
|
base_confidence = (
|
|
235
|
-
0.3 * self.historical_success_rate
|
|
236
|
-
0.4 * self.predicted_success
|
|
237
|
-
0.15 * self.context_similarity
|
|
238
|
-
0.15 * (1.0 - self.uncertainty)
|
|
241
|
+
0.3 * self.historical_success_rate
|
|
242
|
+
+ 0.4 * self.predicted_success
|
|
243
|
+
+ 0.15 * self.context_similarity
|
|
244
|
+
+ 0.15 * (1.0 - self.uncertainty)
|
|
239
245
|
)
|
|
240
246
|
|
|
241
247
|
# Adjust for risk/opportunity
|
|
242
248
|
risk_adjustment = -0.2 * self.total_risk_score
|
|
243
249
|
opportunity_adjustment = 0.2 * self.total_opportunity_score
|
|
244
250
|
|
|
245
|
-
self.confidence_score = max(
|
|
246
|
-
base_confidence + risk_adjustment + opportunity_adjustment
|
|
247
|
-
)
|
|
251
|
+
self.confidence_score = max(
|
|
252
|
+
0.0, min(1.0, base_confidence + risk_adjustment + opportunity_adjustment)
|
|
253
|
+
)
|
|
248
254
|
|
|
249
255
|
# Determine recommendation
|
|
250
256
|
self._update_recommendation()
|
|
@@ -277,7 +283,9 @@ class ConfidenceSignal:
|
|
|
277
283
|
|
|
278
284
|
# Metrics
|
|
279
285
|
lines.append("### Metrics")
|
|
280
|
-
lines.append(
|
|
286
|
+
lines.append(
|
|
287
|
+
f"- Historical success: {self.historical_success_rate:.0%} ({self.occurrence_count} uses)"
|
|
288
|
+
)
|
|
281
289
|
lines.append(f"- Predicted success: {self.predicted_success:.0%}")
|
|
282
290
|
lines.append(f"- Context similarity: {self.context_similarity:.0%}")
|
|
283
291
|
lines.append(f"- Uncertainty: {self.uncertainty:.0%}")
|
|
@@ -287,7 +295,13 @@ class ConfidenceSignal:
|
|
|
287
295
|
if self.risk_signals:
|
|
288
296
|
lines.append("### Risks")
|
|
289
297
|
for risk in self.risk_signals:
|
|
290
|
-
severity_label =
|
|
298
|
+
severity_label = (
|
|
299
|
+
"HIGH"
|
|
300
|
+
if risk.severity >= 0.7
|
|
301
|
+
else "MEDIUM"
|
|
302
|
+
if risk.severity >= 0.4
|
|
303
|
+
else "LOW"
|
|
304
|
+
)
|
|
291
305
|
lines.append(f"- [{severity_label}] {risk.description}")
|
|
292
306
|
lines.append("")
|
|
293
307
|
|
|
@@ -295,7 +309,13 @@ class ConfidenceSignal:
|
|
|
295
309
|
if self.opportunity_signals:
|
|
296
310
|
lines.append("### Opportunities")
|
|
297
311
|
for opp in self.opportunity_signals:
|
|
298
|
-
strength_label =
|
|
312
|
+
strength_label = (
|
|
313
|
+
"STRONG"
|
|
314
|
+
if opp.strength >= 0.7
|
|
315
|
+
else "MODERATE"
|
|
316
|
+
if opp.strength >= 0.4
|
|
317
|
+
else "WEAK"
|
|
318
|
+
)
|
|
299
319
|
lines.append(f"- [{strength_label}] {opp.description}")
|
|
300
320
|
lines.append("")
|
|
301
321
|
|
alma/config/loader.py
CHANGED
|
@@ -5,10 +5,10 @@ Handles loading configuration from files and environment variables,
|
|
|
5
5
|
with support for Azure Key Vault secret resolution.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import os
|
|
9
8
|
import logging
|
|
9
|
+
import os
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import
|
|
11
|
+
from typing import Any, Dict
|
|
12
12
|
|
|
13
13
|
import yaml
|
|
14
14
|
|
|
@@ -78,6 +78,7 @@ class ConfigLoader:
|
|
|
78
78
|
|
|
79
79
|
# Handle ${VAR} patterns
|
|
80
80
|
import re
|
|
81
|
+
|
|
81
82
|
pattern = r"\$\{([^}]+)\}"
|
|
82
83
|
|
|
83
84
|
def replace(match):
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ALMA Consolidation Module.
|
|
3
|
+
|
|
4
|
+
Provides memory consolidation capabilities for deduplicating and merging
|
|
5
|
+
similar memories, inspired by Mem0's core innovation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from alma.consolidation.engine import ConsolidationEngine, ConsolidationResult
|
|
9
|
+
from alma.consolidation.prompts import (
|
|
10
|
+
MERGE_ANTI_PATTERNS_PROMPT,
|
|
11
|
+
MERGE_DOMAIN_KNOWLEDGE_PROMPT,
|
|
12
|
+
MERGE_HEURISTICS_PROMPT,
|
|
13
|
+
MERGE_OUTCOMES_PROMPT,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"ConsolidationEngine",
|
|
18
|
+
"ConsolidationResult",
|
|
19
|
+
"MERGE_HEURISTICS_PROMPT",
|
|
20
|
+
"MERGE_DOMAIN_KNOWLEDGE_PROMPT",
|
|
21
|
+
"MERGE_ANTI_PATTERNS_PROMPT",
|
|
22
|
+
"MERGE_OUTCOMES_PROMPT",
|
|
23
|
+
]
|