Handles idea generation using MAS
| 63 | # Idea Generation Config |
| 64 | # ============================================================================ |
| 65 | class IdeaGenerator: |
| 66 | """Handles idea generation using MAS""" |
| 67 | |
| 68 | def __init__(self, args, logger, round_num=1, config=None): |
| 69 | self.args = args |
| 70 | self.logger = logger |
| 71 | self.round_num = round_num # Current loop round number (1-indexed) |
| 72 | self.config = config or {} # Config dict for accessing evolution_interval |
| 73 | # Pass exp_backend to the interface so it can be accessed by agents |
| 74 | self.interface = InternAgentInterface( |
| 75 | args.config, |
| 76 | work_dir=args.task_dir, |
| 77 | task_name=args.task_name, |
| 78 | exp_backend=args.exp_backend |
| 79 | ) |
| 80 | self.session_id = None |
| 81 | self.status = None |
| 82 | |
| 83 | # Initialize IdeaGraph (if long memory is available) |
| 84 | self.idea_graph = None |
| 85 | if LONG_MEMORY_AVAILABLE and IdeaGraph is not None: |
| 86 | # Use base_output_dir for IdeaGraph (task-level, shared across launches) |
| 87 | output_dir = getattr(self.args, 'base_output_dir', None) or osp.join("results", self.args.task_name) |
| 88 | os.makedirs(output_dir, exist_ok=True) |
| 89 | try: |
| 90 | self.idea_graph = IdeaGraph( |
| 91 | working_dir=output_dir, |
| 92 | namespace=self.args.task_name, |
| 93 | similarity_threshold=0.7 |
| 94 | ) |
| 95 | self.logger.info("IdeaGraph initialized") |
| 96 | except Exception as e: |
| 97 | self.logger.warning(f"Failed to initialize IdeaGraph: {e}") |
| 98 | self.idea_graph = None |
| 99 | else: |
| 100 | self.logger.info("Long memory not available, IdeaGraph disabled") |
| 101 | |
| 102 | def _load_historical_ideas_to_graph(self): |
| 103 | """ |
| 104 | Load all historical ideas from previous sessions into the IdeaGraph. |
| 105 | |
| 106 | This allows the graph to maintain a complete history of all generated ideas |
| 107 | across multiple iterations, enabling better exploration score calculation. |
| 108 | """ |
| 109 | if self.idea_graph is None: |
| 110 | return |
| 111 | |
| 112 | # Use base_output_dir for consistency with other components |
| 113 | output_dir = getattr(self.args, 'base_output_dir', None) or osp.join("results", self.args.task_name) |
| 114 | if not osp.exists(output_dir): |
| 115 | self.logger.info("No historical ideas found (output directory doesn't exist)") |
| 116 | return |
| 117 | |
| 118 | # Find all ideas.json files in session directories (new structure: *_launch/session_*/ideas.json) |
| 119 | ideas_files = glob.glob(osp.join(output_dir, "*_launch", "session_*", "ideas.json")) |
| 120 | # Also check legacy structure (session_*/ideas.json) |
| 121 | ideas_files.extend(glob.glob(osp.join(output_dir, "session_*", "ideas.json"))) |
| 122 | # Also check old format (ideas_*.json) |