Repository: microsoft/promptflow
File: src/promptflow-devkit/promptflow/_sdk/operations/_run_operations.py (Python)

Code before:
            # so we directly raise error if there is any incomplete run
            run._check_run_status_is_completed()

            local_storage = LocalStorageOperations(run)
            # nan, inf and -inf are not JSON serializable, which will lead to JavaScript parse error
            # so specify `parse_const_as_str` as True to parse them as string
            detail = local_storage.load_detail(parse_const_as_str=True)
            # ad-hoc step: make logs field empty to avoid too big HTML file
            # we don't provide logs view in visualization page for now
            # when we enable, we will save those big data (e.g. logs) in separate file(s)
            # JS load can be faster than static HTML
            for i in range(len(detail["node_runs"])):
                detail["node_runs"][i]["logs"] = {"stdout": "", "stderr": ""}

            metadata = RunMetadata(
                name=run.name,
                display_name=run.display_name,
                create_time=run.created_on,
                flow_path=run.properties.get(FlowRunProperties.FLOW_PATH, None),
                output_path=run.properties[FlowRunProperties.OUTPUT_PATH],
                tags=run.tags,
                lineage=run.run,
                metrics=local_storage.load_metrics(parse_const_as_str=True),
                dag=local_storage.load_dag_as_string(),
                flow_tools_json=local_storage.load_flow_tools_json(),
                mode=EAGER.lower() if local_storage.eager_mode else "",
            )
            details.append(copy.deepcopy(detail))
            metadatas.append(asdict(metadata))
            # TODO: add language to run metadata
            flow_dag = load_yaml_string(metadata.dag) or {}
            configs.append(
                VisualizationConfig(
                    [AvailableIDE.VS_CODE]
                    if flow_dag.get(LANGUAGE_KEY, FlowLanguage.Python) == FlowLanguage.Python
                    else [AvailableIDE.VS]
                )
            )
        data_for_visualize = RunVisualization(
            detail=details,
            metadata=metadatas,
            config=configs,
        )
        html_string = generate_html_string(asdict(data_for_visualize))
        # if html_path is specified, not open it in webbrowser(as it comes from VSC)
        dump_html(html_string, html_path=html_path, open_html=html_path is None)

    @monitor_operation(activity_name="pf.runs.visualize", activity_type=ActivityType.PUBLICAPI)
    def visualize(self, runs: Union[str, Run, List[str], List[Run]], **kwargs) -> None:
        """Visualize run(s).


Review comment (suggestion):
this constant name is a little confusing. What about put it under a class like:
```python
class RunMode:
  EAGER = "eager"
```

Code after:
            # so we directly raise error if there is any incomplete run
            run._check_run_status_is_completed()

            local_storage = LocalStorageOperations(run)
            # nan, inf and -inf are not JSON serializable, which will lead to JavaScript parse error
            # so specify `parse_const_as_str` as True to parse them as string
            detail = local_storage.load_detail(parse_const_as_str=True)
            # ad-hoc step: make logs field empty to avoid too big HTML file
            # we don't provide logs view in visualization page for now
            # when we enable, we will save those big data (e.g. logs) in separate file(s)
            # JS load can be faster than static HTML
            for i in range(len(detail["node_runs"])):
                detail["node_runs"][i]["logs"] = {"stdout": "", "stderr": ""}

            metadata = RunMetadata(
                name=run.name,
                display_name=run.display_name,
                create_time=run.created_on,
                flow_path=run.properties.get(FlowRunProperties.FLOW_PATH, None),
                output_path=run.properties[FlowRunProperties.OUTPUT_PATH],
                tags=run.tags,
                lineage=run.run,
                metrics=local_storage.load_metrics(parse_const_as_str=True),
                dag=local_storage.load_dag_as_string(),
                flow_tools_json=local_storage.load_flow_tools_json(),
                mode=RunMode.EAGER.lower() if local_storage.eager_mode else "",
            )
            details.append(copy.deepcopy(detail))
            metadatas.append(asdict(metadata))
            # TODO: add language to run metadata
            flow_dag = load_yaml_string(metadata.dag) or {}
            configs.append(
                VisualizationConfig(
                    [AvailableIDE.VS_CODE]
                    if flow_dag.get(LANGUAGE_KEY, FlowLanguage.Python) == FlowLanguage.Python
                    else [AvailableIDE.VS]
                )
            )
        data_for_visualize = RunVisualization(
            detail=details,
            metadata=metadatas,
            config=configs,
        )
        html_string = generate_html_string(asdict(data_for_visualize))
        # if html_path is specified, not open it in webbrowser(as it comes from VSC)
        dump_html(html_string, html_path=html_path, open_html=html_path is None)

    @monitor_operation(activity_name="pf.runs.visualize", activity_type=ActivityType.PUBLICAPI)
    def visualize(self, runs: Union[str, Run, List[str], List[Run]], **kwargs) -> None:
        """Visualize run(s).