alma-memory 0.5.1__py3-none-any.whl → 0.7.0__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 +296 -226
- alma/compression/__init__.py +33 -0
- alma/compression/pipeline.py +980 -0
- alma/confidence/__init__.py +47 -47
- alma/confidence/engine.py +540 -540
- alma/confidence/types.py +351 -351
- alma/config/loader.py +157 -157
- alma/consolidation/__init__.py +23 -23
- alma/consolidation/engine.py +678 -678
- alma/consolidation/prompts.py +84 -84
- alma/core.py +1189 -430
- alma/domains/__init__.py +30 -30
- alma/domains/factory.py +359 -359
- alma/domains/schemas.py +448 -448
- alma/domains/types.py +272 -272
- alma/events/__init__.py +75 -75
- alma/events/emitter.py +285 -284
- alma/events/storage_mixin.py +246 -246
- alma/events/types.py +126 -126
- alma/events/webhook.py +425 -425
- alma/exceptions.py +49 -49
- alma/extraction/__init__.py +31 -31
- alma/extraction/auto_learner.py +265 -265
- alma/extraction/extractor.py +420 -420
- alma/graph/__init__.py +106 -106
- alma/graph/backends/__init__.py +32 -32
- alma/graph/backends/kuzu.py +624 -624
- alma/graph/backends/memgraph.py +432 -432
- alma/graph/backends/memory.py +236 -236
- alma/graph/backends/neo4j.py +417 -417
- alma/graph/base.py +159 -159
- alma/graph/extraction.py +198 -198
- alma/graph/store.py +860 -860
- alma/harness/__init__.py +35 -35
- alma/harness/base.py +386 -386
- alma/harness/domains.py +705 -705
- alma/initializer/__init__.py +37 -37
- alma/initializer/initializer.py +418 -418
- alma/initializer/types.py +250 -250
- alma/integration/__init__.py +62 -62
- alma/integration/claude_agents.py +444 -444
- alma/integration/helena.py +423 -423
- alma/integration/victor.py +471 -471
- alma/learning/__init__.py +101 -86
- alma/learning/decay.py +878 -0
- alma/learning/forgetting.py +1446 -1446
- alma/learning/heuristic_extractor.py +390 -390
- alma/learning/protocols.py +374 -374
- alma/learning/validation.py +346 -346
- alma/mcp/__init__.py +123 -45
- alma/mcp/__main__.py +156 -156
- alma/mcp/resources.py +122 -122
- alma/mcp/server.py +955 -591
- alma/mcp/tools.py +3254 -509
- alma/observability/__init__.py +91 -84
- alma/observability/config.py +302 -302
- alma/observability/guidelines.py +170 -0
- alma/observability/logging.py +424 -424
- alma/observability/metrics.py +583 -583
- alma/observability/tracing.py +440 -440
- alma/progress/__init__.py +21 -21
- alma/progress/tracker.py +607 -607
- alma/progress/types.py +250 -250
- alma/retrieval/__init__.py +134 -53
- alma/retrieval/budget.py +525 -0
- alma/retrieval/cache.py +1304 -1061
- alma/retrieval/embeddings.py +202 -202
- alma/retrieval/engine.py +850 -427
- alma/retrieval/modes.py +365 -0
- alma/retrieval/progressive.py +560 -0
- alma/retrieval/scoring.py +344 -344
- alma/retrieval/trust_scoring.py +637 -0
- alma/retrieval/verification.py +797 -0
- alma/session/__init__.py +19 -19
- alma/session/manager.py +442 -399
- alma/session/types.py +288 -288
- alma/storage/__init__.py +101 -90
- alma/storage/archive.py +233 -0
- alma/storage/azure_cosmos.py +1259 -1259
- alma/storage/base.py +1083 -583
- alma/storage/chroma.py +1443 -1443
- alma/storage/constants.py +103 -103
- alma/storage/file_based.py +614 -614
- alma/storage/migrations/__init__.py +21 -21
- alma/storage/migrations/base.py +321 -321
- alma/storage/migrations/runner.py +323 -323
- alma/storage/migrations/version_stores.py +337 -337
- alma/storage/migrations/versions/__init__.py +11 -11
- alma/storage/migrations/versions/v1_0_0.py +373 -373
- alma/storage/migrations/versions/v1_1_0_workflow_context.py +551 -0
- alma/storage/pinecone.py +1080 -1080
- alma/storage/postgresql.py +1948 -1559
- alma/storage/qdrant.py +1306 -1306
- alma/storage/sqlite_local.py +3041 -1457
- alma/testing/__init__.py +46 -46
- alma/testing/factories.py +301 -301
- alma/testing/mocks.py +389 -389
- alma/types.py +292 -264
- alma/utils/__init__.py +19 -0
- alma/utils/tokenizer.py +521 -0
- alma/workflow/__init__.py +83 -0
- alma/workflow/artifacts.py +170 -0
- alma/workflow/checkpoint.py +311 -0
- alma/workflow/context.py +228 -0
- alma/workflow/outcomes.py +189 -0
- alma/workflow/reducers.py +393 -0
- {alma_memory-0.5.1.dist-info → alma_memory-0.7.0.dist-info}/METADATA +210 -72
- alma_memory-0.7.0.dist-info/RECORD +112 -0
- alma_memory-0.5.1.dist-info/RECORD +0 -93
- {alma_memory-0.5.1.dist-info → alma_memory-0.7.0.dist-info}/WHEEL +0 -0
- {alma_memory-0.5.1.dist-info → alma_memory-0.7.0.dist-info}/top_level.txt +0 -0
alma/config/loader.py
CHANGED
|
@@ -1,157 +1,157 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ALMA Configuration Loader.
|
|
3
|
-
|
|
4
|
-
Handles loading configuration from files and environment variables,
|
|
5
|
-
with support for Azure Key Vault secret resolution.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import logging
|
|
9
|
-
import os
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from typing import Any, Dict
|
|
12
|
-
|
|
13
|
-
import yaml
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class ConfigLoader:
|
|
19
|
-
"""
|
|
20
|
-
Loads ALMA configuration from YAML files with environment variable expansion.
|
|
21
|
-
|
|
22
|
-
Supports:
|
|
23
|
-
- ${ENV_VAR} syntax for environment variables
|
|
24
|
-
- ${KEYVAULT:secret-name} syntax for Azure Key Vault (when configured)
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
_keyvault_client = None
|
|
28
|
-
|
|
29
|
-
@classmethod
|
|
30
|
-
def load(cls, config_path: str) -> Dict[str, Any]:
|
|
31
|
-
"""
|
|
32
|
-
Load configuration from YAML file.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
config_path: Path to config.yaml
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
Parsed and expanded configuration dict
|
|
39
|
-
"""
|
|
40
|
-
path = Path(config_path)
|
|
41
|
-
if not path.exists():
|
|
42
|
-
logger.warning(f"Config not found at {config_path}, using defaults")
|
|
43
|
-
return cls._get_defaults()
|
|
44
|
-
|
|
45
|
-
with open(path, "r") as f:
|
|
46
|
-
raw_config = yaml.safe_load(f)
|
|
47
|
-
|
|
48
|
-
# Get the 'alma' section or use whole file
|
|
49
|
-
config = raw_config.get("alma", raw_config)
|
|
50
|
-
|
|
51
|
-
# Expand environment variables and secrets
|
|
52
|
-
config = cls._expand_config(config)
|
|
53
|
-
|
|
54
|
-
return config
|
|
55
|
-
|
|
56
|
-
@classmethod
|
|
57
|
-
def _expand_config(cls, config: Any) -> Any:
|
|
58
|
-
"""Recursively expand environment variables and secrets in config."""
|
|
59
|
-
if isinstance(config, dict):
|
|
60
|
-
return {k: cls._expand_config(v) for k, v in config.items()}
|
|
61
|
-
elif isinstance(config, list):
|
|
62
|
-
return [cls._expand_config(item) for item in config]
|
|
63
|
-
elif isinstance(config, str):
|
|
64
|
-
return cls._expand_value(config)
|
|
65
|
-
return config
|
|
66
|
-
|
|
67
|
-
@classmethod
|
|
68
|
-
def _expand_value(cls, value: str) -> str:
|
|
69
|
-
"""
|
|
70
|
-
Expand a single config value.
|
|
71
|
-
|
|
72
|
-
Handles:
|
|
73
|
-
- ${ENV_VAR} -> os.environ["ENV_VAR"]
|
|
74
|
-
- ${KEYVAULT:secret-name} -> Azure Key Vault lookup
|
|
75
|
-
"""
|
|
76
|
-
if not isinstance(value, str) or "${" not in value:
|
|
77
|
-
return value
|
|
78
|
-
|
|
79
|
-
# Handle ${VAR} patterns
|
|
80
|
-
import re
|
|
81
|
-
|
|
82
|
-
pattern = r"\$\{([^}]+)\}"
|
|
83
|
-
|
|
84
|
-
def replace(match):
|
|
85
|
-
ref = match.group(1)
|
|
86
|
-
|
|
87
|
-
if ref.startswith("KEYVAULT:"):
|
|
88
|
-
secret_name = ref[9:] # Remove "KEYVAULT:" prefix
|
|
89
|
-
return cls._get_keyvault_secret(secret_name)
|
|
90
|
-
else:
|
|
91
|
-
# Environment variable
|
|
92
|
-
env_value = os.environ.get(ref)
|
|
93
|
-
if env_value is None:
|
|
94
|
-
logger.warning(f"Environment variable {ref} not set")
|
|
95
|
-
return match.group(0) # Keep original if not found
|
|
96
|
-
return env_value
|
|
97
|
-
|
|
98
|
-
return re.sub(pattern, replace, value)
|
|
99
|
-
|
|
100
|
-
@classmethod
|
|
101
|
-
def _get_keyvault_secret(cls, secret_name: str) -> str:
|
|
102
|
-
"""
|
|
103
|
-
Retrieve secret from Azure Key Vault.
|
|
104
|
-
|
|
105
|
-
Requires AZURE_KEYVAULT_URL environment variable.
|
|
106
|
-
"""
|
|
107
|
-
if cls._keyvault_client is None:
|
|
108
|
-
vault_url = os.environ.get("AZURE_KEYVAULT_URL")
|
|
109
|
-
if not vault_url:
|
|
110
|
-
logger.error("AZURE_KEYVAULT_URL not set, cannot retrieve secrets")
|
|
111
|
-
return f"${{KEYVAULT:{secret_name}}}"
|
|
112
|
-
|
|
113
|
-
try:
|
|
114
|
-
from azure.identity import DefaultAzureCredential
|
|
115
|
-
from azure.keyvault.secrets import SecretClient
|
|
116
|
-
|
|
117
|
-
credential = DefaultAzureCredential()
|
|
118
|
-
cls._keyvault_client = SecretClient(
|
|
119
|
-
vault_url=vault_url,
|
|
120
|
-
credential=credential,
|
|
121
|
-
)
|
|
122
|
-
except ImportError:
|
|
123
|
-
logger.error(
|
|
124
|
-
"azure-identity and azure-keyvault-secrets packages required "
|
|
125
|
-
"for Key Vault integration"
|
|
126
|
-
)
|
|
127
|
-
return f"${{KEYVAULT:{secret_name}}}"
|
|
128
|
-
|
|
129
|
-
try:
|
|
130
|
-
secret = cls._keyvault_client.get_secret(secret_name)
|
|
131
|
-
return secret.value
|
|
132
|
-
except Exception as e:
|
|
133
|
-
logger.error(f"Failed to retrieve secret {secret_name}: {e}")
|
|
134
|
-
return f"${{KEYVAULT:{secret_name}}}"
|
|
135
|
-
|
|
136
|
-
@staticmethod
|
|
137
|
-
def _get_defaults() -> Dict[str, Any]:
|
|
138
|
-
"""Return default configuration."""
|
|
139
|
-
return {
|
|
140
|
-
"project_id": "default",
|
|
141
|
-
"storage": "file",
|
|
142
|
-
"embedding_provider": "local",
|
|
143
|
-
"agents": {},
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@classmethod
|
|
147
|
-
def save(cls, config: Dict[str, Any], config_path: str):
|
|
148
|
-
"""
|
|
149
|
-
Save configuration to YAML file.
|
|
150
|
-
|
|
151
|
-
Note: Does NOT save secrets - those should remain as ${} references.
|
|
152
|
-
"""
|
|
153
|
-
path = Path(config_path)
|
|
154
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
155
|
-
|
|
156
|
-
with open(path, "w") as f:
|
|
157
|
-
yaml.dump({"alma": config}, f, default_flow_style=False)
|
|
1
|
+
"""
|
|
2
|
+
ALMA Configuration Loader.
|
|
3
|
+
|
|
4
|
+
Handles loading configuration from files and environment variables,
|
|
5
|
+
with support for Azure Key Vault secret resolution.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, Dict
|
|
12
|
+
|
|
13
|
+
import yaml
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ConfigLoader:
|
|
19
|
+
"""
|
|
20
|
+
Loads ALMA configuration from YAML files with environment variable expansion.
|
|
21
|
+
|
|
22
|
+
Supports:
|
|
23
|
+
- ${ENV_VAR} syntax for environment variables
|
|
24
|
+
- ${KEYVAULT:secret-name} syntax for Azure Key Vault (when configured)
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
_keyvault_client = None
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def load(cls, config_path: str) -> Dict[str, Any]:
|
|
31
|
+
"""
|
|
32
|
+
Load configuration from YAML file.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
config_path: Path to config.yaml
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Parsed and expanded configuration dict
|
|
39
|
+
"""
|
|
40
|
+
path = Path(config_path)
|
|
41
|
+
if not path.exists():
|
|
42
|
+
logger.warning(f"Config not found at {config_path}, using defaults")
|
|
43
|
+
return cls._get_defaults()
|
|
44
|
+
|
|
45
|
+
with open(path, "r") as f:
|
|
46
|
+
raw_config = yaml.safe_load(f)
|
|
47
|
+
|
|
48
|
+
# Get the 'alma' section or use whole file
|
|
49
|
+
config = raw_config.get("alma", raw_config)
|
|
50
|
+
|
|
51
|
+
# Expand environment variables and secrets
|
|
52
|
+
config = cls._expand_config(config)
|
|
53
|
+
|
|
54
|
+
return config
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def _expand_config(cls, config: Any) -> Any:
|
|
58
|
+
"""Recursively expand environment variables and secrets in config."""
|
|
59
|
+
if isinstance(config, dict):
|
|
60
|
+
return {k: cls._expand_config(v) for k, v in config.items()}
|
|
61
|
+
elif isinstance(config, list):
|
|
62
|
+
return [cls._expand_config(item) for item in config]
|
|
63
|
+
elif isinstance(config, str):
|
|
64
|
+
return cls._expand_value(config)
|
|
65
|
+
return config
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def _expand_value(cls, value: str) -> str:
|
|
69
|
+
"""
|
|
70
|
+
Expand a single config value.
|
|
71
|
+
|
|
72
|
+
Handles:
|
|
73
|
+
- ${ENV_VAR} -> os.environ["ENV_VAR"]
|
|
74
|
+
- ${KEYVAULT:secret-name} -> Azure Key Vault lookup
|
|
75
|
+
"""
|
|
76
|
+
if not isinstance(value, str) or "${" not in value:
|
|
77
|
+
return value
|
|
78
|
+
|
|
79
|
+
# Handle ${VAR} patterns
|
|
80
|
+
import re
|
|
81
|
+
|
|
82
|
+
pattern = r"\$\{([^}]+)\}"
|
|
83
|
+
|
|
84
|
+
def replace(match):
|
|
85
|
+
ref = match.group(1)
|
|
86
|
+
|
|
87
|
+
if ref.startswith("KEYVAULT:"):
|
|
88
|
+
secret_name = ref[9:] # Remove "KEYVAULT:" prefix
|
|
89
|
+
return cls._get_keyvault_secret(secret_name)
|
|
90
|
+
else:
|
|
91
|
+
# Environment variable
|
|
92
|
+
env_value = os.environ.get(ref)
|
|
93
|
+
if env_value is None:
|
|
94
|
+
logger.warning(f"Environment variable {ref} not set")
|
|
95
|
+
return match.group(0) # Keep original if not found
|
|
96
|
+
return env_value
|
|
97
|
+
|
|
98
|
+
return re.sub(pattern, replace, value)
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def _get_keyvault_secret(cls, secret_name: str) -> str:
|
|
102
|
+
"""
|
|
103
|
+
Retrieve secret from Azure Key Vault.
|
|
104
|
+
|
|
105
|
+
Requires AZURE_KEYVAULT_URL environment variable.
|
|
106
|
+
"""
|
|
107
|
+
if cls._keyvault_client is None:
|
|
108
|
+
vault_url = os.environ.get("AZURE_KEYVAULT_URL")
|
|
109
|
+
if not vault_url:
|
|
110
|
+
logger.error("AZURE_KEYVAULT_URL not set, cannot retrieve secrets")
|
|
111
|
+
return f"${{KEYVAULT:{secret_name}}}"
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
from azure.identity import DefaultAzureCredential
|
|
115
|
+
from azure.keyvault.secrets import SecretClient
|
|
116
|
+
|
|
117
|
+
credential = DefaultAzureCredential()
|
|
118
|
+
cls._keyvault_client = SecretClient(
|
|
119
|
+
vault_url=vault_url,
|
|
120
|
+
credential=credential,
|
|
121
|
+
)
|
|
122
|
+
except ImportError:
|
|
123
|
+
logger.error(
|
|
124
|
+
"azure-identity and azure-keyvault-secrets packages required "
|
|
125
|
+
"for Key Vault integration"
|
|
126
|
+
)
|
|
127
|
+
return f"${{KEYVAULT:{secret_name}}}"
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
secret = cls._keyvault_client.get_secret(secret_name)
|
|
131
|
+
return secret.value
|
|
132
|
+
except Exception as e:
|
|
133
|
+
logger.error(f"Failed to retrieve secret {secret_name}: {e}")
|
|
134
|
+
return f"${{KEYVAULT:{secret_name}}}"
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def _get_defaults() -> Dict[str, Any]:
|
|
138
|
+
"""Return default configuration."""
|
|
139
|
+
return {
|
|
140
|
+
"project_id": "default",
|
|
141
|
+
"storage": "file",
|
|
142
|
+
"embedding_provider": "local",
|
|
143
|
+
"agents": {},
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@classmethod
|
|
147
|
+
def save(cls, config: Dict[str, Any], config_path: str):
|
|
148
|
+
"""
|
|
149
|
+
Save configuration to YAML file.
|
|
150
|
+
|
|
151
|
+
Note: Does NOT save secrets - those should remain as ${} references.
|
|
152
|
+
"""
|
|
153
|
+
path = Path(config_path)
|
|
154
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
155
|
+
|
|
156
|
+
with open(path, "w") as f:
|
|
157
|
+
yaml.dump({"alma": config}, f, default_flow_style=False)
|
alma/consolidation/__init__.py
CHANGED
|
@@ -1,23 +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
|
-
]
|
|
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
|
+
]
|