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.
Files changed (111) hide show
  1. alma/__init__.py +296 -226
  2. alma/compression/__init__.py +33 -0
  3. alma/compression/pipeline.py +980 -0
  4. alma/confidence/__init__.py +47 -47
  5. alma/confidence/engine.py +540 -540
  6. alma/confidence/types.py +351 -351
  7. alma/config/loader.py +157 -157
  8. alma/consolidation/__init__.py +23 -23
  9. alma/consolidation/engine.py +678 -678
  10. alma/consolidation/prompts.py +84 -84
  11. alma/core.py +1189 -430
  12. alma/domains/__init__.py +30 -30
  13. alma/domains/factory.py +359 -359
  14. alma/domains/schemas.py +448 -448
  15. alma/domains/types.py +272 -272
  16. alma/events/__init__.py +75 -75
  17. alma/events/emitter.py +285 -284
  18. alma/events/storage_mixin.py +246 -246
  19. alma/events/types.py +126 -126
  20. alma/events/webhook.py +425 -425
  21. alma/exceptions.py +49 -49
  22. alma/extraction/__init__.py +31 -31
  23. alma/extraction/auto_learner.py +265 -265
  24. alma/extraction/extractor.py +420 -420
  25. alma/graph/__init__.py +106 -106
  26. alma/graph/backends/__init__.py +32 -32
  27. alma/graph/backends/kuzu.py +624 -624
  28. alma/graph/backends/memgraph.py +432 -432
  29. alma/graph/backends/memory.py +236 -236
  30. alma/graph/backends/neo4j.py +417 -417
  31. alma/graph/base.py +159 -159
  32. alma/graph/extraction.py +198 -198
  33. alma/graph/store.py +860 -860
  34. alma/harness/__init__.py +35 -35
  35. alma/harness/base.py +386 -386
  36. alma/harness/domains.py +705 -705
  37. alma/initializer/__init__.py +37 -37
  38. alma/initializer/initializer.py +418 -418
  39. alma/initializer/types.py +250 -250
  40. alma/integration/__init__.py +62 -62
  41. alma/integration/claude_agents.py +444 -444
  42. alma/integration/helena.py +423 -423
  43. alma/integration/victor.py +471 -471
  44. alma/learning/__init__.py +101 -86
  45. alma/learning/decay.py +878 -0
  46. alma/learning/forgetting.py +1446 -1446
  47. alma/learning/heuristic_extractor.py +390 -390
  48. alma/learning/protocols.py +374 -374
  49. alma/learning/validation.py +346 -346
  50. alma/mcp/__init__.py +123 -45
  51. alma/mcp/__main__.py +156 -156
  52. alma/mcp/resources.py +122 -122
  53. alma/mcp/server.py +955 -591
  54. alma/mcp/tools.py +3254 -509
  55. alma/observability/__init__.py +91 -84
  56. alma/observability/config.py +302 -302
  57. alma/observability/guidelines.py +170 -0
  58. alma/observability/logging.py +424 -424
  59. alma/observability/metrics.py +583 -583
  60. alma/observability/tracing.py +440 -440
  61. alma/progress/__init__.py +21 -21
  62. alma/progress/tracker.py +607 -607
  63. alma/progress/types.py +250 -250
  64. alma/retrieval/__init__.py +134 -53
  65. alma/retrieval/budget.py +525 -0
  66. alma/retrieval/cache.py +1304 -1061
  67. alma/retrieval/embeddings.py +202 -202
  68. alma/retrieval/engine.py +850 -427
  69. alma/retrieval/modes.py +365 -0
  70. alma/retrieval/progressive.py +560 -0
  71. alma/retrieval/scoring.py +344 -344
  72. alma/retrieval/trust_scoring.py +637 -0
  73. alma/retrieval/verification.py +797 -0
  74. alma/session/__init__.py +19 -19
  75. alma/session/manager.py +442 -399
  76. alma/session/types.py +288 -288
  77. alma/storage/__init__.py +101 -90
  78. alma/storage/archive.py +233 -0
  79. alma/storage/azure_cosmos.py +1259 -1259
  80. alma/storage/base.py +1083 -583
  81. alma/storage/chroma.py +1443 -1443
  82. alma/storage/constants.py +103 -103
  83. alma/storage/file_based.py +614 -614
  84. alma/storage/migrations/__init__.py +21 -21
  85. alma/storage/migrations/base.py +321 -321
  86. alma/storage/migrations/runner.py +323 -323
  87. alma/storage/migrations/version_stores.py +337 -337
  88. alma/storage/migrations/versions/__init__.py +11 -11
  89. alma/storage/migrations/versions/v1_0_0.py +373 -373
  90. alma/storage/migrations/versions/v1_1_0_workflow_context.py +551 -0
  91. alma/storage/pinecone.py +1080 -1080
  92. alma/storage/postgresql.py +1948 -1559
  93. alma/storage/qdrant.py +1306 -1306
  94. alma/storage/sqlite_local.py +3041 -1457
  95. alma/testing/__init__.py +46 -46
  96. alma/testing/factories.py +301 -301
  97. alma/testing/mocks.py +389 -389
  98. alma/types.py +292 -264
  99. alma/utils/__init__.py +19 -0
  100. alma/utils/tokenizer.py +521 -0
  101. alma/workflow/__init__.py +83 -0
  102. alma/workflow/artifacts.py +170 -0
  103. alma/workflow/checkpoint.py +311 -0
  104. alma/workflow/context.py +228 -0
  105. alma/workflow/outcomes.py +189 -0
  106. alma/workflow/reducers.py +393 -0
  107. {alma_memory-0.5.1.dist-info → alma_memory-0.7.0.dist-info}/METADATA +210 -72
  108. alma_memory-0.7.0.dist-info/RECORD +112 -0
  109. alma_memory-0.5.1.dist-info/RECORD +0 -93
  110. {alma_memory-0.5.1.dist-info → alma_memory-0.7.0.dist-info}/WHEEL +0 -0
  111. {alma_memory-0.5.1.dist-info → alma_memory-0.7.0.dist-info}/top_level.txt +0 -0
