From 40bb3b1052571d798a8f5f7dde9aaf1b63c2dffd Mon Sep 17 00:00:00 2001 From: "jinli.yl" Date: Wed, 18 Jun 2025 12:23:43 +0800 Subject: [PATCH] clean project --- .../simple_agent/your_own_agent_enhanced.py | 4 +- cookbook/step_agent/examples.py | 3 +- .../agent_wrapper/base_agent_wrapper.py | 78 ------------- .../module/agent_wrapper/mcp_react_agent.py | 107 ------------------ .../agent_wrapper/simple_agent_wrapper.py | 2 +- .../simple_context_generator.py | 5 +- .../traj_context_generator.py | 1 - .../module/environment/__init__.py | 0 .../module/environment/base_environment.py | 56 --------- experiencemaker/module/evaluator/__init__.py | 0 .../module/evaluator/base_evaluator.py | 19 ---- .../reward_fn/simple_compare_reward_fn.py | 6 +- experiencemaker/module/runner/__init__.py | 0 experiencemaker/module/runner/base_runner.py | 27 ----- .../module/summarizer/step_summarizer.py | 4 +- .../module/summarizer/traj_summarizer.py | 34 ------ experiencemaker/module/trainner/__init__.py | 0 .../module/trainner/base_trainner.py | 34 ------ experiencemaker/schema/reward.py | 7 +- experiencemaker/schema/trajectory.py | 26 ++--- experiencemaker/storage/base_sample_buffer.py | 17 --- 21 files changed, 26 insertions(+), 404 deletions(-) delete mode 100644 experiencemaker/module/agent_wrapper/base_agent_wrapper.py delete mode 100644 experiencemaker/module/agent_wrapper/mcp_react_agent.py delete mode 100644 experiencemaker/module/context_generator/traj_context_generator.py delete mode 100644 experiencemaker/module/environment/__init__.py delete mode 100644 experiencemaker/module/environment/base_environment.py delete mode 100644 experiencemaker/module/evaluator/__init__.py delete mode 100644 experiencemaker/module/evaluator/base_evaluator.py delete mode 100644 experiencemaker/module/runner/__init__.py delete mode 100644 experiencemaker/module/runner/base_runner.py delete mode 100644 experiencemaker/module/summarizer/traj_summarizer.py delete mode 100644 experiencemaker/module/trainner/__init__.py delete mode 100644 experiencemaker/module/trainner/base_trainner.py delete mode 100644 experiencemaker/storage/base_sample_buffer.py diff --git a/cookbook/simple_agent/your_own_agent_enhanced.py b/cookbook/simple_agent/your_own_agent_enhanced.py index be70de89..864fe7e2 100644 --- a/cookbook/simple_agent/your_own_agent_enhanced.py +++ b/cookbook/simple_agent/your_own_agent_enhanced.py @@ -20,7 +20,7 @@ class YourOwnAgentEnhanced(YourOwnAgent): def summary_experience(self, query: str): messages = self.run(query) - trajectory: Trajectory = Trajectory(query=query, steps=messages, answer=messages[-1].content, done=True) + trajectory: Trajectory = Trajectory(query=query, steps=messages, answer=messages[-1].content, is_terminated=True) request: SummarizerRequest = SummarizerRequest(trajectories=[trajectory], workspace_id=self.workspace_id) response: SummarizerResponse = self.em_client.call_summarizer(request) @@ -40,7 +40,7 @@ class YourOwnAgentEnhanced(YourOwnAgent): trajectory.steps = messages trajectory.answer = messages[-1].content - trajectory.done = True + trajectory.is_terminated = True trajectory.metadata["experience"] = response.context_msg.content return trajectory diff --git a/cookbook/step_agent/examples.py b/cookbook/step_agent/examples.py index c97233ae..75932fd6 100644 --- a/cookbook/step_agent/examples.py +++ b/cookbook/step_agent/examples.py @@ -21,8 +21,7 @@ def create_sample_trajectory(query: str, steps: List[Message], done: bool = True trajectory = Trajectory( query=query, steps=steps, - done=done, - current_step=len(steps) - 1, + is_terminated=done, metadata={ "domain": "coding", "task_type": "problem_solving" diff --git a/experiencemaker/module/agent_wrapper/base_agent_wrapper.py b/experiencemaker/module/agent_wrapper/base_agent_wrapper.py deleted file mode 100644 index 93f6303f..00000000 --- a/experiencemaker/module/agent_wrapper/base_agent_wrapper.py +++ /dev/null @@ -1,78 +0,0 @@ -from typing import List - -from pydantic import Field - -from experiencemaker.module.agent_wrapper.agent_wrapper_mixin import AgentWrapperMixin -from experiencemaker.module.environment.base_environment import BaseEnvironment -from experiencemaker.schema.trajectory import Trajectory, Message, StateMessage, ActionMessage, ContextMessage - - -class BaseAgentWrapper(AgentWrapperMixin): - max_steps: int = Field(default=10) - enable_exploration: bool = Field(default=False) - trajectory: Trajectory | None = Field(default_factory=Trajectory) - - def reset(self): - self.trajectory.reset() - - def after_step_hook(self, **kwargs): - raise NotImplementedError - - def build_messages(self, - state: StateMessage, - context_msg: ContextMessage | None, - env: BaseEnvironment, **kwargs) -> List[Message]: - raise NotImplementedError - - def explore_messages(self, messages: List[Message], **kwargs) -> List[Message]: - raise NotImplementedError - - def action_parser(self, action_msg: ActionMessage) -> ActionMessage: # noqa - return action_msg - - def generate_action(self, - state: StateMessage, - context_msg: ContextMessage | None, - env: BaseEnvironment, - **kwargs) -> ActionMessage: - - messages: List[Message] = self.build_messages(state, context_msg, env, **kwargs) - if self.enable_exploration: - messages = self.explore_messages(messages, **kwargs) - - action_msg: ActionMessage = self.llm.chat(messages, tools=env.tools) - return self.action_parser(action_msg) - - def execute(self, query: str, env: BaseEnvironment = None, **kwargs) -> Trajectory: - self.trajectory.query = query - current_state = env.current_state - - for i in range(self.max_steps): - self.trajectory.current_step = i - - # generate context - context_msg: ContextMessage | None = None - if self.context_generator: - context_msg = self.context_generator.execute(trajectory=self.trajectory, **kwargs) - - # generate action - action_msg = self.generate_action(state=current_state, context_msg=context_msg, env=env, **kwargs) - - # generate next state - next_state, reward, done, info = env.step(action_msg, trajectory=self.trajectory, **kwargs) - - self.after_step_hook(step_index=i, - current_state=current_state, - action_msg=action_msg, - reward=reward, - next_state=next_state, - done=done, - info=info, - **kwargs) - - if done: - break - - current_state = next_state - - return self.trajectory diff --git a/experiencemaker/module/agent_wrapper/mcp_react_agent.py b/experiencemaker/module/agent_wrapper/mcp_react_agent.py deleted file mode 100644 index 349c4525..00000000 --- a/experiencemaker/module/agent_wrapper/mcp_react_agent.py +++ /dev/null @@ -1,107 +0,0 @@ - -# import os -# import time -# import json -# import best_logger -# import agentscope -# from experiencemaker.module.base_module import BaseModule -# from experiencemaker.schema.trajectory import Trajectory as OutputTrajectory -# from experiencemaker.schema.trajectory import Message as OutputTrajectoryMessage - -# from datetime import datetime -# from pydantic import BaseModel, Field -# import uuid -# from typing import ( -# Literal, -# Union, -# List, -# Optional, -# Dict, -# Any, -# Sequence, -# ) - - -# from experiencemaker.module.agent_wrapper.base_agent_wrapper import BaseAgentWrapper -# from agentscope.agents import ReActAgent, DialogAgent -# from beyond.trajectory import Trajectory as TrajectoryOperation -# from beyond.solver import TaskExecutor -# from agentscope.message import Msg -# from beyond.planner import * -# from beyond.debug import * -# from best_logger import * -# from loguru import logger - - -# def run_agent_and_extract_memory(msg_question, traj, agent): -# if not isinstance(msg_question, list): -# raise ValueError("msg_question should be a list of Msg objects") -# agent_ret = agent(msg_question) -# latest_agent_memory_buffer = msg_sort(agent.memory.get_memory()) -# traj.add_steps(latest_agent_memory_buffer) -# return latest_agent_memory_buffer, agent_ret - - -# def msg_sort(msg_list: List[Msg]) -> List[Msg]: -# """ -# Sort the message list by timestamp. -# """ -# sorted_msg = sorted( -# msg_list, -# key=lambda msg: datetime.strptime(msg.timestamp, "%Y-%m-%d %H:%M:%S.%f") -# ) - -# return sorted_msg - - -# class MainAgent(BaseAgentWrapper): -# mcp_url: str = Field( -# default=os.getenv('MCP_URL', 'http://localhost:33333/sse'), -# description="The URL of the MCP server.", -# ) - -# def __init__(self, *args, **kwargs): -# return super().__init__(*args, **kwargs) - -# def execute(self, query, **kwargs): -# question = query.strip() -# ref_answer = "not available" - -# print_dict({ -# 'question': question, -# 'ref_answer': ref_answer, -# }, mod='gaia_result') - -# try: -# except Exception as e: -# logger.exception(f"Error in solving task {question}: {e}") -# raise RuntimeError(f"Error in solving task {question}: {e}") - -# print_dict({ -# 'question': question, -# 'ref_answer': ref_answer, -# 'predicted_result': final_answer, -# }, mod='gaia_result') - - -# role_mapping = { -# 'system': 'system', -# 'end-user': 'user', -# 'commander': 'user', -# 'assistant': 'assistant', -# 'tool-agent': 'user', -# 'tool': 'tool', -# } -# output_trajectory = OutputTrajectory( -# steps=[OutputTrajectoryMessage( -# role=role_mapping[step.executor], -# content=step.content, -# timestamp=step.timestamp -# ) for step in traj.raw_steps], -# done=True, -# query=question, -# answer=final_answer, -# current_step=len(traj.raw_steps), -# ) -# return output_trajectory - diff --git a/experiencemaker/module/agent_wrapper/simple_agent_wrapper.py b/experiencemaker/module/agent_wrapper/simple_agent_wrapper.py index 33b194e7..24081848 100644 --- a/experiencemaker/module/agent_wrapper/simple_agent_wrapper.py +++ b/experiencemaker/module/agent_wrapper/simple_agent_wrapper.py @@ -15,5 +15,5 @@ class SimpleAgentWrapper(SimpleAgent, AgentWrapperMixin): trajectory.steps = messages trajectory.answer = messages[-1].content - trajectory.done = True + trajectory.is_terminated = True return trajectory diff --git a/experiencemaker/module/context_generator/simple_context_generator.py b/experiencemaker/module/context_generator/simple_context_generator.py index 233be9da..e072b619 100644 --- a/experiencemaker/module/context_generator/simple_context_generator.py +++ b/experiencemaker/module/context_generator/simple_context_generator.py @@ -11,10 +11,7 @@ from experiencemaker.schema.vector_store_node import VectorStoreNode class SimpleContextGenerator(BaseContextGenerator): def _build_retrieve_query(self, trajectory: Trajectory, **kwargs) -> str: - query = "" - if trajectory.current_step == 0: - query = trajectory.query - return query + return trajectory.query def _retrieve_by_query(self, trajectory: Trajectory, query: str, workspace_id: str, retrieve_top_k: int, **kwargs) -> List[VectorStoreNode]: diff --git a/experiencemaker/module/context_generator/traj_context_generator.py b/experiencemaker/module/context_generator/traj_context_generator.py deleted file mode 100644 index 1ce47dfa..00000000 --- a/experiencemaker/module/context_generator/traj_context_generator.py +++ /dev/null @@ -1 +0,0 @@ -from experiencemaker.module.context_generator.base_context_generator import BaseContextGenerator \ No newline at end of file diff --git a/experiencemaker/module/environment/__init__.py b/experiencemaker/module/environment/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/experiencemaker/module/environment/base_environment.py b/experiencemaker/module/environment/base_environment.py deleted file mode 100644 index cca3f4b2..00000000 --- a/experiencemaker/module/environment/base_environment.py +++ /dev/null @@ -1,56 +0,0 @@ -from abc import ABC -from typing import List - -from pydantic import Field, BaseModel - -from experiencemaker.module.reward_fn.base_reward_fn import BaseRewardFn -from experiencemaker.schema.reward import Reward -from experiencemaker.schema.trajectory import StateMessage, ActionMessage, ToolCall -from experiencemaker.tool.base_tool import BaseTool - - -class BaseEnvironment(BaseModel, ABC): - tools: List[BaseTool] = Field(default_factory=list) - reward_fns: List[BaseRewardFn] = Field(default_factory=list) - current_state: StateMessage = Field(default_factory=StateMessage) - metadata: dict = Field(default_factory=dict, description="add query / answer and etc for reward calculating!") - - def reset(self): - self.current_state = StateMessage() - self.metadata.clear() - - def step(self, action_msg: ActionMessage, **kwargs): - next_state: StateMessage = self.transition(action_msg=action_msg, **kwargs) - - reward: Reward = self.calculate_reward(action_msg=action_msg, next_state=next_state, **kwargs) - - done: bool = self.is_terminated(action_msg=action_msg, next_state=next_state, reward=reward, **kwargs) - - info: dict = self.build_info(action_msg=action_msg, next_state=next_state, reward=reward, done=done, **kwargs) - - self.current_state = next_state - return next_state, reward, done, info - - def transition(self, action_msg: ActionMessage, **kwargs) -> StateMessage: - tool_dict = {tool.name: tool for tool in self.tools} - - new_tool_calls: List[ToolCall] = [] - for tool_call in action_msg.tool_calls: - if tool_call.name not in tool_dict: - continue - - new_tool_call = tool_call.model_copy(deep=True) - tool = tool_dict[tool_call.name] - new_tool_call.result = tool.execute(**tool_call.argument_dict) - new_tool_calls.append(new_tool_call) - - return StateMessage(tool_calls=new_tool_calls) - - def calculate_reward(self, **kwargs) -> Reward: - return Reward() - - def is_terminated(self, **kwargs) -> bool: - raise NotImplementedError - - def build_info(self, **kwargs): - return {} diff --git a/experiencemaker/module/evaluator/__init__.py b/experiencemaker/module/evaluator/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/experiencemaker/module/evaluator/base_evaluator.py b/experiencemaker/module/evaluator/base_evaluator.py deleted file mode 100644 index e2de7d44..00000000 --- a/experiencemaker/module/evaluator/base_evaluator.py +++ /dev/null @@ -1,19 +0,0 @@ -from abc import ABC - -from pydantic import BaseModel, Field - -from experiencemaker.module.agent_wrapper.agent_wrapper_mixin import AgentWrapperMixin -from experiencemaker.module.context_generator.base_context_generator import BaseContextGenerator -from experiencemaker.module.environment.base_environment import BaseEnvironment -from experiencemaker.module.summarizer.base_summarizer import BaseSummarizer - - -class BaseEvaluator(BaseModel, ABC): - data_path: str = Field(default="") - agent_wrapper: AgentWrapperMixin | None = Field(default=None) - context_generator: BaseContextGenerator | None = Field(default=None) - summarizer: BaseSummarizer | None = Field(default=None) - env: BaseEnvironment | None = Field(default=None) - - def evaluate(self, **kwargs): - raise NotImplementedError diff --git a/experiencemaker/module/reward_fn/simple_compare_reward_fn.py b/experiencemaker/module/reward_fn/simple_compare_reward_fn.py index 7c77af94..b06339c9 100644 --- a/experiencemaker/module/reward_fn/simple_compare_reward_fn.py +++ b/experiencemaker/module/reward_fn/simple_compare_reward_fn.py @@ -55,7 +55,7 @@ class SimpleCompareRewardFn(BaseRewardFn, PromptMixin): else: logger.warning(f"no plan exists in result={result}") - reward_value = 0 + outcome = 0 if valid_cnt > 0: - reward_value = better_cnt / valid_cnt - return Reward(reward_value=reward_value) + outcome = better_cnt / valid_cnt + return Reward(outcome=outcome) diff --git a/experiencemaker/module/runner/__init__.py b/experiencemaker/module/runner/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/experiencemaker/module/runner/base_runner.py b/experiencemaker/module/runner/base_runner.py deleted file mode 100644 index cb90519f..00000000 --- a/experiencemaker/module/runner/base_runner.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import List - -from pydantic import BaseModel, Field - -from experiencemaker.module.agent_wrapper.agent_wrapper_mixin import AgentWrapperMixin -from experiencemaker.module.context_generator.base_context_generator import BaseContextGenerator -from experiencemaker.module.environment.base_environment import BaseEnvironment -from experiencemaker.module.summarizer.base_summarizer import BaseSummarizer -from experiencemaker.schema.trajectory import Trajectory - - -class BaseRunner(BaseModel): - agent_wrapper: AgentWrapperMixin | None = Field(default=None) - context_generator: BaseContextGenerator | None = Field(default=None) - summarizer: BaseSummarizer | None = Field(default=None) - env: BaseEnvironment | None = Field(default=None) - traj_buffer: List[Trajectory] = Field(default_factory=list) - - def reset(self): - self.traj_buffer.clear() - self.env.reset() - - def rollout_trajectory(self, query: str, **kwargs): - raise NotImplementedError - - def summary(self, **kwargs): - raise NotImplementedError diff --git a/experiencemaker/module/summarizer/step_summarizer.py b/experiencemaker/module/summarizer/step_summarizer.py index 08496436..6e835b0c 100644 --- a/experiencemaker/module/summarizer/step_summarizer.py +++ b/experiencemaker/module/summarizer/step_summarizer.py @@ -80,8 +80,8 @@ class StepSummarizer(BaseSummarizer, PromptMixin): all_experiences = [] # Classify trajectories based on trajectory.done - success_trajectories = [traj for traj in trajectories if traj.done] - failure_trajectories = [traj for traj in trajectories if not traj.done] + success_trajectories = [traj for traj in trajectories if traj.is_terminated] + failure_trajectories = [traj for traj in trajectories if not traj.is_terminated] # Process success and failure samples concurrently tasks = [] diff --git a/experiencemaker/module/summarizer/traj_summarizer.py b/experiencemaker/module/summarizer/traj_summarizer.py deleted file mode 100644 index ba2ee284..00000000 --- a/experiencemaker/module/summarizer/traj_summarizer.py +++ /dev/null @@ -1,34 +0,0 @@ -import os -from typing import List -from pydantic import Field - -from experiencemaker.schema.trajectory import Trajectory, Sample, SummaryMessage -from experiencemaker.storage.base_vector_store import BaseVectorStore -from experiencemaker.module.summarizer.base_summarizer import BaseSummarizer -from beyond.trajectory import Trajectory as TrajectoryOperation -from beyond.solver import TaskExecutor - -class TrajectorySummarizer(BaseSummarizer): - vector_store: BaseVectorStore | None = Field(default=None) - samples: List[Sample] = Field(default=[]) - - def extract_samples(self, trajectories: List[Trajectory], **kwargs) -> List[Sample]: - raise NotImplementedError - - def insert_into_vector_store(self, samples: List[Sample], **kwargs): - raise NotImplementedError - - def process_trajectory(self, traj: Trajectory): - traj_operation = TrajectoryOperation() - for step in traj.steps: - step.executor = step.role.value - traj_operation.raw_steps += [step] - traj_description = traj_operation.chain_work_steps() - mcp_url = os.getenv('MCP_URL', 'http://localhost:33333/sse') - world_summary = traj_operation.generate_failure_ask_for_internet_help_raj_abs_post_level_3(mcp_url=mcp_url) - self.samples += [] - - def execute(self, trajectories: List[Trajectory], return_samples: bool = True, **kwargs) -> List[Sample]: - for traj in trajectories: - self.process_trajectory(traj) - return self.samples diff --git a/experiencemaker/module/trainner/__init__.py b/experiencemaker/module/trainner/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/experiencemaker/module/trainner/base_trainner.py b/experiencemaker/module/trainner/base_trainner.py deleted file mode 100644 index dc597b60..00000000 --- a/experiencemaker/module/trainner/base_trainner.py +++ /dev/null @@ -1,34 +0,0 @@ -from abc import ABC -from typing import List - -from pydantic import BaseModel, Field - -from experiencemaker.schema.trajectory import Trajectory - - -class BaseTrainner(BaseModel, ABC): - traj_buffer: List[Trajectory] = Field() - - def fit(self): - return - - def save_module_state(self): - return - - -class BaseContextTrainner(BaseTrainner): - """ - load model/prompt/db/buffer -> new cpt - """ - - -class BaseSummaryTrainner(BaseTrainner): - """ - load model/prompt/db/buffer -> new cpt - """ - - -class BasePolicyTrainner(BaseTrainner): - """ - load model/prompt/db/buffer -> new cpt - """ diff --git a/experiencemaker/schema/reward.py b/experiencemaker/schema/reward.py index 8636e3b6..1224d30d 100644 --- a/experiencemaker/schema/reward.py +++ b/experiencemaker/schema/reward.py @@ -2,5 +2,10 @@ from pydantic import Field, BaseModel class Reward(BaseModel): - reward_value: float | None = Field(default=None) + outcome: float = Field(default=0) + description: str = Field(default="Outcome 1 denotes success, and 0 denotes failure.") metadata: dict = Field(default_factory=dict) + + @property + def success(self) -> bool: + return self.outcome > 0 diff --git a/experiencemaker/schema/trajectory.py b/experiencemaker/schema/trajectory.py index 22a6dac2..3a304a8f 100644 --- a/experiencemaker/schema/trajectory.py +++ b/experiencemaker/schema/trajectory.py @@ -6,6 +6,7 @@ from uuid import uuid4 from pydantic import BaseModel, Field, model_validator from experiencemaker.enumeration.role import Role +from experiencemaker.schema.reward import Reward class ToolCall(BaseModel): @@ -45,12 +46,7 @@ class ToolCall(BaseModel): @property def tool_text_result(self): - return f""" -tool.{self.index} -name={self.name} -arguments={self.arguments} -result={str(self.result)} -""".strip() + return f"tool.{self.index}\nname={self.name}\narguments={self.arguments}\nresult={str(self.result)}".strip() class Message(BaseModel): @@ -117,21 +113,19 @@ class Sample(BaseModel): class Trajectory(BaseModel): id: str = Field(default_factory=lambda: uuid4().hex) steps: List[Message] = Field(default_factory=list) - current_step: int = Field(default=0) + is_terminated: bool = Field(default=False) + reward: Reward = Field(default_factory=Reward) - done: bool = Field(default=False) query: str = Field(default="") - answer: Any = Field(default=None) + answer: str = Field(default="") metadata: dict = Field(default_factory=dict) def add_step(self, step: Message): self.steps.append(step) def reset(self): - self.id = uuid4().hex - self.steps.clear() - self.current_step = 0 - self.done = False - self.query = "" - self.answer = "" - self.metadata.clear() + for name, field in self.model_fields.items(): + if field.default is not None: + setattr(self, name, field.default) + elif field.default_factory is not None: + setattr(self, name, field.default_factory()) diff --git a/experiencemaker/storage/base_sample_buffer.py b/experiencemaker/storage/base_sample_buffer.py deleted file mode 100644 index 1b892d6e..00000000 --- a/experiencemaker/storage/base_sample_buffer.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -from pydantic import BaseModel - -from experiencemaker.schema.trajectory import Sample - - -class BaseSampleBuffer(BaseModel): - - def add(self, samples: Sample | List[Sample]): - raise NotImplementedError - - def get_all(self): - raise NotImplementedError - - def clear(self): - raise NotImplementedError