Skip to content

Commit

Permalink
code contests
Browse files Browse the repository at this point in the history
  • Loading branch information
femto committed Jan 12, 2025
1 parent 7602d41 commit 91c3457
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 12 deletions.
9 changes: 9 additions & 0 deletions examples/smart_minion/brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ async def smart_brain():
)
# obs, score, *_ = await brain.step(query="what's the solution for game of 24 for 4 3 9 8")
# print(obs)
current_file_dir = os.path.dirname(os.path.abspath(__file__))
cache_plan = os.path.join(current_file_dir, "aime", "plan_gpt4o.1.json")
obs, score, *_ = await brain.step(
query="Every morning Aya goes for a $9$-kilometer-long walk and stops at a coffee shop afterwards. When she walks at a constant speed of $s$ kilometers per hour, the walk takes her 4 hours, including $t$ minutes spent in the coffee shop. When she walks $s+2$ kilometers per hour, the walk takes her 2 hours and 24 minutes, including $t$ minutes spent in the coffee shop. Suppose Aya walks at $s+\frac{1}{2}$ kilometers per hour. Find the number of minutes the walk takes her, including the $t$ minutes spent in the coffee shop.",
route="plan",
dataset="aime 2024",
cache_plan=cache_plan,
)
print(obs)

# 从 HumanEval/88 提取的测试用例
test_data = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "ensemble",

"pre_processing": ["problem_reflect"],
"workers": [
{
"name": "python",
Expand Down
4 changes: 1 addition & 3 deletions examples/smart_minion/code_contests/evalute_code_contests.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,8 @@ async def solve_single_question(item, route="cot"):
return {
"result": 0,
"item_id": item_id,
"task_id": item["task_id"],
"item": item,
"question": question,
"canonical_solution": canonical_solution,
"test": test,
"answer": answer,
"reason": ret[1],
"idx": item_id,
Expand Down
25 changes: 19 additions & 6 deletions minion/main/minion.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
MINION_REGISTRY = {}
WORKER_MINIONS = {}
IMPROVER_MINIONS = {}
PRE_PROCESSING_REGISTRY = {} # New registry for pre-processing minions


# a dummy score that does nothing, always return 1 to shortcut the score process
Expand All @@ -29,21 +30,21 @@ def __init__(cls, name, bases, clsdict):
super().__init__(name, bases, clsdict)
cls._subclassed_hook()

def register_minion(name):
def decorator(cls):
MINION_REGISTRY[name] = cls
return cls
return decorator

def register_worker_minion(cls=None, *, name=None):
"""Decorator to register worker minions.
Can be used as @register_worker_minion or @register_worker_minion(name="custom_name")
Args:
cls: The class to register (when used as @register_worker_minion)
name: Optional custom name (when used as @register_worker_minion(name="custom_name"))
"""
def decorator(cls):
# Use custom name if provided, otherwise convert class name to snake_case
register_name = name if name is not None else camel_case_to_snake_case(cls.__name__)
WORKER_MINIONS[register_name] = cls
return cls

# Handle both @register_worker_minion and @register_worker_minion(name="custom_name")
if cls is None:
return decorator
return decorator(cls)
Expand All @@ -61,6 +62,18 @@ def decorator(cls):
return decorator
return decorator(cls)

def register_pre_processing_minion(cls=None, *, name=None):
"""Decorator to register pre-processing minions.
Can be used as @register_pre_processing_minion or @register_pre_processing_minion(name="custom_name")
"""
def decorator(cls):
register_name = name if name is not None else camel_case_to_snake_case(cls.__name__).replace('_minion', '')
PRE_PROCESSING_REGISTRY[register_name] = cls
return cls

if cls is None:
return decorator
return decorator(cls)

class Minion(metaclass=SubclassHookMeta):
def __init__(self, input=None, brain=None, id=None, score_func=None, worker_config=None, task=None, **kwargs):
Expand Down
15 changes: 15 additions & 0 deletions minion/main/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,18 @@
"""
+ ASK_PROMPT_JINJA
)

PROBLEM_REFLECT_PROMPT = """Please analyze the following problem and provide a detailed reflection:
Problem Description:
{{input.query}}
Please provide:
1. Key concepts and requirements
2. Potential challenges and edge cases
3. Similar problems you've encountered
4. Suggested approach and methodology
5. Any assumptions that need to be validated
Your reflection should help guide the solution process.
"""
44 changes: 42 additions & 2 deletions minion/main/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from minion.actions.action_node import ActionNode
from minion.configs.config import config
from minion.logs import logger
from minion.main.pre_processing import PreProcessingMinion
from minion.main.check import CheckMinion
from minion.main.check_route import CheckRouterMinion
from minion.main.improve import ImproverMinion
Expand Down Expand Up @@ -562,6 +563,40 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)
self.execution_state: Dict[str, Any] = {}

async def execute_pre_processing(self):
"""Execute pre-processing steps if configured"""
if not hasattr(self.input, 'execution_config'):
return

pre_processing_steps = self.input.execution_config.get('pre_processing', [])
if not pre_processing_steps:
return

# Ensure pre_processing_steps is a list
if isinstance(pre_processing_steps, str):
pre_processing_steps = [pre_processing_steps]

# Get pre-processing minion registry
from minion.main.minion import PRE_PROCESSING_REGISTRY

# Execute each pre-processing step in sequence
for step in pre_processing_steps:
pre_processing_class = PRE_PROCESSING_REGISTRY.get(step)
if not pre_processing_class:
logger.warning(f"Pre-processing minion {step} not found")
continue
self.execution_state["current_pre_processing"] = step
self.save_execution_state()

# Execute pre-processing
pre_processing_minion = pre_processing_class(input=self.input, brain=self.brain)
await pre_processing_minion.execute()

# Update execution state

self.execution_state["current_pre_processing"] = None
self.save_execution_state()

async def invoke_minion(self, minion_name, worker_config=None):
self.input.run_id = uuid.uuid4() # a new run id for each run
self.input.route = minion_name
Expand All @@ -588,6 +623,9 @@ async def execute_ensemble(self):
if 'workers' not in self.input.execution_config:
return await self.execute_single()

# Execute pre-processing first
await self.execute_pre_processing()

results = {}
total_count = sum(worker["count"] for worker in self.input.execution_config["workers"])
majority_count = total_count // 2 + 1
Expand Down Expand Up @@ -627,6 +665,8 @@ async def execute_ensemble(self):
return most_voted_result

async def execute_single(self):
# Execute pre-processing first
await self.execute_pre_processing()
return await self.invoke_minion(self.input.route)

async def execute(self):
Expand All @@ -649,12 +689,12 @@ async def execute(self):
def save_execution_state(self):
"""保存执行状态"""
if self.input.save_state:
self.input.exec_save_state(f"state_{self.input.query_id}.pkl")
self.input.save_state(f"state_{self.input.query_id}.pkl")

def load_execution_state(self):
"""加载执行状态"""
if self.input.save_state:
loaded_input = Input.exec_load_state(f"state_{self.input.query_id}.pkl")
loaded_input = Input.load_state(f"state_{self.input.query_id}.pkl")
if loaded_input:
self.input = loaded_input

Expand Down

0 comments on commit 91c3457

Please sign in to comment.