hanzo 0.3.21__py3-none-any.whl → 0.3.23__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.
Potentially problematic release.
This version of hanzo might be problematic. Click here for more details.
- hanzo/base_agent.py +517 -0
- hanzo/batch_orchestrator.py +988 -0
- hanzo/cli.py +1 -1
- hanzo/commands/repl.py +5 -2
- hanzo/dev.py +463 -261
- hanzo/fallback_handler.py +78 -52
- hanzo/memory_manager.py +145 -122
- hanzo/model_registry.py +399 -0
- hanzo/rate_limiter.py +59 -74
- hanzo/streaming.py +91 -70
- {hanzo-0.3.21.dist-info → hanzo-0.3.23.dist-info}/METADATA +1 -1
- {hanzo-0.3.21.dist-info → hanzo-0.3.23.dist-info}/RECORD +14 -11
- {hanzo-0.3.21.dist-info → hanzo-0.3.23.dist-info}/WHEEL +0 -0
- {hanzo-0.3.21.dist-info → hanzo-0.3.23.dist-info}/entry_points.txt +0 -0
hanzo/memory_manager.py
CHANGED
|
@@ -3,66 +3,70 @@ Memory management system for Hanzo Dev.
|
|
|
3
3
|
Provides persistent context and memory like Claude Desktop.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
import json
|
|
7
6
|
import os
|
|
7
|
+
import json
|
|
8
|
+
import hashlib
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
8
10
|
from pathlib import Path
|
|
9
|
-
from typing import Dict, List, Any, Optional
|
|
10
11
|
from datetime import datetime
|
|
11
|
-
from dataclasses import
|
|
12
|
-
|
|
12
|
+
from dataclasses import asdict, dataclass
|
|
13
|
+
|
|
13
14
|
|
|
14
15
|
@dataclass
|
|
15
16
|
class MemoryItem:
|
|
16
17
|
"""A single memory item."""
|
|
18
|
+
|
|
17
19
|
id: str
|
|
18
20
|
content: str
|
|
19
21
|
type: str # 'context', 'instruction', 'fact', 'code'
|
|
20
22
|
created_at: str
|
|
21
23
|
tags: List[str]
|
|
22
24
|
priority: int = 0 # Higher priority items are kept longer
|
|
23
|
-
|
|
25
|
+
|
|
24
26
|
def to_dict(self) -> Dict:
|
|
25
27
|
return asdict(self)
|
|
26
|
-
|
|
28
|
+
|
|
27
29
|
@classmethod
|
|
28
|
-
def from_dict(cls, data: Dict) ->
|
|
30
|
+
def from_dict(cls, data: Dict) -> "MemoryItem":
|
|
29
31
|
return cls(**data)
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
class MemoryManager:
|
|
33
35
|
"""Manages persistent memory and context for AI conversations."""
|
|
34
|
-
|
|
36
|
+
|
|
35
37
|
def __init__(self, workspace_dir: str = None):
|
|
36
38
|
"""Initialize memory manager."""
|
|
37
39
|
if workspace_dir:
|
|
38
40
|
self.memory_dir = Path(workspace_dir) / ".hanzo" / "memory"
|
|
39
41
|
else:
|
|
40
42
|
self.memory_dir = Path.home() / ".hanzo" / "memory"
|
|
41
|
-
|
|
43
|
+
|
|
42
44
|
self.memory_dir.mkdir(parents=True, exist_ok=True)
|
|
43
45
|
self.memory_file = self.memory_dir / "context.json"
|
|
44
46
|
self.session_file = self.memory_dir / "session.json"
|
|
45
|
-
|
|
47
|
+
|
|
46
48
|
self.memories: List[MemoryItem] = []
|
|
47
49
|
self.session_context: Dict[str, Any] = {}
|
|
48
|
-
|
|
50
|
+
|
|
49
51
|
self.load_memories()
|
|
50
52
|
self.load_session()
|
|
51
|
-
|
|
53
|
+
|
|
52
54
|
def load_memories(self):
|
|
53
55
|
"""Load persistent memories from disk."""
|
|
54
56
|
if self.memory_file.exists():
|
|
55
57
|
try:
|
|
56
|
-
with open(self.memory_file,
|
|
58
|
+
with open(self.memory_file, "r") as f:
|
|
57
59
|
data = json.load(f)
|
|
58
|
-
self.memories = [
|
|
60
|
+
self.memories = [
|
|
61
|
+
MemoryItem.from_dict(item) for item in data.get("memories", [])
|
|
62
|
+
]
|
|
59
63
|
except Exception as e:
|
|
60
64
|
print(f"Error loading memories: {e}")
|
|
61
65
|
self.memories = []
|
|
62
66
|
else:
|
|
63
67
|
# Initialize with default memories
|
|
64
68
|
self._init_default_memories()
|
|
65
|
-
|
|
69
|
+
|
|
66
70
|
def _init_default_memories(self):
|
|
67
71
|
"""Initialize with helpful default memories."""
|
|
68
72
|
defaults = [
|
|
@@ -72,7 +76,7 @@ class MemoryManager:
|
|
|
72
76
|
type="instruction",
|
|
73
77
|
created_at=datetime.now().isoformat(),
|
|
74
78
|
tags=["system", "identity"],
|
|
75
|
-
priority=10
|
|
79
|
+
priority=10,
|
|
76
80
|
),
|
|
77
81
|
MemoryItem(
|
|
78
82
|
id=self._generate_id("capabilities"),
|
|
@@ -80,7 +84,7 @@ class MemoryManager:
|
|
|
80
84
|
type="fact",
|
|
81
85
|
created_at=datetime.now().isoformat(),
|
|
82
86
|
tags=["system", "capabilities"],
|
|
83
|
-
priority=9
|
|
87
|
+
priority=9,
|
|
84
88
|
),
|
|
85
89
|
MemoryItem(
|
|
86
90
|
id=self._generate_id("help"),
|
|
@@ -88,71 +92,77 @@ class MemoryManager:
|
|
|
88
92
|
type="instruction",
|
|
89
93
|
created_at=datetime.now().isoformat(),
|
|
90
94
|
tags=["system", "usage"],
|
|
91
|
-
priority=8
|
|
95
|
+
priority=8,
|
|
92
96
|
),
|
|
93
97
|
]
|
|
94
98
|
self.memories = defaults
|
|
95
99
|
self.save_memories()
|
|
96
|
-
|
|
100
|
+
|
|
97
101
|
def save_memories(self):
|
|
98
102
|
"""Save memories to disk."""
|
|
99
103
|
try:
|
|
100
104
|
data = {
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
"memories": [m.to_dict() for m in self.memories],
|
|
106
|
+
"updated_at": datetime.now().isoformat(),
|
|
103
107
|
}
|
|
104
|
-
with open(self.memory_file,
|
|
108
|
+
with open(self.memory_file, "w") as f:
|
|
105
109
|
json.dump(data, f, indent=2)
|
|
106
110
|
except Exception as e:
|
|
107
111
|
print(f"Error saving memories: {e}")
|
|
108
|
-
|
|
112
|
+
|
|
109
113
|
def load_session(self):
|
|
110
114
|
"""Load current session context."""
|
|
111
115
|
if self.session_file.exists():
|
|
112
116
|
try:
|
|
113
|
-
with open(self.session_file,
|
|
117
|
+
with open(self.session_file, "r") as f:
|
|
114
118
|
self.session_context = json.load(f)
|
|
115
119
|
except:
|
|
116
120
|
self.session_context = {}
|
|
117
121
|
else:
|
|
118
122
|
self.session_context = {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
"started_at": datetime.now().isoformat(),
|
|
124
|
+
"messages": [],
|
|
125
|
+
"current_task": None,
|
|
126
|
+
"preferences": {},
|
|
123
127
|
}
|
|
124
|
-
|
|
128
|
+
|
|
125
129
|
def save_session(self):
|
|
126
130
|
"""Save session context."""
|
|
127
131
|
try:
|
|
128
|
-
with open(self.session_file,
|
|
132
|
+
with open(self.session_file, "w") as f:
|
|
129
133
|
json.dump(self.session_context, f, indent=2)
|
|
130
134
|
except Exception as e:
|
|
131
135
|
print(f"Error saving session: {e}")
|
|
132
|
-
|
|
133
|
-
def add_memory(
|
|
136
|
+
|
|
137
|
+
def add_memory(
|
|
138
|
+
self,
|
|
139
|
+
content: str,
|
|
140
|
+
type: str = "context",
|
|
141
|
+
tags: List[str] = None,
|
|
142
|
+
priority: int = 0,
|
|
143
|
+
) -> str:
|
|
134
144
|
"""Add a new memory item."""
|
|
135
145
|
memory_id = self._generate_id(content)
|
|
136
|
-
|
|
146
|
+
|
|
137
147
|
# Check if similar memory exists
|
|
138
148
|
for mem in self.memories:
|
|
139
149
|
if mem.content == content:
|
|
140
150
|
return mem.id # Don't duplicate
|
|
141
|
-
|
|
151
|
+
|
|
142
152
|
memory = MemoryItem(
|
|
143
153
|
id=memory_id,
|
|
144
154
|
content=content,
|
|
145
155
|
type=type,
|
|
146
156
|
created_at=datetime.now().isoformat(),
|
|
147
157
|
tags=tags or [],
|
|
148
|
-
priority=priority
|
|
158
|
+
priority=priority,
|
|
149
159
|
)
|
|
150
|
-
|
|
160
|
+
|
|
151
161
|
self.memories.append(memory)
|
|
152
162
|
self.save_memories()
|
|
153
|
-
|
|
163
|
+
|
|
154
164
|
return memory_id
|
|
155
|
-
|
|
165
|
+
|
|
156
166
|
def remove_memory(self, memory_id: str) -> bool:
|
|
157
167
|
"""Remove a memory by ID."""
|
|
158
168
|
for i, mem in enumerate(self.memories):
|
|
@@ -161,7 +171,7 @@ class MemoryManager:
|
|
|
161
171
|
self.save_memories()
|
|
162
172
|
return True
|
|
163
173
|
return False
|
|
164
|
-
|
|
174
|
+
|
|
165
175
|
def clear_memories(self, keep_system: bool = True):
|
|
166
176
|
"""Clear all memories, optionally keeping system memories."""
|
|
167
177
|
if keep_system:
|
|
@@ -169,37 +179,39 @@ class MemoryManager:
|
|
|
169
179
|
else:
|
|
170
180
|
self.memories = []
|
|
171
181
|
self.save_memories()
|
|
172
|
-
|
|
173
|
-
def get_memories(
|
|
182
|
+
|
|
183
|
+
def get_memories(
|
|
184
|
+
self, type: str = None, tags: List[str] = None
|
|
185
|
+
) -> List[MemoryItem]:
|
|
174
186
|
"""Get memories filtered by type or tags."""
|
|
175
187
|
result = self.memories
|
|
176
|
-
|
|
188
|
+
|
|
177
189
|
if type:
|
|
178
190
|
result = [m for m in result if m.type == type]
|
|
179
|
-
|
|
191
|
+
|
|
180
192
|
if tags:
|
|
181
193
|
result = [m for m in result if any(tag in m.tags for tag in tags)]
|
|
182
|
-
|
|
194
|
+
|
|
183
195
|
# Sort by priority and creation date
|
|
184
196
|
result.sort(key=lambda m: (-m.priority, m.created_at), reverse=True)
|
|
185
|
-
|
|
197
|
+
|
|
186
198
|
return result
|
|
187
|
-
|
|
199
|
+
|
|
188
200
|
def get_context_string(self, max_tokens: int = 2000) -> str:
|
|
189
201
|
"""Get a formatted context string for AI prompts."""
|
|
190
202
|
# Sort memories by priority
|
|
191
203
|
sorted_memories = sorted(self.memories, key=lambda m: -m.priority)
|
|
192
|
-
|
|
204
|
+
|
|
193
205
|
context_parts = []
|
|
194
206
|
token_count = 0
|
|
195
|
-
|
|
207
|
+
|
|
196
208
|
for memory in sorted_memories:
|
|
197
209
|
# Rough token estimation (4 chars = 1 token)
|
|
198
210
|
memory_tokens = len(memory.content) // 4
|
|
199
|
-
|
|
211
|
+
|
|
200
212
|
if token_count + memory_tokens > max_tokens:
|
|
201
213
|
break
|
|
202
|
-
|
|
214
|
+
|
|
203
215
|
if memory.type == "instruction":
|
|
204
216
|
context_parts.append(f"INSTRUCTION: {memory.content}")
|
|
205
217
|
elif memory.type == "fact":
|
|
@@ -208,101 +220,99 @@ class MemoryManager:
|
|
|
208
220
|
context_parts.append(f"CODE CONTEXT:\n{memory.content}")
|
|
209
221
|
else:
|
|
210
222
|
context_parts.append(memory.content)
|
|
211
|
-
|
|
223
|
+
|
|
212
224
|
token_count += memory_tokens
|
|
213
|
-
|
|
225
|
+
|
|
214
226
|
return "\n\n".join(context_parts)
|
|
215
|
-
|
|
227
|
+
|
|
216
228
|
def add_message(self, role: str, content: str):
|
|
217
229
|
"""Add a message to session history."""
|
|
218
|
-
self.session_context[
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
})
|
|
223
|
-
|
|
230
|
+
self.session_context["messages"].append(
|
|
231
|
+
{"role": role, "content": content, "timestamp": datetime.now().isoformat()}
|
|
232
|
+
)
|
|
233
|
+
|
|
224
234
|
# Keep only last 50 messages
|
|
225
|
-
if len(self.session_context[
|
|
226
|
-
self.session_context[
|
|
227
|
-
|
|
235
|
+
if len(self.session_context["messages"]) > 50:
|
|
236
|
+
self.session_context["messages"] = self.session_context["messages"][-50:]
|
|
237
|
+
|
|
228
238
|
self.save_session()
|
|
229
|
-
|
|
239
|
+
|
|
230
240
|
def get_recent_messages(self, count: int = 10) -> List[Dict]:
|
|
231
241
|
"""Get recent messages from session."""
|
|
232
|
-
return self.session_context[
|
|
233
|
-
|
|
242
|
+
return self.session_context["messages"][-count:]
|
|
243
|
+
|
|
234
244
|
def set_preference(self, key: str, value: Any):
|
|
235
245
|
"""Set a user preference."""
|
|
236
|
-
self.session_context[
|
|
246
|
+
self.session_context["preferences"][key] = value
|
|
237
247
|
self.save_session()
|
|
238
|
-
|
|
248
|
+
|
|
239
249
|
def get_preference(self, key: str, default: Any = None) -> Any:
|
|
240
250
|
"""Get a user preference."""
|
|
241
|
-
return self.session_context[
|
|
242
|
-
|
|
251
|
+
return self.session_context["preferences"].get(key, default)
|
|
252
|
+
|
|
243
253
|
def _generate_id(self, content: str) -> str:
|
|
244
254
|
"""Generate a unique ID for a memory item."""
|
|
245
255
|
hash_input = f"{content}{datetime.now().isoformat()}"
|
|
246
256
|
return hashlib.md5(hash_input.encode()).hexdigest()[:8]
|
|
247
|
-
|
|
257
|
+
|
|
248
258
|
def summarize_for_ai(self) -> str:
|
|
249
259
|
"""Create a summary suitable for AI context."""
|
|
250
260
|
summary = []
|
|
251
|
-
|
|
261
|
+
|
|
252
262
|
# Add system memories
|
|
253
263
|
system_memories = self.get_memories(tags=["system"])
|
|
254
264
|
if system_memories:
|
|
255
265
|
summary.append("SYSTEM CONTEXT:")
|
|
256
266
|
for mem in system_memories[:3]: # Top 3 system memories
|
|
257
267
|
summary.append(f"- {mem.content}")
|
|
258
|
-
|
|
268
|
+
|
|
259
269
|
# Add recent instructions
|
|
260
270
|
instructions = self.get_memories(type="instruction")
|
|
261
271
|
if instructions:
|
|
262
272
|
summary.append("\nINSTRUCTIONS:")
|
|
263
273
|
for mem in instructions[:3]: # Top 3 instructions
|
|
264
274
|
summary.append(f"- {mem.content}")
|
|
265
|
-
|
|
275
|
+
|
|
266
276
|
# Add important facts
|
|
267
277
|
facts = self.get_memories(type="fact")
|
|
268
278
|
if facts:
|
|
269
279
|
summary.append("\nKEY FACTS:")
|
|
270
280
|
for mem in facts[:5]: # Top 5 facts
|
|
271
281
|
summary.append(f"- {mem.content}")
|
|
272
|
-
|
|
282
|
+
|
|
273
283
|
# Add current task if set
|
|
274
|
-
if self.session_context.get(
|
|
284
|
+
if self.session_context.get("current_task"):
|
|
275
285
|
summary.append(f"\nCURRENT TASK: {self.session_context['current_task']}")
|
|
276
|
-
|
|
286
|
+
|
|
277
287
|
return "\n".join(summary)
|
|
278
|
-
|
|
288
|
+
|
|
279
289
|
def export_memories(self, file_path: str):
|
|
280
290
|
"""Export memories to a file."""
|
|
281
291
|
data = {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
292
|
+
"memories": [m.to_dict() for m in self.memories],
|
|
293
|
+
"session": self.session_context,
|
|
294
|
+
"exported_at": datetime.now().isoformat(),
|
|
285
295
|
}
|
|
286
|
-
|
|
287
|
-
with open(file_path,
|
|
296
|
+
|
|
297
|
+
with open(file_path, "w") as f:
|
|
288
298
|
json.dump(data, f, indent=2)
|
|
289
|
-
|
|
299
|
+
|
|
290
300
|
def import_memories(self, file_path: str):
|
|
291
301
|
"""Import memories from a file."""
|
|
292
|
-
with open(file_path,
|
|
302
|
+
with open(file_path, "r") as f:
|
|
293
303
|
data = json.load(f)
|
|
294
|
-
|
|
304
|
+
|
|
295
305
|
# Merge memories (avoid duplicates)
|
|
296
306
|
existing_ids = {m.id for m in self.memories}
|
|
297
|
-
|
|
298
|
-
for mem_data in data.get(
|
|
299
|
-
if mem_data[
|
|
307
|
+
|
|
308
|
+
for mem_data in data.get("memories", []):
|
|
309
|
+
if mem_data["id"] not in existing_ids:
|
|
300
310
|
self.memories.append(MemoryItem.from_dict(mem_data))
|
|
301
|
-
|
|
311
|
+
|
|
302
312
|
# Merge session preferences
|
|
303
|
-
if
|
|
304
|
-
self.session_context[
|
|
305
|
-
|
|
313
|
+
if "session" in data and "preferences" in data["session"]:
|
|
314
|
+
self.session_context["preferences"].update(data["session"]["preferences"])
|
|
315
|
+
|
|
306
316
|
self.save_memories()
|
|
307
317
|
self.save_session()
|
|
308
318
|
|
|
@@ -312,85 +322,86 @@ def handle_memory_command(command: str, memory_manager: MemoryManager, console)
|
|
|
312
322
|
Handle #memory commands.
|
|
313
323
|
Returns True if command was handled, False otherwise.
|
|
314
324
|
"""
|
|
315
|
-
from rich.table import Table
|
|
316
325
|
from rich.panel import Panel
|
|
317
|
-
|
|
326
|
+
from rich.table import Table
|
|
327
|
+
|
|
318
328
|
parts = command.strip().split(maxsplit=2)
|
|
319
|
-
|
|
329
|
+
|
|
320
330
|
if len(parts) == 1 or parts[1] == "show":
|
|
321
331
|
# Show current memories
|
|
322
332
|
memories = memory_manager.get_memories()
|
|
323
|
-
|
|
333
|
+
|
|
324
334
|
if not memories:
|
|
325
335
|
console.print("[yellow]No memories stored.[/yellow]")
|
|
326
336
|
return True
|
|
327
|
-
|
|
328
|
-
table = Table(
|
|
329
|
-
|
|
337
|
+
|
|
338
|
+
table = Table(
|
|
339
|
+
title="Current Memories", show_header=True, header_style="bold magenta"
|
|
340
|
+
)
|
|
330
341
|
table.add_column("ID", style="cyan", width=10)
|
|
331
342
|
table.add_column("Type", width=12)
|
|
332
343
|
table.add_column("Content", width=50)
|
|
333
344
|
table.add_column("Priority", width=8)
|
|
334
|
-
|
|
345
|
+
|
|
335
346
|
for mem in memories[:10]: # Show top 10
|
|
336
347
|
content = mem.content[:47] + "..." if len(mem.content) > 50 else mem.content
|
|
337
348
|
table.add_row(mem.id, mem.type, content, str(mem.priority))
|
|
338
|
-
|
|
349
|
+
|
|
339
350
|
console.print(table)
|
|
340
|
-
|
|
351
|
+
|
|
341
352
|
if len(memories) > 10:
|
|
342
353
|
console.print(f"[dim]... and {len(memories) - 10} more[/dim]")
|
|
343
|
-
|
|
354
|
+
|
|
344
355
|
return True
|
|
345
|
-
|
|
356
|
+
|
|
346
357
|
elif parts[1] == "add":
|
|
347
358
|
if len(parts) < 3:
|
|
348
359
|
console.print("[red]Usage: #memory add <content>[/red]")
|
|
349
360
|
return True
|
|
350
|
-
|
|
361
|
+
|
|
351
362
|
content = parts[2]
|
|
352
363
|
memory_id = memory_manager.add_memory(content, type="context")
|
|
353
364
|
console.print(f"[green]Added memory: {memory_id}[/green]")
|
|
354
365
|
return True
|
|
355
|
-
|
|
366
|
+
|
|
356
367
|
elif parts[1] == "remove":
|
|
357
368
|
if len(parts) < 3:
|
|
358
369
|
console.print("[red]Usage: #memory remove <id>[/red]")
|
|
359
370
|
return True
|
|
360
|
-
|
|
371
|
+
|
|
361
372
|
memory_id = parts[2]
|
|
362
373
|
if memory_manager.remove_memory(memory_id):
|
|
363
374
|
console.print(f"[green]Removed memory: {memory_id}[/green]")
|
|
364
375
|
else:
|
|
365
376
|
console.print(f"[red]Memory not found: {memory_id}[/red]")
|
|
366
377
|
return True
|
|
367
|
-
|
|
378
|
+
|
|
368
379
|
elif parts[1] == "clear":
|
|
369
380
|
memory_manager.clear_memories(keep_system=True)
|
|
370
381
|
console.print("[green]Cleared all non-system memories.[/green]")
|
|
371
382
|
return True
|
|
372
|
-
|
|
383
|
+
|
|
373
384
|
elif parts[1] == "save":
|
|
374
385
|
memory_manager.save_memories()
|
|
375
386
|
memory_manager.save_session()
|
|
376
387
|
console.print("[green]Memories saved.[/green]")
|
|
377
388
|
return True
|
|
378
|
-
|
|
389
|
+
|
|
379
390
|
elif parts[1] == "export":
|
|
380
391
|
if len(parts) < 3:
|
|
381
392
|
file_path = "hanzo_memories.json"
|
|
382
393
|
else:
|
|
383
394
|
file_path = parts[2]
|
|
384
|
-
|
|
395
|
+
|
|
385
396
|
memory_manager.export_memories(file_path)
|
|
386
397
|
console.print(f"[green]Exported memories to {file_path}[/green]")
|
|
387
398
|
return True
|
|
388
|
-
|
|
399
|
+
|
|
389
400
|
elif parts[1] == "import":
|
|
390
401
|
if len(parts) < 3:
|
|
391
402
|
console.print("[red]Usage: #memory import <file_path>[/red]")
|
|
392
403
|
return True
|
|
393
|
-
|
|
404
|
+
|
|
394
405
|
file_path = parts[2]
|
|
395
406
|
try:
|
|
396
407
|
memory_manager.import_memories(file_path)
|
|
@@ -398,14 +409,20 @@ def handle_memory_command(command: str, memory_manager: MemoryManager, console)
|
|
|
398
409
|
except Exception as e:
|
|
399
410
|
console.print(f"[red]Error importing: {e}[/red]")
|
|
400
411
|
return True
|
|
401
|
-
|
|
412
|
+
|
|
402
413
|
elif parts[1] == "context":
|
|
403
414
|
# Show AI context
|
|
404
415
|
context = memory_manager.summarize_for_ai()
|
|
405
|
-
console.print(
|
|
406
|
-
|
|
416
|
+
console.print(
|
|
417
|
+
Panel(
|
|
418
|
+
context,
|
|
419
|
+
title="[bold cyan]AI Context[/bold cyan]",
|
|
420
|
+
title_align="left",
|
|
421
|
+
border_style="dim cyan",
|
|
422
|
+
)
|
|
423
|
+
)
|
|
407
424
|
return True
|
|
408
|
-
|
|
425
|
+
|
|
409
426
|
elif parts[1] == "help":
|
|
410
427
|
help_text = """Memory Commands:
|
|
411
428
|
#memory [show] - Show current memories
|
|
@@ -417,9 +434,15 @@ def handle_memory_command(command: str, memory_manager: MemoryManager, console)
|
|
|
417
434
|
#memory import <file> - Import memories from file
|
|
418
435
|
#memory context - Show AI context summary
|
|
419
436
|
#memory help - Show this help"""
|
|
420
|
-
|
|
421
|
-
console.print(
|
|
422
|
-
|
|
437
|
+
|
|
438
|
+
console.print(
|
|
439
|
+
Panel(
|
|
440
|
+
help_text,
|
|
441
|
+
title="[bold cyan]Memory Help[/bold cyan]",
|
|
442
|
+
title_align="left",
|
|
443
|
+
border_style="dim cyan",
|
|
444
|
+
)
|
|
445
|
+
)
|
|
423
446
|
return True
|
|
424
|
-
|
|
425
|
-
return False
|
|
447
|
+
|
|
448
|
+
return False
|