-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpersistence.py
More file actions
258 lines (205 loc) Β· 9.37 KB
/
Copy pathpersistence.py
File metadata and controls
258 lines (205 loc) Β· 9.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
"""
Persistence layer for saving/loading evolved DSL functions
"""
import json
import pickle
import os
from typing import Dict, Any, List
from dataclasses import asdict
import importlib.util
from dsl import DSL, DSLFunction, DSLType
class DSLPersistence:
"""Handle saving and loading DSL state"""
def __init__(self, storage_dir: str = "dsl_storage"):
self.storage_dir = storage_dir
os.makedirs(storage_dir, exist_ok=True)
def save_dsl(self, dsl: DSL, name: str = "current_dsl") -> str:
"""Save DSL to disk"""
filepath = os.path.join(self.storage_dir, f"{name}.json")
# Serialize DSL functions (without implementation objects)
dsl_data = {
"functions": {},
"metadata": {
"total_functions": len(dsl.functions),
"primitive_count": 0,
"evolved_count": 0
}
}
for name, func in dsl.functions.items():
# Check if it's a primitive (has implementation but no body)
is_primitive = func.implementation is not None and func.body is None
dsl_data["functions"][name] = {
"name": func.name,
"params": func.params,
"param_types": [t.value for t in func.param_types],
"return_type": func.return_type.value,
"body": func.body,
"fitness_score": func.fitness_score,
"usage_count": func.usage_count,
"is_primitive": is_primitive
}
if is_primitive:
dsl_data["metadata"]["primitive_count"] += 1
else:
dsl_data["metadata"]["evolved_count"] += 1
with open(filepath, 'w') as f:
json.dump(dsl_data, f, indent=2)
print(f"πΎ DSL saved to {filepath}")
return filepath
def load_dsl(self, name: str = "current_dsl") -> DSL:
"""Load DSL from disk"""
filepath = os.path.join(self.storage_dir, f"{name}.json")
if not os.path.exists(filepath):
print(f"β DSL file {filepath} not found, creating new DSL")
return DSL()
with open(filepath, 'r') as f:
dsl_data = json.load(f)
# Create new DSL (this initializes primitives)
dsl = DSL()
# Add evolved functions (non-primitives)
for func_name, func_data in dsl_data["functions"].items():
if not func_data.get("is_primitive", False):
# Reconstruct DSL function
param_types = [DSLType(t) for t in func_data["param_types"]]
return_type = DSLType(func_data["return_type"])
evolved_func = DSLFunction(
name=func_data["name"],
params=func_data["params"],
param_types=param_types,
return_type=return_type,
body=func_data["body"],
fitness_score=func_data["fitness_score"],
usage_count=func_data["usage_count"]
)
# Try to reconstruct implementation from body
if func_data["body"]:
try:
evolved_func.implementation = self._create_implementation(
evolved_func, dsl
)
except Exception as e:
print(f"β οΈ Could not reconstruct implementation for {func_name}: {e}")
dsl.add_function(evolved_func)
print(f"π DSL loaded from {filepath}")
print(f" Primitives: {dsl_data['metadata']['primitive_count']}")
print(f" Evolved: {dsl_data['metadata']['evolved_count']}")
return dsl
def _create_implementation(self, func: DSLFunction, dsl: DSL):
"""Recreate function implementation from code body"""
if not func.body:
return None
# Create namespace with DSL functions
namespace = {"__builtins__": {}}
namespace.update({name: f for name, f in dsl.functions.items()})
# Execute the function definition
exec(func.body, namespace)
# Return the function object
return namespace[func.name]
def export_to_python(self, dsl: DSL, filename: str = None) -> str:
"""Export evolved functions as standalone Python code"""
if filename is None:
filename = os.path.join(self.storage_dir, "evolved_functions.py")
code_lines = [
"# Automatically generated evolved functions",
"# Generated by MCTS + Evolution Coding Agent",
"",
"# Primitive functions (manually implemented)",
]
# Add primitive function implementations
primitives = {
"add": "def add(x, y): return x + y",
"sub": "def sub(x, y): return x - y",
"mul": "def mul(x, y): return x * y",
"div": "def div(x, y): return x // y if y != 0 else 0",
"eq": "def eq(x, y): return x == y",
"lt": "def lt(x, y): return x < y",
"gt": "def gt(x, y): return x > y",
"if_then_else": "def if_then_else(cond, then_val, else_val): return then_val if cond else else_val",
"identity": "def identity(x): return x"
}
for name, implementation in primitives.items():
code_lines.append(implementation)
code_lines.extend(["", "# Evolved functions"])
# Add evolved functions
for name, func in dsl.functions.items():
if func.body and name not in primitives:
code_lines.append("")
code_lines.append(f"# Fitness: {func.fitness_score:.3f}")
code_lines.append(func.body)
# Write to file
with open(filename, 'w') as f:
f.write('\n'.join(code_lines))
print(f"π Python code exported to {filename}")
return filename
def list_saved_dsls(self) -> List[str]:
"""List all saved DSL files"""
json_files = [f[:-5] for f in os.listdir(self.storage_dir)
if f.endswith('.json')]
return json_files
def backup_dsl(self, dsl: DSL, cycle_id: int) -> str:
"""Create a backup of DSL after each cycle"""
backup_name = f"dsl_cycle_{cycle_id}"
return self.save_dsl(dsl, backup_name)
class SessionManager:
"""Manage DSL evolution sessions"""
def __init__(self, session_name: str = "default"):
self.session_name = session_name
self.persistence = DSLPersistence(f"sessions/{session_name}")
self.session_log = []
def start_session(self, resume: bool = True) -> DSL:
"""Start or resume a session"""
if resume:
dsl = self.persistence.load_dsl("latest")
print(f"π Resumed session '{self.session_name}'")
else:
dsl = DSL()
print(f"π Started new session '{self.session_name}'")
return dsl
def save_cycle(self, dsl: DSL, cycle_id: int, summary: Dict[str, Any]):
"""Save DSL state and cycle summary"""
# Save DSL
self.persistence.save_dsl(dsl, "latest")
self.persistence.backup_dsl(dsl, cycle_id)
# Log cycle summary
self.session_log.append({
"cycle_id": cycle_id,
"timestamp": summary.get("timestamp"),
"functions_added": summary.get("new_functions", 0),
"total_functions": len(dsl.functions),
"best_fitness": summary.get("best_fitness", 0.0)
})
# Save session log
log_file = os.path.join(self.persistence.storage_dir, "session_log.json")
with open(log_file, 'w') as f:
json.dump(self.session_log, f, indent=2)
print(f"πΎ Cycle {cycle_id} saved to session '{self.session_name}'")
def get_session_summary(self) -> Dict[str, Any]:
"""Get summary of current session"""
if not self.session_log:
return {"cycles": 0, "total_functions": 0}
latest = self.session_log[-1]
return {
"session_name": self.session_name,
"cycles_completed": len(self.session_log),
"total_functions": latest["total_functions"],
"best_fitness_achieved": max(log["best_fitness"] for log in self.session_log),
"functions_discovered": sum(log["functions_added"] for log in self.session_log)
}
# Example usage integration
def create_persistent_system(session_name: str = "my_evolution"):
"""Create a bootstrap system with persistence"""
# Create session manager
session = SessionManager(session_name)
# Load or create DSL
dsl = session.start_session(resume=True)
return session, dsl
# Usage in main system
def persistent_bootstrap_cycle(session: SessionManager, dsl: DSL, cycle_id: int):
"""Run bootstrap cycle with automatic saving"""
from mcts_gpt4o import GPT4BootstrapSystem
# Run cycle
system = GPT4BootstrapSystem(initial_dsl=dsl)
summary = system.run_bootstrap_cycle_async(cycle_id=cycle_id)
# Save results
session.save_cycle(dsl, cycle_id, summary)
return summary