synth-ai 0.2.4.dev4__py3-none-any.whl → 0.2.4.dev5__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 (104) hide show
  1. synth_ai/environments/examples/__init__.py +1 -0
  2. synth_ai/environments/examples/crafter_classic/__init__.py +8 -0
  3. synth_ai/environments/examples/crafter_classic/config_logging.py +111 -0
  4. synth_ai/environments/examples/crafter_classic/debug_translation.py +0 -0
  5. synth_ai/environments/examples/crafter_classic/engine.py +575 -0
  6. synth_ai/environments/examples/crafter_classic/engine_deterministic_patch.py +63 -0
  7. synth_ai/environments/examples/crafter_classic/engine_helpers/action_map.py +5 -0
  8. synth_ai/environments/examples/crafter_classic/engine_helpers/serialization.py +74 -0
  9. synth_ai/environments/examples/crafter_classic/engine_serialization_patch_v3.py +266 -0
  10. synth_ai/environments/examples/crafter_classic/environment.py +364 -0
  11. synth_ai/environments/examples/crafter_classic/taskset.py +233 -0
  12. synth_ai/environments/examples/crafter_classic/trace_hooks_v3.py +229 -0
  13. synth_ai/environments/examples/crafter_classic/world_config_patch_simple.py +298 -0
  14. synth_ai/environments/examples/crafter_custom/__init__.py +4 -0
  15. synth_ai/environments/examples/crafter_custom/crafter/__init__.py +7 -0
  16. synth_ai/environments/examples/crafter_custom/crafter/config.py +182 -0
  17. synth_ai/environments/examples/crafter_custom/crafter/constants.py +8 -0
  18. synth_ai/environments/examples/crafter_custom/crafter/engine.py +269 -0
  19. synth_ai/environments/examples/crafter_custom/crafter/env.py +266 -0
  20. synth_ai/environments/examples/crafter_custom/crafter/objects.py +418 -0
  21. synth_ai/environments/examples/crafter_custom/crafter/recorder.py +187 -0
  22. synth_ai/environments/examples/crafter_custom/crafter/worldgen.py +119 -0
  23. synth_ai/environments/examples/crafter_custom/dataset_builder.py +373 -0
  24. synth_ai/environments/examples/crafter_custom/environment.py +312 -0
  25. synth_ai/environments/examples/crafter_custom/run_dataset.py +305 -0
  26. synth_ai/environments/examples/enron/art_helpers/email_search_tools.py +156 -0
  27. synth_ai/environments/examples/enron/art_helpers/local_email_db.py +280 -0
  28. synth_ai/environments/examples/enron/art_helpers/types_enron.py +24 -0
  29. synth_ai/environments/examples/enron/engine.py +291 -0
  30. synth_ai/environments/examples/enron/environment.py +165 -0
  31. synth_ai/environments/examples/enron/taskset.py +112 -0
  32. synth_ai/environments/examples/minigrid/__init__.py +48 -0
  33. synth_ai/environments/examples/minigrid/engine.py +589 -0
  34. synth_ai/environments/examples/minigrid/environment.py +274 -0
  35. synth_ai/environments/examples/minigrid/environment_mapping.py +242 -0
  36. synth_ai/environments/examples/minigrid/puzzle_loader.py +416 -0
  37. synth_ai/environments/examples/minigrid/taskset.py +583 -0
  38. synth_ai/environments/examples/nethack/__init__.py +7 -0
  39. synth_ai/environments/examples/nethack/achievements.py +337 -0
  40. synth_ai/environments/examples/nethack/engine.py +738 -0
  41. synth_ai/environments/examples/nethack/environment.py +255 -0
  42. synth_ai/environments/examples/nethack/helpers/__init__.py +42 -0
  43. synth_ai/environments/examples/nethack/helpers/action_mapping.py +301 -0
  44. synth_ai/environments/examples/nethack/helpers/nle_wrapper.py +401 -0
  45. synth_ai/environments/examples/nethack/helpers/observation_utils.py +433 -0
  46. synth_ai/environments/examples/nethack/helpers/recording_wrapper.py +201 -0
  47. synth_ai/environments/examples/nethack/helpers/trajectory_recorder.py +268 -0
  48. synth_ai/environments/examples/nethack/helpers/visualization/replay_viewer.py +308 -0
  49. synth_ai/environments/examples/nethack/helpers/visualization/visualizer.py +430 -0
  50. synth_ai/environments/examples/nethack/taskset.py +323 -0
  51. synth_ai/environments/examples/red/__init__.py +7 -0
  52. synth_ai/environments/examples/red/config_logging.py +110 -0
  53. synth_ai/environments/examples/red/engine.py +693 -0
  54. synth_ai/environments/examples/red/engine_helpers/__init__.py +1 -0
  55. synth_ai/environments/examples/red/engine_helpers/memory_map.py +28 -0
  56. synth_ai/environments/examples/red/engine_helpers/reward_components.py +275 -0
  57. synth_ai/environments/examples/red/engine_helpers/reward_library/__init__.py +142 -0
  58. synth_ai/environments/examples/red/engine_helpers/reward_library/adaptive_rewards.py +56 -0
  59. synth_ai/environments/examples/red/engine_helpers/reward_library/battle_rewards.py +283 -0
  60. synth_ai/environments/examples/red/engine_helpers/reward_library/composite_rewards.py +149 -0
  61. synth_ai/environments/examples/red/engine_helpers/reward_library/economy_rewards.py +137 -0
  62. synth_ai/environments/examples/red/engine_helpers/reward_library/efficiency_rewards.py +56 -0
  63. synth_ai/environments/examples/red/engine_helpers/reward_library/exploration_rewards.py +330 -0
  64. synth_ai/environments/examples/red/engine_helpers/reward_library/novelty_rewards.py +120 -0
  65. synth_ai/environments/examples/red/engine_helpers/reward_library/pallet_town_rewards.py +558 -0
  66. synth_ai/environments/examples/red/engine_helpers/reward_library/pokemon_rewards.py +312 -0
  67. synth_ai/environments/examples/red/engine_helpers/reward_library/social_rewards.py +147 -0
  68. synth_ai/environments/examples/red/engine_helpers/reward_library/story_rewards.py +246 -0
  69. synth_ai/environments/examples/red/engine_helpers/screen_analysis.py +367 -0
  70. synth_ai/environments/examples/red/engine_helpers/state_extraction.py +139 -0
  71. synth_ai/environments/examples/red/environment.py +235 -0
  72. synth_ai/environments/examples/red/taskset.py +77 -0
  73. synth_ai/environments/examples/sokoban/__init__.py +1 -0
  74. synth_ai/environments/examples/sokoban/engine.py +675 -0
  75. synth_ai/environments/examples/sokoban/engine_helpers/__init__.py +1 -0
  76. synth_ai/environments/examples/sokoban/engine_helpers/room_utils.py +656 -0
  77. synth_ai/environments/examples/sokoban/engine_helpers/vendored/__init__.py +17 -0
  78. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/__init__.py +3 -0
  79. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/boxoban_env.py +129 -0
  80. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/render_utils.py +370 -0
  81. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/room_utils.py +331 -0
  82. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env.py +305 -0
  83. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_fixed_targets.py +66 -0
  84. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_pull.py +114 -0
  85. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_two_player.py +122 -0
  86. synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_variations.py +394 -0
  87. synth_ai/environments/examples/sokoban/environment.py +228 -0
  88. synth_ai/environments/examples/sokoban/generate_verified_puzzles.py +438 -0
  89. synth_ai/environments/examples/sokoban/puzzle_loader.py +311 -0
  90. synth_ai/environments/examples/sokoban/taskset.py +425 -0
  91. synth_ai/environments/examples/tictactoe/__init__.py +1 -0
  92. synth_ai/environments/examples/tictactoe/engine.py +368 -0
  93. synth_ai/environments/examples/tictactoe/environment.py +239 -0
  94. synth_ai/environments/examples/tictactoe/taskset.py +214 -0
  95. synth_ai/environments/examples/verilog/__init__.py +10 -0
  96. synth_ai/environments/examples/verilog/engine.py +328 -0
  97. synth_ai/environments/examples/verilog/environment.py +349 -0
  98. synth_ai/environments/examples/verilog/taskset.py +418 -0
  99. {synth_ai-0.2.4.dev4.dist-info → synth_ai-0.2.4.dev5.dist-info}/METADATA +1 -1
  100. {synth_ai-0.2.4.dev4.dist-info → synth_ai-0.2.4.dev5.dist-info}/RECORD +104 -6
  101. {synth_ai-0.2.4.dev4.dist-info → synth_ai-0.2.4.dev5.dist-info}/WHEEL +0 -0
  102. {synth_ai-0.2.4.dev4.dist-info → synth_ai-0.2.4.dev5.dist-info}/entry_points.txt +0 -0
  103. {synth_ai-0.2.4.dev4.dist-info → synth_ai-0.2.4.dev5.dist-info}/licenses/LICENSE +0 -0
  104. {synth_ai-0.2.4.dev4.dist-info → synth_ai-0.2.4.dev5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,418 @@
1
+ from synth_ai.environments.tasks.core import (
2
+ Task,
3
+ TaskInstance,
4
+ TaskInstanceMetadata,
5
+ TaskInstanceSet,
6
+ SplitInfo,
7
+ Impetus,
8
+ Intent,
9
+ )
10
+ from uuid import uuid4, UUID
11
+ from dataclasses import dataclass, asdict, fields
12
+ from typing import Optional
13
+ from pathlib import Path
14
+ import tempfile
15
+ import os
16
+ import shutil
17
+ import atexit
18
+ from datasets import load_dataset
19
+
20
+ # Global list to track temp directories for cleanup
21
+ _temp_dirs = []
22
+
23
+
24
+ def _cleanup_temp_dirs():
25
+ """Clean up all temporary directories created during task instances."""
26
+ for temp_dir in _temp_dirs:
27
+ try:
28
+ if os.path.exists(temp_dir):
29
+ shutil.rmtree(temp_dir)
30
+ except Exception:
31
+ pass # Ignore cleanup errors
32
+ _temp_dirs.clear()
33
+
34
+
35
+ # Register cleanup function to run at exit
36
+ atexit.register(_cleanup_temp_dirs)
37
+
38
+ verilog_task = Task(
39
+ global_premises="Implement and verify Verilog hardware designs",
40
+ global_constraints="Must pass testbench verification",
41
+ global_objectives="Write correct Verilog code that passes all tests",
42
+ shared_env_params={},
43
+ )
44
+
45
+
46
+ @dataclass
47
+ class VerilogTaskInstanceMetadata(TaskInstanceMetadata):
48
+ problem_name: str
49
+ difficulty: str
50
+ description: str
51
+ files_provided: list[str]
52
+
53
+
54
+ @dataclass
55
+ class VerilogTaskInstance(TaskInstance):
56
+ pristine_dir: Optional[str] = None
57
+ snapshot_dir: Optional[str] = None
58
+
59
+ async def serialize(self) -> dict:
60
+ data = asdict(self)
61
+ if "id" in data and isinstance(data["id"], UUID):
62
+ data["id"] = str(data["id"])
63
+ if "intent" in data and data["intent"] is not None:
64
+ if "deterministic_eval_functions" in data["intent"]:
65
+ data["intent"]["deterministic_eval_functions"] = []
66
+ return data
67
+
68
+ @classmethod
69
+ async def deserialize(cls, data: dict) -> "VerilogTaskInstance":
70
+ """Gracefully accept non-UUID ids and rebuild required objects."""
71
+ if "id" in data:
72
+ try:
73
+ data["id"] = UUID(str(data["id"]))
74
+ except (ValueError, TypeError, AttributeError):
75
+ pass # keep original string
76
+
77
+ if "impetus" in data and isinstance(data["impetus"], dict):
78
+ impetus_data = data["impetus"]
79
+ # Ensure instructions field exists with default if missing
80
+ if "instructions" not in impetus_data:
81
+ impetus_data["instructions"] = "Implement the Verilog module"
82
+ data["impetus"] = Impetus(**impetus_data)
83
+
84
+ if "intent" in data and isinstance(data["intent"], dict):
85
+ intent_data = data["intent"]
86
+ if "deterministic_eval_functions" not in intent_data:
87
+ intent_data["deterministic_eval_functions"] = []
88
+ # Provide default values for required fields if missing
89
+ if "rubric" not in intent_data:
90
+ intent_data["rubric"] = {"goal": "Pass all testbench tests"}
91
+ if "gold_trajectories" not in intent_data:
92
+ intent_data["gold_trajectories"] = None
93
+ if "gold_state_diff" not in intent_data:
94
+ intent_data["gold_state_diff"] = {}
95
+ data["intent"] = Intent(**intent_data)
96
+
97
+ if "metadata" in data and isinstance(data["metadata"], dict):
98
+ metadata_data = data["metadata"]
99
+ # Ensure required fields exist with defaults if missing
100
+ if "problem_name" not in metadata_data:
101
+ metadata_data["problem_name"] = "unknown"
102
+ if "difficulty" not in metadata_data:
103
+ metadata_data["difficulty"] = "medium"
104
+ if "description" not in metadata_data:
105
+ metadata_data["description"] = "Verilog implementation task"
106
+ if "files_provided" not in metadata_data:
107
+ metadata_data["files_provided"] = []
108
+ data["metadata"] = VerilogTaskInstanceMetadata(**metadata_data)
109
+
110
+ constructor_field_names = {f.name for f in fields(cls)}
111
+ filtered_data = {k: v for k, v in data.items() if k in constructor_field_names}
112
+
113
+ # Add default values for required fields if missing
114
+ if "is_reproducible" not in filtered_data:
115
+ filtered_data["is_reproducible"] = True
116
+ if "initial_engine_snapshot" not in filtered_data:
117
+ filtered_data["initial_engine_snapshot"] = None
118
+
119
+ return cls(**filtered_data)
120
+
121
+
122
+ async def create_verilog_taskset(max_instances: int = 10) -> TaskInstanceSet:
123
+ """Create a Verilog task set from HuggingFace VerilogEval v2 dataset."""
124
+ # Load VerilogEval v2 dataset from HuggingFace
125
+ ds = load_dataset("dakies/nvlabs-verilogeval-v2-spec-to-rtl", split="test")
126
+
127
+ instances = []
128
+
129
+ # Limit the number of instances for faster testing
130
+ dataset_size = min(max_instances, len(ds)) # type: ignore[arg-type]
131
+
132
+ # Convert each dataset item to VerilogTaskInstance
133
+ for i in range(dataset_size):
134
+ item = ds[i]
135
+ instance = _create_hf_task_instance(item, i)
136
+ instances.append(instance)
137
+
138
+ # Create split info - use first 80% for validation, last 20% for test
139
+ total_instances = len(instances)
140
+ val_split = int(0.8 * total_instances)
141
+
142
+ val_ids = {inst.id for inst in instances[:val_split]}
143
+ test_ids = {inst.id for inst in instances[val_split:]}
144
+
145
+ split_info = SplitInfo(
146
+ val_instance_ids=val_ids,
147
+ test_instance_ids=test_ids,
148
+ _is_split_defined=True,
149
+ )
150
+
151
+ return TaskInstanceSet(
152
+ name="VerilogEval v2 TaskSet",
153
+ description="VerilogEval v2 spec-to-RTL tasks from HuggingFace",
154
+ instances=instances,
155
+ split_info=split_info,
156
+ )
157
+
158
+
159
+ def _create_hf_task_instance(item, index: int) -> VerilogTaskInstance:
160
+ """Create a VerilogTaskInstance from a HuggingFace dataset item."""
161
+ instance_id = uuid4()
162
+
163
+ # Create temporary directory for this task
164
+ temp_dir = tempfile.mkdtemp(prefix=f"verilog_hf_{index}_{instance_id}_")
165
+ _temp_dirs.append(temp_dir) # Track for cleanup
166
+ pristine_dir = Path(temp_dir)
167
+ pristine_dir.mkdir(exist_ok=True)
168
+
169
+ # Extract information from dataset item
170
+ problem_id = item["problem_id"]
171
+ prompt = item["prompt"]
172
+ testbench = item["test"]
173
+ ref_solution = item["ref"]
174
+
175
+ # Create incomplete module template (TopModule is the expected name in tests)
176
+ module_content = (
177
+ """module TopModule();
178
+ // TODO: Implement the module based on the specification below
179
+ /*
180
+ Specification:
181
+ """
182
+ + prompt.strip()
183
+ + """
184
+ */
185
+ endmodule"""
186
+ )
187
+
188
+ # Write files to pristine directory
189
+ module_file = "TopModule.v"
190
+ testbench_file = f"{problem_id}_tb.v"
191
+ ref_file = "RefModule.v"
192
+
193
+ (pristine_dir / module_file).write_text(module_content)
194
+ (pristine_dir / testbench_file).write_text(testbench)
195
+ (pristine_dir / ref_file).write_text(ref_solution) # Include reference module
196
+
197
+ files_provided = [module_file, testbench_file, ref_file]
198
+
199
+ # Create task components
200
+ impetus = Impetus(
201
+ instructions=f"Problem: {problem_id}\n\n{prompt.strip()}\n\nImplement the TopModule according to the specification. The testbench will verify your implementation."
202
+ )
203
+
204
+ intent = Intent(
205
+ rubric={
206
+ "goal": f"Implement correct TopModule for {problem_id} that passes testbench verification"
207
+ },
208
+ gold_trajectories=None,
209
+ gold_state_diff={},
210
+ )
211
+
212
+ metadata = VerilogTaskInstanceMetadata(
213
+ problem_name=problem_id,
214
+ difficulty="medium", # VerilogEval doesn't specify difficulty levels
215
+ description=prompt.strip(), # Full description
216
+ files_provided=files_provided,
217
+ )
218
+
219
+ # Create snapshot directory and track for cleanup
220
+ snapshot_dir = tempfile.mkdtemp(prefix=f"verilog_snapshot_{instance_id}_")
221
+ _temp_dirs.append(snapshot_dir)
222
+
223
+ return VerilogTaskInstance(
224
+ id=instance_id,
225
+ impetus=impetus,
226
+ intent=intent,
227
+ metadata=metadata,
228
+ is_reproducible=True,
229
+ initial_engine_snapshot=None,
230
+ pristine_dir=str(pristine_dir),
231
+ snapshot_dir=snapshot_dir,
232
+ )
233
+
234
+
235
+ def _create_adder_task() -> VerilogTaskInstance:
236
+ """Create a simple 4-bit adder task."""
237
+ instance_id = uuid4()
238
+
239
+ # Create temporary directory for this task
240
+ temp_dir = tempfile.mkdtemp(prefix=f"verilog_adder_{instance_id}_")
241
+ _temp_dirs.append(temp_dir) # Track for cleanup
242
+
243
+ # Write adder testbench
244
+ adder_tb_content = """`timescale 1ns/1ps
245
+ module adder4_tb;
246
+ reg [3:0] a, b;
247
+ wire [4:0] sum;
248
+
249
+ adder4 dut(.a(a), .b(b), .sum(sum));
250
+
251
+ initial begin
252
+ a = 4'b0000; b = 4'b0000; #10;
253
+ if (sum != 5'b00000) $fatal(1, "Test failed: 0 + 0 != 0");
254
+
255
+ a = 4'b0001; b = 4'b0001; #10;
256
+ if (sum != 5'b00010) $fatal(1, "Test failed: 1 + 1 != 2");
257
+
258
+ a = 4'b1111; b = 4'b0001; #10;
259
+ if (sum != 5'b10000) $fatal(1, "Test failed: 15 + 1 != 16");
260
+
261
+ $display("ALL_TESTS_PASSED");
262
+ $finish;
263
+ end
264
+ endmodule"""
265
+
266
+ # Write incomplete adder module (for student to complete)
267
+ adder_content = """module adder4(
268
+ input [3:0] a,
269
+ input [3:0] b,
270
+ output [4:0] sum
271
+ );
272
+ // TODO: Implement 4-bit adder
273
+ // assign sum = ?;
274
+ endmodule"""
275
+
276
+ pristine_dir = Path(temp_dir)
277
+ pristine_dir.mkdir(exist_ok=True)
278
+
279
+ (pristine_dir / "adder4_tb.v").write_text(adder_tb_content)
280
+ (pristine_dir / "adder4.v").write_text(adder_content)
281
+
282
+ impetus = Impetus(
283
+ instructions="Implement a 4-bit adder module that takes two 4-bit inputs 'a' and 'b' and produces a 5-bit output 'sum'."
284
+ )
285
+
286
+ intent = Intent(
287
+ rubric="Implement correct 4-bit adder that passes testbench",
288
+ gold_trajectories=None,
289
+ gold_state_diff={},
290
+ )
291
+
292
+ metadata = VerilogTaskInstanceMetadata(
293
+ problem_name="adder4",
294
+ difficulty="easy",
295
+ description="4-bit adder implementation",
296
+ files_provided=["adder4.v", "adder4_tb.v"],
297
+ )
298
+
299
+ return VerilogTaskInstance(
300
+ id=instance_id,
301
+ impetus=impetus,
302
+ intent=intent,
303
+ metadata=metadata,
304
+ is_reproducible=True,
305
+ initial_engine_snapshot=None,
306
+ pristine_dir=str(pristine_dir),
307
+ snapshot_dir=(
308
+ lambda: (
309
+ _temp_dirs.append(d := tempfile.mkdtemp(prefix=f"verilog_snapshot_{instance_id}_")),
310
+ d,
311
+ )[1]
312
+ )(),
313
+ )
314
+
315
+
316
+ def _create_and_gate_task() -> VerilogTaskInstance:
317
+ """Create a simple AND gate task."""
318
+ instance_id = uuid4()
319
+
320
+ # Create temporary directory for this task
321
+ temp_dir = tempfile.mkdtemp(prefix=f"verilog_and_{instance_id}_")
322
+ _temp_dirs.append(temp_dir) # Track for cleanup
323
+
324
+ # Write AND gate testbench
325
+ and_tb_content = """`timescale 1ns/1ps
326
+ module and_gate_tb;
327
+ reg a, b;
328
+ wire y;
329
+
330
+ and_gate dut(.a(a), .b(b), .y(y));
331
+
332
+ initial begin
333
+ a = 0; b = 0; #10;
334
+ if (y != 0) $fatal(1, "Test failed: 0 AND 0 != 0");
335
+
336
+ a = 0; b = 1; #10;
337
+ if (y != 0) $fatal(1, "Test failed: 0 AND 1 != 0");
338
+
339
+ a = 1; b = 0; #10;
340
+ if (y != 0) $fatal(1, "Test failed: 1 AND 0 != 0");
341
+
342
+ a = 1; b = 1; #10;
343
+ if (y != 1) $fatal(1, "Test failed: 1 AND 1 != 1");
344
+
345
+ $display("ALL_TESTS_PASSED");
346
+ $finish;
347
+ end
348
+ endmodule"""
349
+
350
+ # Write incomplete AND gate module
351
+ and_content = """module and_gate(
352
+ input a,
353
+ input b,
354
+ output y
355
+ );
356
+ // TODO: Implement AND gate
357
+ // assign y = ?;
358
+ endmodule"""
359
+
360
+ pristine_dir = Path(temp_dir)
361
+ pristine_dir.mkdir(exist_ok=True)
362
+
363
+ (pristine_dir / "and_gate_tb.v").write_text(and_tb_content)
364
+ (pristine_dir / "and_gate.v").write_text(and_content)
365
+
366
+ impetus = Impetus(
367
+ instructions="Implement an AND gate module that takes two inputs 'a' and 'b' and produces output 'y'."
368
+ )
369
+
370
+ intent = Intent(
371
+ rubric="Implement correct AND gate that passes testbench",
372
+ gold_trajectories=None,
373
+ gold_state_diff={},
374
+ )
375
+
376
+ metadata = VerilogTaskInstanceMetadata(
377
+ problem_name="and_gate",
378
+ difficulty="easy",
379
+ description="Basic AND gate implementation",
380
+ files_provided=["and_gate.v", "and_gate_tb.v"],
381
+ )
382
+
383
+ return VerilogTaskInstance(
384
+ id=instance_id,
385
+ impetus=impetus,
386
+ intent=intent,
387
+ metadata=metadata,
388
+ is_reproducible=True,
389
+ initial_engine_snapshot=None,
390
+ pristine_dir=str(pristine_dir),
391
+ snapshot_dir=(
392
+ lambda: (
393
+ _temp_dirs.append(d := tempfile.mkdtemp(prefix=f"verilog_snapshot_{instance_id}_")),
394
+ d,
395
+ )[1]
396
+ )(),
397
+ )
398
+
399
+
400
+ # Example usage
401
+ if __name__ == "__main__":
402
+ import asyncio
403
+
404
+ async def main():
405
+ taskset = await create_verilog_taskset()
406
+
407
+ serialized = await asyncio.gather(*(inst.serialize() for inst in taskset.instances))
408
+
409
+ print(f"Created {len(serialized)} Verilog task instances")
410
+
411
+ # Print summary
412
+ for i, inst in enumerate(taskset.instances):
413
+ print(f"Task {i + 1}: {inst.metadata.problem_name} ({inst.metadata.difficulty})")
414
+ print(f" Description: {inst.metadata.description}")
415
+ print(f" Files: {inst.metadata.files_provided}")
416
+ print()
417
+
418
+ asyncio.run(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-ai
3
- Version: 0.2.4.dev4
3
+ Version: 0.2.4.dev5
4
4
  Summary: Software for aiding the best and multiplying the will - Core AI functionality and tracing
5
5
  Author-email: Synth AI <josh@usesynth.ai>
6
6
  License-Expression: MIT
@@ -29,6 +29,104 @@ synth_ai/environments/environment/resources/sqlite.py,sha256=_kKSF2SUGN1E61Hq7AZ
29
29
  synth_ai/environments/environment/rewards/__init__.py,sha256=5TpSHuCNeRy0W5N55ITVVoAI6oNYre9usbPhFnDrc7I,18
30
30
  synth_ai/environments/environment/rewards/core.py,sha256=NPy6EmpBzeWlEulIvWXh12aJqQ71_X7rqzgVu85myXk,888
31
31
  synth_ai/environments/environment/tools/__init__.py,sha256=hl244E3Zy4RYMtCzz0RPpFTTqYCh0IckRrdN7mGafoc,6910
32
+ synth_ai/environments/examples/__init__.py,sha256=POgz9O4n1tvPAW1rYNUNeQGrMlWxoPDmyht85o5Po0s,38
33
+ synth_ai/environments/examples/crafter_classic/__init__.py,sha256=waICaSbO19tTJpj-BxCURLDxRdx_gnSVQXLIwo4gqLM,270
34
+ synth_ai/environments/examples/crafter_classic/config_logging.py,sha256=Eqq35s0lPAmBiU0neZM6vmHPct15gp9TwS3vogrNziM,3794
35
+ synth_ai/environments/examples/crafter_classic/debug_translation.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ synth_ai/environments/examples/crafter_classic/engine.py,sha256=Nvp3aSd2Qqby6eJOPH1bLXuk-rU6EuUC-HEs8d-D-sY,25046
37
+ synth_ai/environments/examples/crafter_classic/engine_deterministic_patch.py,sha256=Jhn4dtLypG4-eLMsHxesagVTGJtzoGF6UssEfblEJYE,2801
38
+ synth_ai/environments/examples/crafter_classic/engine_serialization_patch_v3.py,sha256=E7EA1IODxeb8Fq6uV15pL5HFuv4q-KTwnmRGqweuM34,11126
39
+ synth_ai/environments/examples/crafter_classic/environment.py,sha256=6Us77M0AhVOrBwZoaZesxC4QXC6q1tmVphga2BZvVv4,17218
40
+ synth_ai/environments/examples/crafter_classic/taskset.py,sha256=Jg3BgGetBjFor6MT3Fsx8BrrNRcS-RsffvusZsmi7v0,9843
41
+ synth_ai/environments/examples/crafter_classic/trace_hooks_v3.py,sha256=OuP_pm565jRIFc4AzzEAa7jrIvm0E4B5EAv6GnQWGzw,7195
42
+ synth_ai/environments/examples/crafter_classic/world_config_patch_simple.py,sha256=hrWo6OweT1Cyrck9YVP4TtxGdHmezbvITRTrhibWieo,10165
43
+ synth_ai/environments/examples/crafter_classic/engine_helpers/action_map.py,sha256=KUf20wX_t-DpU6kxWX6n7iyZxg_zrq7dV5S8Ci-2r18,229
44
+ synth_ai/environments/examples/crafter_classic/engine_helpers/serialization.py,sha256=biLmlrQFsSS4SVAqKilFyR6NjgcNJR1UlTnql98L0a0,2242
45
+ synth_ai/environments/examples/crafter_custom/__init__.py,sha256=139ewayoaO3Oxr-vG-1hxI89urYr1Dsy35JEeJEdvj0,190
46
+ synth_ai/environments/examples/crafter_custom/dataset_builder.py,sha256=QHoP45shr9kFvCjf0ta0aHPuVq9R6rU9MP1ZE1wk4L0,12956
47
+ synth_ai/environments/examples/crafter_custom/environment.py,sha256=9RswjKlVa2NwSELqYuvqxeZnW9O3eOVClMKDmdVV0m0,14784
48
+ synth_ai/environments/examples/crafter_custom/run_dataset.py,sha256=DmyxqebahMcnUDLgTCQdprfHYzFXKho17U6ypbobuQs,9959
49
+ synth_ai/environments/examples/crafter_custom/crafter/__init__.py,sha256=_M8hAShOyx-rd7prlDNGpzWk8BhGKY2l6hQvQ5teECs,235
50
+ synth_ai/environments/examples/crafter_custom/crafter/config.py,sha256=b3EuU7aK9XUIBeEbJiq6Xnt_7D4aYOBg8_hdqKxCxS8,5542
51
+ synth_ai/environments/examples/crafter_custom/crafter/constants.py,sha256=ZAHy89ZCWyLGzP1sQqlHHqGIMuIHqgsYWy7usD3ODB8,218
52
+ synth_ai/environments/examples/crafter_custom/crafter/engine.py,sha256=DFGknXHvOoliVtded7TnDsBrOOSnb79gbTdgpJNQKtE,9479
53
+ synth_ai/environments/examples/crafter_custom/crafter/env.py,sha256=EsYNnypT797f5yH_2FXcd_kQrxO3UA_gsXZ8HX6pSY4,9313
54
+ synth_ai/environments/examples/crafter_custom/crafter/objects.py,sha256=mCMu0ofXBaQIgjVM27eD2IN9IWi7ki6LeYDLnScNctk,13022
55
+ synth_ai/environments/examples/crafter_custom/crafter/recorder.py,sha256=NcqecXkU8S5pJ4vE89KcZPIO8SknkKuV1AookEvQ2Gw,5898
56
+ synth_ai/environments/examples/crafter_custom/crafter/worldgen.py,sha256=ieQMJyoni4Xl6uM_32ekKLk1QdFtJRHz6FR-8nLCwcI,4128
57
+ synth_ai/environments/examples/enron/engine.py,sha256=Unq3mrgit0Y4Y64s9cmiG4wocWyE28iRGGBFjN2IvmA,11534
58
+ synth_ai/environments/examples/enron/environment.py,sha256=QW0dmvv7og31tVnFHrQefZjAoo-yiKkkUUwj8QSd2f4,5985
59
+ synth_ai/environments/examples/enron/taskset.py,sha256=PdCkrPm99lAfRKKwkh6Qg_3LUEHy2AAP3qcvFht8_PI,3171
60
+ synth_ai/environments/examples/enron/art_helpers/email_search_tools.py,sha256=VqUy5pDRHt2qs0G7jwgqN60T7xQJEKRUhWQYsIopqP0,5545
61
+ synth_ai/environments/examples/enron/art_helpers/local_email_db.py,sha256=G0_26Y-6TwDIHcjVrMLJ-4gqQwJowoFB-WkgQhtAlPU,9984
62
+ synth_ai/environments/examples/enron/art_helpers/types_enron.py,sha256=Nxn0yP5aQyRftlsuXvH6_8BxM3Ms14UuD1Pq-UO9uBY,733
63
+ synth_ai/environments/examples/minigrid/__init__.py,sha256=tWQQ9kqbf-eP9RcJtlM_RNR63YkNXAl_U1zPfgP2TWk,1328
64
+ synth_ai/environments/examples/minigrid/engine.py,sha256=gvdc8Wgc8E4SGRhxCtCARgTzMMmtzxZT5Nc68-iI85k,22061
65
+ synth_ai/environments/examples/minigrid/environment.py,sha256=T-65hM-C3vqncmaLYzemNTwY7akDkRHiCKk3Dhiu9sQ,10490
66
+ synth_ai/environments/examples/minigrid/environment_mapping.py,sha256=N0JJ4Ako-sX-89nE9vCbPQIzVuhGpyy309Y_y7osNiA,7019
67
+ synth_ai/environments/examples/minigrid/puzzle_loader.py,sha256=Kc2KRBQr2wo1Lq3xhTASXFo1-j9ZgysY7imQ8uNz0zE,14655
68
+ synth_ai/environments/examples/minigrid/taskset.py,sha256=_ekomoTujsRbur60GvWSwWmABmZCp5k7f_JBDwJGmYk,21305
69
+ synth_ai/environments/examples/nethack/__init__.py,sha256=viygo8pTUB891fGm_tb38s5thNcr17bLFffQdDOfiQ0,266
70
+ synth_ai/environments/examples/nethack/achievements.py,sha256=hSDld5CBHubzmrDy2kZcfVDxQtymfg3kjQr0WuPH-Ro,12443
71
+ synth_ai/environments/examples/nethack/engine.py,sha256=e4F1bBoCbcvJwiHOGCCB5Ogwk_ARYHXiO3WC7tQAI-o,29956
72
+ synth_ai/environments/examples/nethack/environment.py,sha256=5ez7AJiKdnwe4cekTSTEh1Y5I1ZtPrDtCa6VeH_6pIY,10041
73
+ synth_ai/environments/examples/nethack/taskset.py,sha256=aPuleNGageiPhSXfNV-bzdmyPMi6gQSU40BAd8eT-a0,11339
74
+ synth_ai/environments/examples/nethack/helpers/__init__.py,sha256=7U8i1NKNIMC2eFKU5aOKYnUHbQCBTkoEZe-prFhAZOw,959
75
+ synth_ai/environments/examples/nethack/helpers/action_mapping.py,sha256=AZwkDY9-VEblagnpFrrnzlmNyRumWsDEf4w35y5Csmg,9133
76
+ synth_ai/environments/examples/nethack/helpers/nle_wrapper.py,sha256=dhyBFbHVHVslSm_4ztELLEURNt-iky0OOer2DEM7J8A,15141
77
+ synth_ai/environments/examples/nethack/helpers/observation_utils.py,sha256=XIHK6gtroNfeiLc8aisj7rDvcxROYiIpHKSCoJoWypU,12350
78
+ synth_ai/environments/examples/nethack/helpers/recording_wrapper.py,sha256=uWxZOgsi0GT29nv5_7zKAm28YCG8ukYCXafeV1kmgow,7448
79
+ synth_ai/environments/examples/nethack/helpers/trajectory_recorder.py,sha256=vzU_ir8zX1AlwcvgliA-HkCqEJJpICFDvAAS_UuP7xY,8987
80
+ synth_ai/environments/examples/nethack/helpers/visualization/replay_viewer.py,sha256=eceK4aejd3OcBXW98s3uhJ70kzOEXIa19TxdP4BCZdI,11902
81
+ synth_ai/environments/examples/nethack/helpers/visualization/visualizer.py,sha256=jHndZowjrRF2nYFyN-gP_3OOBsP3uPNT2PP1y6WV4pA,14831
82
+ synth_ai/environments/examples/red/__init__.py,sha256=4uHc_oyMmFK9jllUs9BAY4mxMwt5_Q7sD7Meo8zuTa4,199
83
+ synth_ai/environments/examples/red/config_logging.py,sha256=jVjehrms140gnJ1aAaXK9oxRXqh8CuU23yGp4AZOh74,3710
84
+ synth_ai/environments/examples/red/engine.py,sha256=43fKZ9YEs-ccL7rPtVNihStbwvxndk7GYyjr4zoCbYI,23835
85
+ synth_ai/environments/examples/red/environment.py,sha256=oHdG2I1QUOnVj80_IvIgBi5Rv2IyotnPgwMpXqsSZMc,9342
86
+ synth_ai/environments/examples/red/taskset.py,sha256=1oYI2UOqBdV5A-r7fg1LM4JIi5OQcRdTI6UUyPuQW_0,2825
87
+ synth_ai/environments/examples/red/engine_helpers/__init__.py,sha256=YyNOk0TMWA_CI_EakcTMjbLJpkFKKRhJfVe792w-CXE,33
88
+ synth_ai/environments/examples/red/engine_helpers/memory_map.py,sha256=jOsBYaYYxUy2tz3L2pCoj7Y_3UdrViw6vNYdgbEZFDk,1193
89
+ synth_ai/environments/examples/red/engine_helpers/reward_components.py,sha256=QllhLE4lpyKLcTbGgl5zK51ftX5CXjl_7-MOoSIiRLg,9355
90
+ synth_ai/environments/examples/red/engine_helpers/screen_analysis.py,sha256=gR1AU10m_HZGqWr6g6eTUx1fkZi8Yfhg73XuMwmZODg,12773
91
+ synth_ai/environments/examples/red/engine_helpers/state_extraction.py,sha256=i20OpC7DCcOo52dHGzHQnXI2DzUiTbu_2PcyVhGDj9Q,4418
92
+ synth_ai/environments/examples/red/engine_helpers/reward_library/__init__.py,sha256=kETzPWAaFOiAO4sNxcGerX2lXP1xnQkdiVfzmL1JGkU,4015
93
+ synth_ai/environments/examples/red/engine_helpers/reward_library/adaptive_rewards.py,sha256=xE7AsliJVmygo2aptYCHBnt4X0OffeLYzRa0Tjhp92k,1890
94
+ synth_ai/environments/examples/red/engine_helpers/reward_library/battle_rewards.py,sha256=hjJMYS-CzvO2ugJyBVBNZuhZIG-LU2ng0S4DUkHZD90,10426
95
+ synth_ai/environments/examples/red/engine_helpers/reward_library/composite_rewards.py,sha256=sRS4h4njAzfGDnaah_OG0kCz3P5UlAz9zXm0hczRyLA,5091
96
+ synth_ai/environments/examples/red/engine_helpers/reward_library/economy_rewards.py,sha256=25ACp4SDPXUxQjAVRcdFvOw_NStRFaPc5K78OrwcJG4,5018
97
+ synth_ai/environments/examples/red/engine_helpers/reward_library/efficiency_rewards.py,sha256=RCLbN-hh-Cx0fxOB3zKQs6KvRa-u9MlKYeI5_TtOFrg,1817
98
+ synth_ai/environments/examples/red/engine_helpers/reward_library/exploration_rewards.py,sha256=V3Gvs-hHGHV9OohDsZncBd8K7kiGRtQkDo7p8rOG1mA,12391
99
+ synth_ai/environments/examples/red/engine_helpers/reward_library/novelty_rewards.py,sha256=uCRT8CQUDBueCuMa8x7IYKQun2yXq32mt6eHBifu4B8,3611
100
+ synth_ai/environments/examples/red/engine_helpers/reward_library/pallet_town_rewards.py,sha256=I-MzN6eiaQs7cuQHZvKO_nZJ1SRVlsK83dIY4TmTigA,19889
101
+ synth_ai/environments/examples/red/engine_helpers/reward_library/pokemon_rewards.py,sha256=pHMN8mh3qvJ-anxb80DxR_UBChOdrjiL7Ng6oyFBydU,10860
102
+ synth_ai/environments/examples/red/engine_helpers/reward_library/social_rewards.py,sha256=qQ-gN_xceb9QTzMiMGNmmKrZSsQDr-bD9JDWS4d_ops,5675
103
+ synth_ai/environments/examples/red/engine_helpers/reward_library/story_rewards.py,sha256=1sH6bLShvWOrvdOCIWbg56oMJ7eeMm2SmSLMcrO8MME,8464
104
+ synth_ai/environments/examples/sokoban/__init__.py,sha256=Y5MpHrvlI9s5gEwlAJ0FM08bZpyC4QdnGWaTCyPQas8,35
105
+ synth_ai/environments/examples/sokoban/engine.py,sha256=Dn5lV8lyhb_4uQNIwpTeDjN0bYUCqjo1ym3vrD2nQfs,26275
106
+ synth_ai/environments/examples/sokoban/environment.py,sha256=wZ59GS9-UZMt9ysAVgdJIcL9UwvjiCdzYjEj6aPYSKM,9801
107
+ synth_ai/environments/examples/sokoban/generate_verified_puzzles.py,sha256=tGCJNaNsXGK2nsZ54xqJ4p9lyfjQGJ54a9SguUIQiiU,15509
108
+ synth_ai/environments/examples/sokoban/puzzle_loader.py,sha256=4Ufqx9IyuWDfHt77VxcM7URgCb6crpsMHr-1TBkfxsc,11497
109
+ synth_ai/environments/examples/sokoban/taskset.py,sha256=UhavqJceg6CYFFWClbldgjqRzY6gBUqZveaHc7N13Ko,15537
110
+ synth_ai/environments/examples/sokoban/engine_helpers/__init__.py,sha256=ensyOUm01rMpYZPIoV012_v6vxnv95mwwi63hLJvwIw,29
111
+ synth_ai/environments/examples/sokoban/engine_helpers/room_utils.py,sha256=NZ3TSvTmbo19aT9X-xaPsg5CV4oPmdtV6356L76F7Bk,21757
112
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/__init__.py,sha256=jdGs_dghlGglKSi1EpsLz3IivSqNYhgu0icwzS7nKS0,404
113
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/__init__.py,sha256=Gvw94rIHk-BAaARkboJzZ6mx4z_n_UkFxm9xqZqxVFc,134
114
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/boxoban_env.py,sha256=ykJzlZjQtmcG0JJbOECUJ5EgQAURfvKkAq3ACwYF5xE,4132
115
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/render_utils.py,sha256=Vpj86hJhrSkK6kPobB_H5_bcvKsPT86-uhs7Agu66L4,11375
116
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/room_utils.py,sha256=43mge3pUJgvnGqKT1y7Ww39h3k0MRcvmL208ffzHzZ8,10587
117
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env.py,sha256=VaLExeff0vh4hQvkZphPBmjtS-f5v_MRk4E-9jNtCxU,10381
118
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_fixed_targets.py,sha256=aVsb29Q79X_6XYR6-fKynTlSoxBo7_Es9wlUFAM8ltE,2551
119
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_pull.py,sha256=8FiVFOf5-w_fuf2fWUOcluRH5Zzqbn7y4CDxXlMjtMM,3807
120
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_two_player.py,sha256=ChjsHcraEnjRPazhojeG4RDekyBbB9XzRU-UnXIfEEo,3762
121
+ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_variations.py,sha256=mQlnDZJUfi-TiR3zcGyy4iTJutUqxwjRj7fxz8THupg,15455
122
+ synth_ai/environments/examples/tictactoe/__init__.py,sha256=XGoOP8GEGXjG-TI_E_-3b1jOhpGNtl_LmR9G3K59Gig,31
123
+ synth_ai/environments/examples/tictactoe/engine.py,sha256=NuFpXuiClyBCByS-m3fEpU343nkNq_aIsqYAMxXrGCs,12430
124
+ synth_ai/environments/examples/tictactoe/environment.py,sha256=42y9wCpG1NOAPxaILdaBjDl8WgEvnHbk3rd75GtgLH4,9335
125
+ synth_ai/environments/examples/tictactoe/taskset.py,sha256=rGbFwkokndkwXR95RSUF4-mRwvX8EKjpQRofnabmhs8,7811
126
+ synth_ai/environments/examples/verilog/__init__.py,sha256=JBf4ayWGO-VPK7PLitp_-jiKDi9gd3hhQ-PahNkiLJ0,262
127
+ synth_ai/environments/examples/verilog/engine.py,sha256=jxpVJ5oVbRyObCLnETfy-sPARunaoYLLaPx7cyl68jc,12170
128
+ synth_ai/environments/examples/verilog/environment.py,sha256=M6igedpgJWvLjw_ta1k4fwY9Kz0dPDIEgO9S4B-eBGg,12329
129
+ synth_ai/environments/examples/verilog/taskset.py,sha256=-Vqrc_HY07WHcHLDQJ3KIDU3kNjpCgAMqCUYtay2Vyg,13336
32
130
  synth_ai/environments/reproducibility/core.py,sha256=y4__bivu_tdyIas509oK2EH9KUdLaQfbJ6z3dK8wYxc,1499
33
131
  synth_ai/environments/reproducibility/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
132
  synth_ai/environments/reproducibility/tree.py,sha256=bl0lfIjrJGxMNmcWs75uPBwurgd1ENjN_mI5RHfrANY,13743
@@ -181,9 +279,9 @@ synth_ai/v0/tracing_v1/events/manage.py,sha256=dgIlH43aEz7yA1_rj4IisJP6ROiROmLwD
181
279
  synth_ai/v0/tracing_v1/events/scope.py,sha256=BuBkhSpVHUJt8iGT9HJZF82rbb88mQcd2vM2shg-w2I,2550
182
280
  synth_ai/v0/tracing_v1/events/store.py,sha256=gVM3L_bV_PAEh9GD9eg2AQqNfANu-zH9ied7bAKk_Eg,9040
183
281
  synth_ai/zyk/__init__.py,sha256=6HFa13sdHCouhzKOUPEWcJeVxKlzjWO7ERsrrwtTugs,752
184
- synth_ai-0.2.4.dev4.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
185
- synth_ai-0.2.4.dev4.dist-info/METADATA,sha256=rQqUijPG-9CeDt33ihFOSoDyKrQpF_3obxoNG-tCCJg,7150
186
- synth_ai-0.2.4.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
187
- synth_ai-0.2.4.dev4.dist-info/entry_points.txt,sha256=GSFXaJreq4PJXbixkUI0GHZwGh2dZDG5pYaoVmqr_KE,46
188
- synth_ai-0.2.4.dev4.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
189
- synth_ai-0.2.4.dev4.dist-info/RECORD,,
282
+ synth_ai-0.2.4.dev5.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
283
+ synth_ai-0.2.4.dev5.dist-info/METADATA,sha256=j8LGEHF6txGGKOR6MSHd2zPoUUkgS5QeZbsoS-EJids,7150
284
+ synth_ai-0.2.4.dev5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
285
+ synth_ai-0.2.4.dev5.dist-info/entry_points.txt,sha256=GSFXaJreq4PJXbixkUI0GHZwGh2dZDG5pYaoVmqr_KE,46
286
+ synth_ai-0.2.4.dev5.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
287
+ synth_ai-0.2.4.dev5.dist-info/RECORD,,