alma/initializer/types.py CHANGED
@@ -1,250 +1,250 @@
1
- """
2
- Initializer Types.
3
-
4
- Data structures for the Session Initializer pattern.
5
- """
6
-
7
- import uuid
8
- from dataclasses import dataclass, field
9
- from datetime import datetime, timezone
10
- from typing import Any, Dict, List, Optional
11
-
12
-
13
- @dataclass
14
- class CodebaseOrientation:
15
- """Codebase orientation information."""
16
-
17
- # Git state
18
- current_branch: str
19
- has_uncommitted_changes: bool
20
- recent_commits: List[str] # Last N commit messages
21
-
22
- # File structure
23
- root_path: str
24
- key_directories: List[str] # src/, tests/, etc.
25
- config_files: List[str] # package.json, pyproject.toml, etc.
26
-
27
- # Summary
28
- summary: Optional[str] = None
29
-
30
- def to_prompt(self) -> str:
31
- """Format orientation for prompt injection."""
32
- lines = [
33
- f"Branch: {self.current_branch}",
34
- f"Uncommitted changes: {'Yes' if self.has_uncommitted_changes else 'No'}",
35
- ]
36
-
37
- if self.recent_commits:
38
- lines.append("Recent commits:")
39
- for commit in self.recent_commits[:5]:
40
- lines.append(f" - {commit}")
41
-
42
- if self.key_directories:
43
- lines.append(f"Key directories: {', '.join(self.key_directories)}")
44
-
45
- if self.summary:
46
- lines.append(f"Summary: {self.summary}")
47
-
48
- return "\n".join(lines)
49
-
50
-
51
- @dataclass
52
- class RulesOfEngagement:
53
- """Rules governing agent behavior during session."""
54
-
55
- # What agent CAN do
56
- scope_rules: List[str] = field(default_factory=list)
57
-
58
- # What agent CANNOT do
59
- constraints: List[str] = field(default_factory=list)
60
-
61
- # Must pass before marking "done"
62
- quality_gates: List[str] = field(default_factory=list)
63
-
64
- def to_prompt(self) -> str:
65
- """Format rules for prompt injection."""
66
- lines = []
67
-
68
- if self.scope_rules:
69
- lines.append("You CAN:")
70
- for rule in self.scope_rules:
71
- lines.append(f" - {rule}")
72
-
73
- if self.constraints:
74
- lines.append("You CANNOT:")
75
- for constraint in self.constraints:
76
- lines.append(f" - {constraint}")
77
-
78
- if self.quality_gates:
79
- lines.append("Before marking DONE, verify:")
80
- for gate in self.quality_gates:
81
- lines.append(f" - {gate}")
82
-
83
- return "\n".join(lines)
84
-
85
-
86
- @dataclass
87
- class InitializationResult:
88
- """
89
- Result of session initialization.
90
-
91
- Contains everything an agent needs to start work:
92
- - Expanded goal and work items
93
- - Codebase orientation
94
- - Relevant memories
95
- - Rules of engagement
96
- - Recommended starting point
97
- """
98
-
99
- id: str
100
- session_id: str
101
- project_id: str
102
- agent: str
103
-
104
- # Original and expanded goal
105
- original_prompt: str
106
- goal: str
107
-
108
- # Work items extracted from goal
109
- work_items: List[Any] = field(default_factory=list) # WorkItem objects
110
-
111
- # Codebase orientation
112
- orientation: Optional[CodebaseOrientation] = None
113
-
114
- # Recent activity
115
- recent_activity: List[str] = field(default_factory=list)
116
-
117
- # Relevant memories (MemorySlice)
118
- relevant_memories: Optional[Any] = None
119
-
120
- # Rules of engagement
121
- rules: RulesOfEngagement = field(default_factory=RulesOfEngagement)
122
-
123
- # Suggested first action
124
- recommended_start: Optional[Any] = None # WorkItem
125
-
126
- # Metadata
127
- initialized_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
128
- metadata: Dict[str, Any] = field(default_factory=dict)
129
-
130
- @classmethod
131
- def create(
132
- cls,
133
- project_id: str,
134
- agent: str,
135
- original_prompt: str,
136
- goal: Optional[str] = None,
137
- session_id: Optional[str] = None,
138
- ) -> "InitializationResult":
139
- """Create a new initialization result."""
140
- return cls(
141
- id=str(uuid.uuid4()),
142
- session_id=session_id or str(uuid.uuid4()),
143
- project_id=project_id,
144
- agent=agent,
145
- original_prompt=original_prompt,
146
- goal=goal or original_prompt,
147
- )
148
-
149
- def to_prompt(self) -> str:
150
- """
151
- Format initialization result for prompt injection.
152
-
153
- This is the "briefing" that prepares the agent.
154
- """
155
- sections = []
156
-
157
- # Header
158
- sections.append(f"## Session Initialization for {self.agent}")
159
- sections.append(f"Project: {self.project_id}")
160
- sections.append(f"Session: {self.session_id}")
161
- sections.append("")
162
-
163
- # Goal
164
- sections.append("### Goal")
165
- sections.append(self.goal)
166
- sections.append("")
167
-
168
- # Work items
169
- if self.work_items:
170
- sections.append("### Work Items")
171
- for i, item in enumerate(self.work_items, 1):
172
- title = getattr(item, "title", str(item))
173
- status = getattr(item, "status", "pending")
174
- sections.append(f"{i}. [{status}] {title}")
175
- sections.append("")
176
-
177
- # Orientation
178
- if self.orientation:
179
- sections.append("### Codebase Orientation")
180
- sections.append(self.orientation.to_prompt())
181
- sections.append("")
182
-
183
- # Relevant memories
184
- if self.relevant_memories:
185
- sections.append("### Relevant Knowledge from Past Runs")
186
- if hasattr(self.relevant_memories, "to_prompt"):
187
- sections.append(self.relevant_memories.to_prompt())
188
- else:
189
- sections.append(str(self.relevant_memories))
190
- sections.append("")
191
-
192
- # Rules of engagement
193
- if self.rules.scope_rules or self.rules.constraints or self.rules.quality_gates:
194
- sections.append("### Rules of Engagement")
195
- sections.append(self.rules.to_prompt())
196
- sections.append("")
197
-
198
- # Recommended start
199
- if self.recommended_start:
200
- sections.append("### Recommended First Action")
201
- title = getattr(
202
- self.recommended_start, "title", str(self.recommended_start)
203
- )
204
- sections.append(f"Start with: {title}")
205
- sections.append("")
206
-
207
- return "\n".join(sections)
208
-
209
- def to_dict(self) -> Dict[str, Any]:
210
- """Serialize to dictionary."""
211
- return {
212
- "id": self.id,
213
- "session_id": self.session_id,
214
- "project_id": self.project_id,
215
- "agent": self.agent,
216
- "original_prompt": self.original_prompt,
217
- "goal": self.goal,
218
- "work_items": [
219
- item.to_dict() if hasattr(item, "to_dict") else str(item)
220
- for item in self.work_items
221
- ],
222
- "orientation": (
223
- {
224
- "current_branch": self.orientation.current_branch,
225
- "has_uncommitted_changes": self.orientation.has_uncommitted_changes,
226
- "recent_commits": self.orientation.recent_commits,
227
- "root_path": self.orientation.root_path,
228
- "key_directories": self.orientation.key_directories,
229
- "config_files": self.orientation.config_files,
230
- "summary": self.orientation.summary,
231
- }
232
- if self.orientation
233
- else None
234
- ),
235
- "recent_activity": self.recent_activity,
236
- "rules": {
237
- "scope_rules": self.rules.scope_rules,
238
- "constraints": self.rules.constraints,
239
- "quality_gates": self.rules.quality_gates,
240
- },
241
- "recommended_start": (
242
- self.recommended_start.to_dict()
243
- if self.recommended_start and hasattr(self.recommended_start, "to_dict")
244
- else str(self.recommended_start)
245
- if self.recommended_start
246
- else None
247
- ),
248
- "initialized_at": self.initialized_at.isoformat(),
249
- "metadata": self.metadata,
250
- }
1
+ """
2
+ Initializer Types.
3
+
4
+ Data structures for the Session Initializer pattern.
5
+ """
6
+
7
+ import uuid
8
+ from dataclasses import dataclass, field
9
+ from datetime import datetime, timezone
10
+ from typing import Any, Dict, List, Optional
11
+
12
+
13
+ @dataclass
14
+ class CodebaseOrientation:
15
+ """Codebase orientation information."""
16
+
17
+ # Git state
18
+ current_branch: str
19
+ has_uncommitted_changes: bool
20
+ recent_commits: List[str] # Last N commit messages
21
+
22
+ # File structure
23
+ root_path: str
24
+ key_directories: List[str] # src/, tests/, etc.
25
+ config_files: List[str] # package.json, pyproject.toml, etc.
26
+
27
+ # Summary
28
+ summary: Optional[str] = None
29
+
30
+ def to_prompt(self) -> str:
31
+ """Format orientation for prompt injection."""
32
+ lines = [
33
+ f"Branch: {self.current_branch}",
34
+ f"Uncommitted changes: {'Yes' if self.has_uncommitted_changes else 'No'}",
35
+ ]
36
+
37
+ if self.recent_commits:
38
+ lines.append("Recent commits:")
39
+ for commit in self.recent_commits[:5]:
40
+ lines.append(f" - {commit}")
41
+
42
+ if self.key_directories:
43
+ lines.append(f"Key directories: {', '.join(self.key_directories)}")
44
+
45
+ if self.summary:
46
+ lines.append(f"Summary: {self.summary}")
47
+
48
+ return "\n".join(lines)
49
+
50
+
51
+ @dataclass
52
+ class RulesOfEngagement:
53
+ """Rules governing agent behavior during session."""
54
+
55
+ # What agent CAN do
56
+ scope_rules: List[str] = field(default_factory=list)
57
+
58
+ # What agent CANNOT do
59
+ constraints: List[str] = field(default_factory=list)
60
+
61
+ # Must pass before marking "done"
62
+ quality_gates: List[str] = field(default_factory=list)
63
+
64
+ def to_prompt(self) -> str:
65
+ """Format rules for prompt injection."""
66
+ lines = []
67
+
68
+ if self.scope_rules:
69
+ lines.append("You CAN:")
70
+ for rule in self.scope_rules:
71
+ lines.append(f" - {rule}")
72
+
73
+ if self.constraints:
74
+ lines.append("You CANNOT:")
75
+ for constraint in self.constraints:
76
+ lines.append(f" - {constraint}")
77
+
78
+ if self.quality_gates:
79
+ lines.append("Before marking DONE, verify:")
80
+ for gate in self.quality_gates:
81
+ lines.append(f" - {gate}")
82
+
83
+ return "\n".join(lines)
84
+
85
+
86
+ @dataclass
87
+ class InitializationResult:
88
+ """
89
+ Result of session initialization.
90
+
91
+ Contains everything an agent needs to start work:
92
+ - Expanded goal and work items
93
+ - Codebase orientation
94
+ - Relevant memories
95
+ - Rules of engagement
96
+ - Recommended starting point
97
+ """
98
+
99
+ id: str
100
+ session_id: str
101
+ project_id: str
102
+ agent: str
103
+
104
+ # Original and expanded goal
105
+ original_prompt: str
106
+ goal: str
107
+
108
+ # Work items extracted from goal
109
+ work_items: List[Any] = field(default_factory=list) # WorkItem objects
110
+
111
+ # Codebase orientation
112
+ orientation: Optional[CodebaseOrientation] = None
113
+
114
+ # Recent activity
115
+ recent_activity: List[str] = field(default_factory=list)
116
+
117
+ # Relevant memories (MemorySlice)
118
+ relevant_memories: Optional[Any] = None
119
+
120
+ # Rules of engagement
121
+ rules: RulesOfEngagement = field(default_factory=RulesOfEngagement)
122
+
123
+ # Suggested first action
124
+ recommended_start: Optional[Any] = None # WorkItem
125
+
126
+ # Metadata
127
+ initialized_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
128
+ metadata: Dict[str, Any] = field(default_factory=dict)
129
+
130
+ @classmethod
131
+ def create(
132
+ cls,
133
+ project_id: str,
134
+ agent: str,
135
+ original_prompt: str,
136
+ goal: Optional[str] = None,
137
+ session_id: Optional[str] = None,
138
+ ) -> "InitializationResult":
139
+ """Create a new initialization result."""
140
+ return cls(
141
+ id=str(uuid.uuid4()),
142
+ session_id=session_id or str(uuid.uuid4()),
143
+ project_id=project_id,
144
+ agent=agent,
145
+ original_prompt=original_prompt,
146
+ goal=goal or original_prompt,
147
+ )
148
+
149
+ def to_prompt(self) -> str:
150
+ """
151
+ Format initialization result for prompt injection.
152
+
153
+ This is the "briefing" that prepares the agent.
154
+ """
155
+ sections = []
156
+
157
+ # Header
158
+ sections.append(f"## Session Initialization for {self.agent}")
159
+ sections.append(f"Project: {self.project_id}")
160
+ sections.append(f"Session: {self.session_id}")
161
+ sections.append("")
162
+
163
+ # Goal
164
+ sections.append("### Goal")
165
+ sections.append(self.goal)
166
+ sections.append("")
167
+
168
+ # Work items
169
+ if self.work_items:
170
+ sections.append("### Work Items")
171
+ for i, item in enumerate(self.work_items, 1):
172
+ title = getattr(item, "title", str(item))
173
+ status = getattr(item, "status", "pending")
174
+ sections.append(f"{i}. [{status}] {title}")
175
+ sections.append("")
176
+
177
+ # Orientation
178
+ if self.orientation:
179
+ sections.append("### Codebase Orientation")
180
+ sections.append(self.orientation.to_prompt())
181
+ sections.append("")
182
+
183
+ # Relevant memories
184
+ if self.relevant_memories:
185
+ sections.append("### Relevant Knowledge from Past Runs")
186
+ if hasattr(self.relevant_memories, "to_prompt"):
187
+ sections.append(self.relevant_memories.to_prompt())
188
+ else:
189
+ sections.append(str(self.relevant_memories))
190
+ sections.append("")
191
+
192
+ # Rules of engagement
193
+ if self.rules.scope_rules or self.rules.constraints or self.rules.quality_gates:
194
+ sections.append("### Rules of Engagement")
195
+ sections.append(self.rules.to_prompt())
196
+ sections.append("")
197
+
198
+ # Recommended start
199
+ if self.recommended_start:
200
+ sections.append("### Recommended First Action")
201
+ title = getattr(
202
+ self.recommended_start, "title", str(self.recommended_start)
203
+ )
204
+ sections.append(f"Start with: {title}")
205
+ sections.append("")
206
+
207
+ return "\n".join(sections)
208
+
209
+ def to_dict(self) -> Dict[str, Any]:
210
+ """Serialize to dictionary."""
211
+ return {
212
+ "id": self.id,
213
+ "session_id": self.session_id,
214
+ "project_id": self.project_id,
215
+ "agent": self.agent,
216
+ "original_prompt": self.original_prompt,
217
+ "goal": self.goal,
218
+ "work_items": [
219
+ item.to_dict() if hasattr(item, "to_dict") else str(item)
220
+ for item in self.work_items
221
+ ],
222
+ "orientation": (
223
+ {
224
+ "current_branch": self.orientation.current_branch,
225
+ "has_uncommitted_changes": self.orientation.has_uncommitted_changes,
226
+ "recent_commits": self.orientation.recent_commits,
227
+ "root_path": self.orientation.root_path,
228
+ "key_directories": self.orientation.key_directories,
229
+ "config_files": self.orientation.config_files,
230
+ "summary": self.orientation.summary,
231
+ }
232
+ if self.orientation
233
+ else None
234
+ ),
235
+ "recent_activity": self.recent_activity,
236
+ "rules": {
237
+ "scope_rules": self.rules.scope_rules,
238
+ "constraints": self.rules.constraints,
239
+ "quality_gates": self.rules.quality_gates,
240
+ },
241
+ "recommended_start": (
242
+ self.recommended_start.to_dict()
243
+ if self.recommended_start and hasattr(self.recommended_start, "to_dict")
244
+ else str(self.recommended_start)
245
+ if self.recommended_start
246
+ else None
247
+ ),
248
+ "initialized_at": self.initialized_at.isoformat(),
249
+ "metadata": self.metadata,
250
+ }
@@ -1,62 +1,62 @@
1
- """
2
- ALMA Agent Integration.
3
-
4
- Provides integration hooks for Claude Code agents (Helena, Victor, etc).
5
- """
6
-
7
- from alma.integration.claude_agents import (
8
- AgentIntegration,
9
- AgentType,
10
- ClaudeAgentHooks,
11
- TaskContext,
12
- TaskOutcome,
13
- create_integration,
14
- )
15
- from alma.integration.helena import (
16
- HELENA_CATEGORIES,
17
- HELENA_FORBIDDEN,
18
- HelenaHooks,
19
- UITestContext,
20
- UITestOutcome,
21
- create_helena_hooks,
22
- helena_post_task,
23
- helena_pre_task,
24
- )
25
- from alma.integration.victor import (
26
- VICTOR_CATEGORIES,
27
- VICTOR_FORBIDDEN,
28
- APITestContext,
29
- APITestOutcome,
30
- VictorHooks,
31
- create_victor_hooks,
32
- victor_post_task,
33
- victor_pre_task,
34
- )
35
-
36
- __all__ = [
37
- # Core Integration
38
- "AgentType",
39
- "TaskContext",
40
- "TaskOutcome",
41
- "ClaudeAgentHooks",
42
- "AgentIntegration",
43
- "create_integration",
44
- # Helena Integration
45
- "UITestContext",
46
- "UITestOutcome",
47
- "HelenaHooks",
48
- "create_helena_hooks",
49
- "helena_pre_task",
50
- "helena_post_task",
51
- "HELENA_CATEGORIES",
52
- "HELENA_FORBIDDEN",
53
- # Victor Integration
54
- "APITestContext",
55
- "APITestOutcome",
56
- "VictorHooks",
57
- "create_victor_hooks",
58
- "victor_pre_task",
59
- "victor_post_task",
60
- "VICTOR_CATEGORIES",
61
- "VICTOR_FORBIDDEN",
62
- ]
1
+ """
2
+ ALMA Agent Integration.
3
+
4
+ Provides integration hooks for Claude Code agents (Helena, Victor, etc).
5
+ """
6
+
7
+ from alma.integration.claude_agents import (
8
+ AgentIntegration,
9
+ AgentType,
10
+ ClaudeAgentHooks,
11
+ TaskContext,
12
+ TaskOutcome,
13
+ create_integration,
14
+ )
15
+ from alma.integration.helena import (
16
+ HELENA_CATEGORIES,
17
+ HELENA_FORBIDDEN,
18
+ HelenaHooks,
19
+ UITestContext,
20
+ UITestOutcome,
21
+ create_helena_hooks,
22
+ helena_post_task,
23
+ helena_pre_task,
24
+ )
25
+ from alma.integration.victor import (
26
+ VICTOR_CATEGORIES,
27
+ VICTOR_FORBIDDEN,
28
+ APITestContext,
29
+ APITestOutcome,
30
+ VictorHooks,
31
+ create_victor_hooks,
32
+ victor_post_task,
33
+ victor_pre_task,
34
+ )
35
+
36
+ __all__ = [
37
+ # Core Integration
38
+ "AgentType",
39
+ "TaskContext",
40
+ "TaskOutcome",
41
+ "ClaudeAgentHooks",
42
+ "AgentIntegration",
43
+ "create_integration",
44
+ # Helena Integration
45
+ "UITestContext",
46
+ "UITestOutcome",
47
+ "HelenaHooks",
48
+ "create_helena_hooks",
49
+ "helena_pre_task",
50
+ "helena_post_task",
51
+ "HELENA_CATEGORIES",
52
+ "HELENA_FORBIDDEN",
53
+ # Victor Integration
54
+ "APITestContext",
55
+ "APITestOutcome",
56
+ "VictorHooks",
57
+ "create_victor_hooks",
58
+ "victor_pre_task",
59
+ "victor_post_task",
60
+ "VICTOR_CATEGORIES",
61
+ "VICTOR_FORBIDDEN",
62
+ ]