ReMe/reme4/steps/evolve/_evolve.py
jinliyl ef22bfb071
refactor(evolve): replace ReActAgent with FlexReActAgent to allow structured output (#265)
- Create FlexReActAgent subclass that overrides _reasoning method to handle tool_choice parameter
- Modify auto_memory_planner to use FlexReActAgent instead of ReActAgent
- Update base_step.py to accept additional kwargs in add_as_tool method
- Change run_job function to merge kwargs properly when calling jobs
- Remove redundant imports and constants from file_io.py
- Simplify _render_notes_block and rename _replace_or_append_notes to _rebuild_body
- Update method calls to use new function names in file_io operations
2026-05-29 15:19:56 +08:00

43 lines
1.4 KiB
Python

"""Shared helpers for evolve steps."""
import datetime
import zoneinfo
from typing import Literal
from agentscope.agent import ReActAgent
from agentscope.message import Msg
def now(timezone: str | None = None) -> datetime.datetime:
"""Return current datetime in the given IANA timezone, falling back to local."""
if not timezone:
return datetime.datetime.now()
try:
return datetime.datetime.now(zoneinfo.ZoneInfo(timezone))
except Exception:
return datetime.datetime.now()
def format_history(messages: list[Msg], include_timestamp: bool = True) -> str:
"""Render a conversation slice as a human-readable transcript."""
lines: list[str] = []
for msg in messages:
text = (msg.get_text_content() or "").strip()
if not text:
continue
speaker = msg.name or msg.role or "?"
header = f"[{speaker} @ {msg.timestamp}]" if include_timestamp else f"[{speaker}]"
lines.append(f"{header}\n{text}")
return "\n\n".join(lines) or "(empty)"
class FlexReActAgent(ReActAgent):
"""ReActAgent subclass that allows structured output without forcing tool_choice='required'."""
async def _reasoning(
self,
tool_choice: Literal["auto", "none", "required"] | None = None,
) -> Msg:
if tool_choice == "required":
tool_choice = None
return await super()._reasoning(tool_choice)