""" Process Reward Schema Binary per-step correct/incorrect signals for Process Reward Model (PRM) training. Two modes: - "per_step": annotate each step independently with thumbs-up/down - "first_error": click the first wrong step, all subsequent auto-marked wrong Research: AgentPRM, ToolRM, ToolRL, SPORT """ import json import logging from typing import Dict, Any, Tuple, List from .identifier_utils import ( safe_generate_layout, generate_element_identifier, generate_validation_attribute, escape_html_content, generate_layout_attributes, ) logger = logging.getLogger(__name__) def generate_process_reward_layout( annotation_scheme: Dict[str, Any], ) -> Tuple[str, List[Tuple[str, str]]]: """Generate HTML for a process reward annotation interface. Args: annotation_scheme: Configuration dict. Required keys: ``name``, ``description``. Optional: ``steps_key``, ``mode``. Returns: ``(html, keybindings)`` tuple. """ return safe_generate_layout(annotation_scheme, _generate_internal) def _generate_internal( annotation_scheme: Dict[str, Any], ) -> Tuple[str, List[Tuple[str, str]]]: schema_name = annotation_scheme["name"] description = annotation_scheme["description"] steps_key = annotation_scheme.get("steps_key", "steps") step_text_key = annotation_scheme.get("step_text_key", "action") mode = annotation_scheme.get("mode", "first_error") # "first_error" or "per_step" # When true, the per-step Correct/Wrong control is injected to the right # of each rendered trace step (a [data-turn-index] element) rather than a # separate card list at the bottom. Falls back to the card list if no # trace step elements are present (e.g. non-trace displays). inline_with_trace = bool(annotation_scheme.get("inline_with_trace", False)) layout_attrs = generate_layout_attributes(annotation_scheme) validation = generate_validation_attribute(annotation_scheme) identifiers = generate_element_identifier(schema_name, schema_name, "hidden") esc_schema = escape_html_content(schema_name) config_json = json.dumps({ "steps_key": steps_key, "step_text_key": step_text_key, "mode": mode, "inline_with_trace": inline_with_trace, }) container_class = "process-reward-container" if inline_with_trace: container_class += " prm-inline-mode" html = f"""
{escape_html_content(description)}
Mode: {escape_html_content(mode.replace('_', ' ').title())} {' — click the first incorrect step' if mode == 'first_error' else ' — rate each step independently'}
""" logger.info( f"Successfully generated process_reward layout for {schema_name} " f"(mode={mode})" ) return html, [] # No keybindings