ReMe/reme/steps/evolve/dream/proactive.py

60 lines
2.9 KiB
Python

"""Read daily interests.yaml for proactive use."""
from ...base_step import BaseStep
from ....components import R
from ....schema import ProactiveResult
from .utils import load_yaml_topics, today, workspace_dir
@R.register("proactive_step")
class ProactiveStep(BaseStep):
"""Read ``daily/<date>/interests.yaml``."""
def __init__(self, include_content: bool = True, **kwargs):
super().__init__(**kwargs)
self.include_content = include_content
async def execute(self):
assert self.context is not None
day = today(self, str(self.context.get("date", "") or ""))
include_content = bool(self.context.get("include_content", self.include_content))
daily = self.config_value("daily_dir")
rel_path, abs_path = f"{daily}/{day}/interests.yaml", workspace_dir(self) / daily / day / "interests.yaml"
result = ProactiveResult(date=day, path=rel_path)
self.logger.info(f"[{self.name}] start date={day} path={rel_path} include_content={include_content}")
if not abs_path.is_file():
result.skipped, result.summary = True, f"Skipped: interests file not found at {rel_path}"
self.logger.info(f"[{self.name}] skip missing path={rel_path}")
return self._finish(True, result, include_content=include_content)
try:
self.logger.info(f"[{self.name}] read start path={rel_path}")
result.content = abs_path.read_text(encoding="utf-8") if include_content else ""
result.topics = load_yaml_topics(abs_path)
self.logger.info(
f"[{self.name}] read done path={rel_path} topics={len(result.topics)} chars={len(result.content)}",
)
except Exception as e: # noqa: BLE001
result.error, result.summary = f"{type(e).__name__}: {e}", ""
self.logger.error(f"[{self.name}] read failed path={rel_path}: {result.error}")
return self._finish(False, result, include_content=include_content)
result.summary = f"Read {len(result.topics)} proactive topic(s) from {rel_path}"
return self._finish(True, result, include_content=include_content)
def _finish(self, success: bool, result: ProactiveResult, *, include_content: bool):
assert self.context is not None
self.context.response.success = success
if not success:
self.context.response.answer = f"Error: {result.error}"
elif result.skipped:
self.context.response.answer = result.summary
else:
self.context.response.answer = {
"summary": result.summary,
"topics": result.topics,
**({"content": result.content} if include_content else {}),
}
self.context.response.metadata.update(result.model_dump())
self.logger.info(f"[{self.name}] finish success={success} answer={self.context.response.answer!r}")
return self.context.response