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/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
|
+
}
|
alma/integration/__init__.py
CHANGED
|
@@ -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
|
+
]
|