Skip to content

Commit d3dca0b

Browse files
committed
fix: added back the utils functions
1 parent e13cac9 commit d3dca0b

3 files changed

Lines changed: 228 additions & 0 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the terms described in the LICENSE file in
5+
# the root directory of this source tree.
6+
"""
7+
Utility functions for working with optimization strategies.
8+
"""
9+
10+
from typing import Literal, Optional
11+
12+
13+
def map_auto_mode_to_dspy(
14+
auto_mode: Optional[Literal["basic", "intermediate", "advanced"]],
15+
) -> str:
16+
"""Map our naming convention to DSPy's expected values.
17+
18+
Args:
19+
auto_mode: Our naming convention ('basic', 'intermediate', 'advanced')
20+
21+
Returns:
22+
The corresponding DSPy auto mode ('light', 'medium', 'heavy')
23+
"""
24+
mapping = {"basic": "light", "intermediate": "medium", "advanced": "heavy"}
25+
return mapping.get(auto_mode, "light") # Default to light if not found
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
Summary utilities for creating and managing optimization summaries.
3+
4+
This module provides utility functions for creating pre-optimization summaries
5+
in a clean, testable, and reusable way.
6+
"""
7+
8+
import logging
9+
from typing import Any, Dict, Optional
10+
11+
from .telemetry import PreOptimizationSummary
12+
13+
14+
def create_pre_optimization_summary(
15+
strategy, prompt_data: Dict[str, Any]
16+
) -> PreOptimizationSummary:
17+
"""
18+
Create a pre-optimization summary from strategy data.
19+
20+
This utility function extracts summary creation logic from strategy classes,
21+
making it testable in isolation and reusable across different strategies.
22+
23+
Args:
24+
strategy: The optimization strategy instance (BaseStrategy or subclass)
25+
prompt_data: The prompt data being optimized
26+
27+
Returns:
28+
PreOptimizationSummary instance ready for display/logging
29+
"""
30+
# Import here to avoid circular imports
31+
from ..prompt_strategies import map_auto_mode_to_dspy
32+
33+
# Collect guidance information
34+
guidance = None
35+
if (
36+
hasattr(strategy, "proposer_kwargs")
37+
and strategy.proposer_kwargs
38+
and "tip" in strategy.proposer_kwargs
39+
):
40+
guidance = strategy.proposer_kwargs["tip"]
41+
42+
# Compute baseline score if enabled
43+
baseline_score = None
44+
if getattr(strategy, "compute_baseline", False):
45+
try:
46+
if hasattr(strategy, "_compute_baseline_score"):
47+
baseline_score = strategy._compute_baseline_score(prompt_data)
48+
except Exception as e:
49+
logging.warning(f"Failed to compute baseline score: {e}")
50+
51+
# Get model names using the strategy's method
52+
task_model_name = "Unknown"
53+
proposer_model_name = "Unknown"
54+
55+
if hasattr(strategy, "_get_model_name"):
56+
if hasattr(strategy, "task_model"):
57+
task_model_name = strategy._get_model_name(strategy.task_model)
58+
if hasattr(strategy, "prompt_model"):
59+
proposer_model_name = strategy._get_model_name(strategy.prompt_model)
60+
61+
# Get metric name
62+
metric_name = "None"
63+
if hasattr(strategy, "metric") and strategy.metric:
64+
metric_name = getattr(strategy.metric, "__name__", str(strategy.metric))
65+
66+
# Collect MIPRO parameters with safe defaults
67+
auto_mode = getattr(strategy, "auto", "basic")
68+
mipro_params = {
69+
"auto_user": auto_mode,
70+
"auto_dspy": map_auto_mode_to_dspy(auto_mode),
71+
"max_labeled_demos": getattr(strategy, "max_labeled_demos", 5),
72+
"max_bootstrapped_demos": getattr(strategy, "max_bootstrapped_demos", 4),
73+
"num_candidates": getattr(strategy, "num_candidates", 10),
74+
"num_threads": getattr(strategy, "num_threads", 18),
75+
"init_temperature": getattr(strategy, "init_temperature", 0.5),
76+
"seed": getattr(strategy, "seed", 9),
77+
}
78+
79+
return PreOptimizationSummary(
80+
task_model=task_model_name,
81+
proposer_model=proposer_model_name,
82+
metric_name=metric_name,
83+
train_size=len(getattr(strategy, "trainset", []) or []),
84+
val_size=len(getattr(strategy, "valset", []) or []),
85+
mipro_params=mipro_params,
86+
guidance=guidance,
87+
baseline_score=baseline_score,
88+
)
89+
90+
91+
def create_and_display_summary(
92+
strategy, prompt_data: Dict[str, Any]
93+
) -> PreOptimizationSummary:
94+
"""
95+
Convenience function to create and display a pre-optimization summary.
96+
97+
Args:
98+
strategy: The optimization strategy instance
99+
prompt_data: The prompt data being optimized
100+
101+
Returns:
102+
The created PreOptimizationSummary instance
103+
"""
104+
try:
105+
summary = create_pre_optimization_summary(strategy, prompt_data)
106+
summary.log()
107+
return summary
108+
except Exception as e:
109+
logging.warning(
110+
f"Failed to create or display pre-optimization summary: {str(e)}"
111+
)
112+
# Return a minimal summary to avoid breaking the optimization flow
113+
return PreOptimizationSummary(
114+
task_model="Unknown",
115+
proposer_model="Unknown",
116+
metric_name="Unknown",
117+
train_size=0,
118+
val_size=0,
119+
mipro_params={},
120+
)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the terms described in the LICENSE file in
5+
# the root directory of this source tree.
6+
"""
7+
Telemetry module for tracking and displaying optimization process information.
8+
9+
This module provides classes and utilities for collecting and displaying
10+
key information about the optimization process before it begins.
11+
"""
12+
13+
import json
14+
from dataclasses import asdict, dataclass
15+
from typing import Any, Dict, Optional
16+
17+
from .logging import get_logger
18+
19+
20+
@dataclass
21+
class PreOptimizationSummary:
22+
"""
23+
Container for pre-optimization summary information.
24+
25+
This class collects and formats key information about the optimization
26+
process that will be displayed to users before optimization begins.
27+
"""
28+
29+
task_model: str
30+
proposer_model: str
31+
metric_name: str
32+
train_size: int
33+
val_size: int
34+
mipro_params: Dict[str, Any]
35+
guidance: Optional[str] = None
36+
baseline_score: Optional[float] = None
37+
38+
def to_pretty(self) -> str:
39+
"""
40+
Format the summary as a human-readable string.
41+
42+
Returns:
43+
A formatted string suitable for console display
44+
"""
45+
pad = " " * 4
46+
lines = [
47+
"=== Pre-Optimization Summary ===",
48+
f"{pad}Task Model : {self.task_model}",
49+
f"{pad}Proposer Model : {self.proposer_model}",
50+
f"{pad}Metric : {self.metric_name}",
51+
f"{pad}Train / Val size : {self.train_size} / {self.val_size}",
52+
f"{pad}MIPRO Params : {json.dumps(self.mipro_params, separators=(',', ':'))}",
53+
]
54+
55+
if self.guidance:
56+
# Truncate guidance for readability
57+
guidance_display = self.guidance[:120]
58+
if len(self.guidance) > 120:
59+
guidance_display += "..."
60+
lines.append(f"{pad}Guidance : {guidance_display}")
61+
62+
if self.baseline_score is not None:
63+
lines.append(f"{pad}Baseline score : {self.baseline_score:.4f}")
64+
65+
return "\n".join(lines)
66+
67+
def to_json(self) -> str:
68+
"""
69+
Convert the summary to JSON format.
70+
71+
Returns:
72+
JSON string representation of the summary
73+
"""
74+
return json.dumps(asdict(self), indent=2)
75+
76+
def log(self) -> None:
77+
"""
78+
Log the summary using the configured logger.
79+
80+
This method outputs the formatted summary at INFO level.
81+
"""
82+
logger = get_logger()
83+
logger.progress(self.to_pretty())

0 commit comments

Comments
 (0)