""" Adapter: Reflective Mutation Proposer. Implements the ProposerPort via the DSPy InstructionProposer. Converts trajectories into readable format for the LLM proposer. """ from __future__ import annotations import dspy from prometheus.domain.entities import Prompt, Trajectory from prometheus.domain.ports import ProposerPort from prometheus.infrastructure.dspy_modules import InstructionProposer class DSPyProposerAdapter(ProposerPort): """Uses evaluation trajectories to build a failure report and propose a new prompt.""" def __init__(self, lm: dspy.LM) -> None: self._lm = lm self._proposer = InstructionProposer() def propose( self, current_prompt: Prompt, trajectories: list[Trajectory], task_description: str, ) -> Prompt: failure_examples = self._format_failures(trajectories) with dspy.context(lm=self._lm): pred = self._proposer( current_instruction=current_prompt.text, task_description=task_description, failure_examples=failure_examples, ) return Prompt(text=pred.new_instruction) @staticmethod def _format_failures(trajectories: list[Trajectory]) -> str: """Convert trajectories into a structured textual report.""" sections: list[str] = [] for i, t in enumerate(trajectories, 1): section = ( f"# Example {i}\n" f"## Input\n{t.input_text}\n\n" f"## Generated Output\n{t.output_text}\n\n" f"## Score\n{t.score:.2f}\n\n" f"## Feedback\n{t.feedback}\n" ) sections.append(section) return "\n---\n".join(sections)