opik-optimizer 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opik_optimizer/__init__.py +65 -0
- opik_optimizer/_throttle.py +43 -0
- opik_optimizer/base_optimizer.py +240 -0
- opik_optimizer/cache_config.py +24 -0
- opik_optimizer/demo/__init__.py +7 -0
- opik_optimizer/demo/cache.py +112 -0
- opik_optimizer/demo/datasets.py +656 -0
- opik_optimizer/few_shot_bayesian_optimizer/__init__.py +5 -0
- opik_optimizer/few_shot_bayesian_optimizer/few_shot_bayesian_optimizer.py +408 -0
- opik_optimizer/few_shot_bayesian_optimizer/prompt_parameter.py +91 -0
- opik_optimizer/few_shot_bayesian_optimizer/prompt_templates.py +80 -0
- opik_optimizer/integrations/__init__.py +0 -0
- opik_optimizer/logging_config.py +69 -0
- opik_optimizer/meta_prompt_optimizer.py +1100 -0
- opik_optimizer/mipro_optimizer/__init__.py +1 -0
- opik_optimizer/mipro_optimizer/_lm.py +394 -0
- opik_optimizer/mipro_optimizer/_mipro_optimizer_v2.py +1058 -0
- opik_optimizer/mipro_optimizer/mipro_optimizer.py +395 -0
- opik_optimizer/mipro_optimizer/utils.py +107 -0
- opik_optimizer/optimization_config/__init__.py +0 -0
- opik_optimizer/optimization_config/configs.py +35 -0
- opik_optimizer/optimization_config/mappers.py +49 -0
- opik_optimizer/optimization_result.py +211 -0
- opik_optimizer/task_evaluator.py +102 -0
- opik_optimizer/utils.py +132 -0
- opik_optimizer-0.7.0.dist-info/METADATA +35 -0
- opik_optimizer-0.7.0.dist-info/RECORD +30 -0
- opik_optimizer-0.7.0.dist-info/WHEEL +5 -0
- opik_optimizer-0.7.0.dist-info/licenses/LICENSE +21 -0
- opik_optimizer-0.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,211 @@
|
|
1
|
+
"""Module containing the OptimizationResult class."""
|
2
|
+
|
3
|
+
from typing import Dict, List, Any, Optional, Union, Literal
|
4
|
+
import pydantic
|
5
|
+
from opik.evaluation.metrics import BaseMetric
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
from .base_optimizer import OptimizationRound # Adjust import as necessary
|
8
|
+
import rich
|
9
|
+
|
10
|
+
|
11
|
+
class OptimizationResult(pydantic.BaseModel):
|
12
|
+
"""Result of an optimization run."""
|
13
|
+
|
14
|
+
prompt: Union[str, List[Dict[Literal["role", "content"], str]]]
|
15
|
+
score: float
|
16
|
+
metric_name: str
|
17
|
+
metadata: Dict[str, Any] = pydantic.Field(
|
18
|
+
default_factory=dict
|
19
|
+
) # Default empty dict
|
20
|
+
details: Dict[str, Any] = pydantic.Field(default_factory=dict) # Default empty dict
|
21
|
+
best_prompt: Optional[str] = None
|
22
|
+
best_score: Optional[float] = None
|
23
|
+
best_metric_name: Optional[str] = None
|
24
|
+
best_details: Optional[Dict[str, Any]] = None
|
25
|
+
all_results: Optional[List[Dict[str, Any]]] = None
|
26
|
+
history: List[Dict[str, Any]] = []
|
27
|
+
metric: Optional[BaseMetric] = None
|
28
|
+
demonstrations: Optional[List[Dict[str, Any]]] = None
|
29
|
+
optimizer: str = "Optimizer"
|
30
|
+
tool_prompts: Optional[Dict[str, str]] = None
|
31
|
+
|
32
|
+
model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)
|
33
|
+
|
34
|
+
def _calculate_improvement_str(self) -> str:
|
35
|
+
"""Helper to calculate improvement percentage string."""
|
36
|
+
initial_s = self.details.get("initial_score")
|
37
|
+
final_s = self.score
|
38
|
+
|
39
|
+
# Check if initial score exists and is a number
|
40
|
+
if not isinstance(initial_s, (int, float)):
|
41
|
+
return "[dim]N/A (no initial score)[/dim]"
|
42
|
+
|
43
|
+
# Proceed with calculation only if initial_s is valid
|
44
|
+
if initial_s != 0:
|
45
|
+
improvement_pct = (final_s - initial_s) / abs(initial_s)
|
46
|
+
# Basic coloring for rich, plain for str
|
47
|
+
color_start = ""
|
48
|
+
color_end = ""
|
49
|
+
if improvement_pct > 0:
|
50
|
+
color_start, color_end = "[bold green]", "[/bold green]"
|
51
|
+
elif improvement_pct < 0:
|
52
|
+
color_start, color_end = "[bold red]", "[/bold red]"
|
53
|
+
return f"{color_start}{improvement_pct:.2%}{color_end}"
|
54
|
+
elif final_s > 0:
|
55
|
+
return "[bold green]infinite[/bold green] (initial score was 0)"
|
56
|
+
else:
|
57
|
+
return "0.00% (no improvement from 0)"
|
58
|
+
|
59
|
+
def __str__(self) -> str:
|
60
|
+
"""Provides a clean, well-formatted plain-text summary."""
|
61
|
+
separator = "=" * 80
|
62
|
+
rounds_ran = len(self.details.get("rounds", []))
|
63
|
+
initial_score = self.details.get("initial_score")
|
64
|
+
initial_score_str = (
|
65
|
+
f"{initial_score:.4f}" if isinstance(initial_score, (int, float)) else "N/A"
|
66
|
+
)
|
67
|
+
final_score_str = f"{self.score:.4f}"
|
68
|
+
improvement_str = (
|
69
|
+
self._calculate_improvement_str()
|
70
|
+
.replace("[bold green]", "")
|
71
|
+
.replace("[/bold green]", "")
|
72
|
+
.replace("[bold red]", "")
|
73
|
+
.replace("[/bold red]", "")
|
74
|
+
.replace("[dim]", "")
|
75
|
+
.replace("[/dim]", "")
|
76
|
+
)
|
77
|
+
stopped_early = self.details.get("stopped_early", "N/A")
|
78
|
+
|
79
|
+
model_name = self.details.get("model", "N/A")
|
80
|
+
temp = self.details.get("temperature")
|
81
|
+
temp_str = f"{temp:.1f}" if isinstance(temp, (int, float)) else "N/A"
|
82
|
+
|
83
|
+
final_prompt_display = self.prompt
|
84
|
+
if self.details.get("prompt_type") == "chat" and self.details.get(
|
85
|
+
"chat_messages"
|
86
|
+
):
|
87
|
+
try:
|
88
|
+
chat_display = "\n".join(
|
89
|
+
[
|
90
|
+
f" {msg.get('role', 'unknown')}: {str(msg.get('content', ''))[:150]}..."
|
91
|
+
for msg in self.details["chat_messages"]
|
92
|
+
]
|
93
|
+
)
|
94
|
+
final_prompt_display = f"Instruction:\n {self.prompt}\nFew-Shot Examples (Chat Structure):\n{chat_display}"
|
95
|
+
except Exception:
|
96
|
+
pass
|
97
|
+
|
98
|
+
output = [
|
99
|
+
f"\n{separator}",
|
100
|
+
f"OPTIMIZATION COMPLETE",
|
101
|
+
f"{separator}",
|
102
|
+
f"Optimizer: {self.details.get('optimizer', type(self).__name__)}",
|
103
|
+
f"Model Used: {model_name} (Temp: {temp_str})",
|
104
|
+
f"Metric Evaluated: {self.metric_name}",
|
105
|
+
f"Initial Score: {initial_score_str}",
|
106
|
+
f"Final Best Score: {final_score_str}",
|
107
|
+
f"Total Improvement:{improvement_str.rjust(max(0, 18 - len('Total Improvement:')))}",
|
108
|
+
f"Rounds Completed: {rounds_ran}",
|
109
|
+
f"Stopped Early: {stopped_early}",
|
110
|
+
f"\nFINAL OPTIMIZED PROMPT / STRUCTURE:",
|
111
|
+
f"--------------------------------------------------------------------------------",
|
112
|
+
f"{final_prompt_display}",
|
113
|
+
f"--------------------------------------------------------------------------------",
|
114
|
+
f"{separator}",
|
115
|
+
]
|
116
|
+
return "\n".join(output)
|
117
|
+
|
118
|
+
def __rich__(self) -> rich.panel.Panel:
|
119
|
+
"""Provides a rich, formatted output for terminals supporting Rich."""
|
120
|
+
improvement_str = self._calculate_improvement_str()
|
121
|
+
rounds_ran = len(self.details.get("rounds", []))
|
122
|
+
initial_score = self.details.get("initial_score")
|
123
|
+
initial_score_str = (
|
124
|
+
f"{initial_score:.4f}"
|
125
|
+
if isinstance(initial_score, (int, float))
|
126
|
+
else "[dim]N/A[/dim]"
|
127
|
+
)
|
128
|
+
final_score_str = f"{self.score:.4f}"
|
129
|
+
stopped_early = self.details.get("stopped_early", "N/A")
|
130
|
+
|
131
|
+
model_name = self.details.get("model", "[dim]N/A[/dim]")
|
132
|
+
temp = self.details.get("temperature")
|
133
|
+
temp_str = f"{temp:.1f}" if isinstance(temp, (int, float)) else "[dim]N/A[/dim]"
|
134
|
+
|
135
|
+
table = rich.table.Table.grid(padding=(0, 1))
|
136
|
+
table.add_column(style="dim")
|
137
|
+
table.add_column()
|
138
|
+
|
139
|
+
table.add_row(
|
140
|
+
"Optimizer:",
|
141
|
+
f"[bold]{self.details.get('optimizer', type(self).__name__)}[/bold]",
|
142
|
+
)
|
143
|
+
table.add_row("Model Used:", f"{model_name} ([dim]Temp:[/dim] {temp_str})")
|
144
|
+
table.add_row("Metric Evaluated:", f"[bold]{self.metric_name}[/bold]")
|
145
|
+
table.add_row("Initial Score:", initial_score_str)
|
146
|
+
table.add_row("Final Best Score:", f"[bold cyan]{final_score_str}[/bold cyan]")
|
147
|
+
table.add_row("Total Improvement:", improvement_str)
|
148
|
+
table.add_row("Rounds Completed:", str(rounds_ran))
|
149
|
+
table.add_row("Stopped Early:", str(stopped_early))
|
150
|
+
|
151
|
+
# Display Chat Structure if available
|
152
|
+
prompt_renderable: Any = rich.text.Text(
|
153
|
+
self.prompt or "", overflow="fold"
|
154
|
+
) # Default to text
|
155
|
+
panel_title = "[bold]Final Optimized Prompt (Instruction)[/bold]"
|
156
|
+
|
157
|
+
if self.details.get("prompt_type") == "chat" and self.details.get(
|
158
|
+
"chat_messages"
|
159
|
+
):
|
160
|
+
panel_title = "[bold]Final Optimized Prompt (Chat Structure)[/bold]"
|
161
|
+
try:
|
162
|
+
chat_group_items = [
|
163
|
+
f"[dim]Instruction:[/dim] [i]{self.prompt}[/i]\n---"
|
164
|
+
]
|
165
|
+
for msg in self.details["chat_messages"]:
|
166
|
+
role = msg.get("role", "unknown")
|
167
|
+
content = str(msg.get("content", ""))
|
168
|
+
role_style = (
|
169
|
+
"bold green"
|
170
|
+
if role == "user"
|
171
|
+
else (
|
172
|
+
"bold blue"
|
173
|
+
if role == "assistant"
|
174
|
+
else ("bold magenta" if role == "system" else "")
|
175
|
+
)
|
176
|
+
)
|
177
|
+
chat_group_items.append(
|
178
|
+
f"[{role_style}]{role.capitalize()}:[/] {content}"
|
179
|
+
)
|
180
|
+
chat_group_items.append("---") # Separator
|
181
|
+
prompt_renderable = rich.console.Group(*chat_group_items)
|
182
|
+
|
183
|
+
except Exception:
|
184
|
+
# Fallback to simple text prompt
|
185
|
+
prompt_renderable = rich.text.Text(self.prompt or "", overflow="fold")
|
186
|
+
panel_title = (
|
187
|
+
"[bold]Final Optimized Prompt (Instruction - fallback)[/bold]"
|
188
|
+
)
|
189
|
+
|
190
|
+
prompt_panel = rich.panel.Panel(
|
191
|
+
prompt_renderable, title=panel_title, border_style="blue", padding=(1, 2)
|
192
|
+
)
|
193
|
+
|
194
|
+
content_group = rich.console.Group(table, "\n", prompt_panel)
|
195
|
+
|
196
|
+
return rich.panel.Panel(
|
197
|
+
content_group,
|
198
|
+
title="[bold yellow]Optimization Complete[/bold yellow]",
|
199
|
+
border_style="yellow",
|
200
|
+
box=rich.box.DOUBLE_EDGE,
|
201
|
+
padding=1,
|
202
|
+
)
|
203
|
+
|
204
|
+
def model_dump(self) -> Dict[str, Any]:
|
205
|
+
return super().model_dump()
|
206
|
+
|
207
|
+
def display(self) -> None:
|
208
|
+
"""
|
209
|
+
Displays the OptimizationResult using rich formatting
|
210
|
+
"""
|
211
|
+
rich.print(self)
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import opik
|
2
|
+
|
3
|
+
from typing import Any, Callable, Dict, List, Optional
|
4
|
+
from opik_optimizer.optimization_config.configs import MetricConfig
|
5
|
+
from opik.evaluation.metrics import score_result
|
6
|
+
|
7
|
+
from opik.evaluation import evaluator as opik_evaluator
|
8
|
+
|
9
|
+
|
10
|
+
def evaluate(
|
11
|
+
dataset: opik.Dataset,
|
12
|
+
evaluated_task: Callable[[Dict[str, Any]], Dict[str, Any]],
|
13
|
+
metric_config: MetricConfig,
|
14
|
+
num_threads: int,
|
15
|
+
optimization_id: Optional[str] = None,
|
16
|
+
dataset_item_ids: Optional[List[str]] = None,
|
17
|
+
project_name: Optional[str] = None,
|
18
|
+
n_samples: Optional[int] = None,
|
19
|
+
experiment_config: Optional[Dict[str, Any]] = None,
|
20
|
+
) -> float:
|
21
|
+
"""
|
22
|
+
Evaluate a task on a dataset.
|
23
|
+
|
24
|
+
Args:
|
25
|
+
dataset: A list of dictionaries representing the dataset.
|
26
|
+
metric_config: The metric configuration to use for evaluation.
|
27
|
+
evaluated_task: A function that takes a dataset item dict as input and returns a dictionary with output(s).
|
28
|
+
dataset_item_ids: Optional list of dataset item IDs to evaluate.
|
29
|
+
project_name: Optional project name for evaluation.
|
30
|
+
n_samples: Optional number of test examples to perform the evaluation and then stop.
|
31
|
+
num_threads: Number of threads to use for evaluation.
|
32
|
+
experiment_config: The dictionary with parameters that describe experiment
|
33
|
+
optimization_id: Optional optimization ID for the experiment.
|
34
|
+
|
35
|
+
Returns:
|
36
|
+
float: The average score of the evaluated task.
|
37
|
+
"""
|
38
|
+
items = dataset.get_items(dataset_item_ids)
|
39
|
+
if not items:
|
40
|
+
print("[DEBUG] Empty dataset, returning 0.0")
|
41
|
+
return 0.0
|
42
|
+
|
43
|
+
if dataset_item_ids:
|
44
|
+
items = [item for item in items if item.get("id") in dataset_item_ids]
|
45
|
+
|
46
|
+
if n_samples:
|
47
|
+
items = items[:n_samples]
|
48
|
+
|
49
|
+
# TODO: move to debug logger
|
50
|
+
# print(f"[DEBUG] Starting evaluation with task: {evaluated_task}")
|
51
|
+
# print(f"[DEBUG] Items to evaluate: {items}")
|
52
|
+
# print(f"[DEBUG] Metric config inputs: {metric_config.inputs}")
|
53
|
+
# print(f"[DEBUG] Number of threads: {num_threads}")
|
54
|
+
# print(f"[DEBUG] Project name: {project_name}")
|
55
|
+
|
56
|
+
scoring_key_mapping = {
|
57
|
+
key: value if isinstance(value, str) else value.__name__
|
58
|
+
for key, value in metric_config.inputs.items()
|
59
|
+
}
|
60
|
+
scoring_key_mapping["output"] = "_llm_task_output"
|
61
|
+
|
62
|
+
if optimization_id is not None:
|
63
|
+
result = opik_evaluator.evaluate_optimization_trial(
|
64
|
+
optimization_id=optimization_id,
|
65
|
+
dataset=dataset,
|
66
|
+
task=evaluated_task,
|
67
|
+
project_name=project_name,
|
68
|
+
scoring_key_mapping=scoring_key_mapping,
|
69
|
+
dataset_item_ids=dataset_item_ids,
|
70
|
+
scoring_metrics=[metric_config.metric],
|
71
|
+
task_threads=num_threads,
|
72
|
+
nb_samples=n_samples,
|
73
|
+
experiment_config=experiment_config,
|
74
|
+
)
|
75
|
+
else:
|
76
|
+
result = opik_evaluator.evaluate(
|
77
|
+
dataset=dataset,
|
78
|
+
task=evaluated_task,
|
79
|
+
project_name=project_name,
|
80
|
+
scoring_key_mapping=scoring_key_mapping,
|
81
|
+
dataset_item_ids=dataset_item_ids,
|
82
|
+
scoring_metrics=[metric_config.metric],
|
83
|
+
task_threads=num_threads,
|
84
|
+
nb_samples=n_samples,
|
85
|
+
experiment_config=experiment_config,
|
86
|
+
)
|
87
|
+
|
88
|
+
if not result.test_results:
|
89
|
+
return 0.0
|
90
|
+
|
91
|
+
# We may allow score aggregation customization.
|
92
|
+
score_results: List[score_result.ScoreResult] = [
|
93
|
+
test_result.score_results[0] for test_result in result.test_results
|
94
|
+
]
|
95
|
+
if not score_results:
|
96
|
+
return 0.0
|
97
|
+
|
98
|
+
avg_score = sum([score_result_.value for score_result_ in score_results]) / len(
|
99
|
+
score_results
|
100
|
+
)
|
101
|
+
|
102
|
+
return avg_score
|
opik_optimizer/utils.py
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
"""Utility functions and constants for the optimizer package."""
|
2
|
+
|
3
|
+
import opik
|
4
|
+
import logging
|
5
|
+
import random
|
6
|
+
import string
|
7
|
+
from opik.api_objects.opik_client import Opik
|
8
|
+
|
9
|
+
from typing import List, Dict, Any, Optional, Callable, TYPE_CHECKING
|
10
|
+
|
11
|
+
# Test dataset name for optimizer examples
|
12
|
+
TEST_DATASET_NAME = "tiny-test-optimizer"
|
13
|
+
|
14
|
+
# Type hint for OptimizationResult without circular import
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from .optimization_result import OptimizationResult
|
17
|
+
|
18
|
+
logger = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
|
21
|
+
def format_prompt(prompt: str, **kwargs: Any) -> str:
|
22
|
+
"""
|
23
|
+
Format a prompt string with the given keyword arguments.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
prompt: The prompt string to format
|
27
|
+
**kwargs: Keyword arguments to format into the prompt
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
str: The formatted prompt string
|
31
|
+
|
32
|
+
Raises:
|
33
|
+
ValueError: If any required keys are missing from kwargs
|
34
|
+
"""
|
35
|
+
try:
|
36
|
+
return prompt.format(**kwargs)
|
37
|
+
except KeyError as e:
|
38
|
+
raise ValueError(f"Missing required key in prompt: {e}")
|
39
|
+
|
40
|
+
|
41
|
+
def validate_prompt(prompt: str) -> bool:
|
42
|
+
"""
|
43
|
+
Validate a prompt string.
|
44
|
+
|
45
|
+
Args:
|
46
|
+
prompt: The prompt string to validate
|
47
|
+
|
48
|
+
Returns:
|
49
|
+
bool: True if the prompt is valid, False otherwise
|
50
|
+
"""
|
51
|
+
if not prompt or not prompt.strip():
|
52
|
+
return False
|
53
|
+
return True
|
54
|
+
|
55
|
+
|
56
|
+
def setup_logging(log_level: str = "INFO") -> None:
|
57
|
+
"""
|
58
|
+
Setup logging configuration.
|
59
|
+
|
60
|
+
Args:
|
61
|
+
log_level: The log level to use (default: INFO)
|
62
|
+
"""
|
63
|
+
valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
64
|
+
if log_level not in valid_levels:
|
65
|
+
raise ValueError(f"Invalid log level. Must be one of {valid_levels}")
|
66
|
+
|
67
|
+
numeric_level = getattr(logging, log_level.upper())
|
68
|
+
logging.basicConfig(level=numeric_level)
|
69
|
+
|
70
|
+
|
71
|
+
def get_random_seed() -> int:
|
72
|
+
"""
|
73
|
+
Get a random seed for reproducibility.
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
int: A random seed
|
77
|
+
"""
|
78
|
+
import random
|
79
|
+
|
80
|
+
return random.randint(0, 2**32 - 1)
|
81
|
+
|
82
|
+
|
83
|
+
def get_or_create_dataset(
|
84
|
+
dataset_name: str,
|
85
|
+
description: str,
|
86
|
+
data_loader: Callable[[], List[Dict[str, Any]]],
|
87
|
+
project_name: Optional[str] = None,
|
88
|
+
) -> opik.Dataset:
|
89
|
+
"""
|
90
|
+
Get an existing dataset or create a new one if it doesn't exist.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
dataset_name: Name of the dataset
|
94
|
+
description: Description of the dataset
|
95
|
+
data: Optional data to insert into the dataset
|
96
|
+
project_name: Optional project name
|
97
|
+
|
98
|
+
Returns:
|
99
|
+
opik.Dataset: The dataset object
|
100
|
+
"""
|
101
|
+
client = Opik(project_name=project_name)
|
102
|
+
|
103
|
+
try:
|
104
|
+
# Try to get existing dataset
|
105
|
+
dataset = client.get_dataset(dataset_name)
|
106
|
+
# If dataset exists but has no data, delete it
|
107
|
+
if not dataset.get_items():
|
108
|
+
print("Dataset exists but is empty - deleting it...")
|
109
|
+
# Delete all items in the dataset
|
110
|
+
items = dataset.get_items()
|
111
|
+
if items:
|
112
|
+
dataset.delete(items_ids=[item.id for item in items])
|
113
|
+
# Delete the dataset itself
|
114
|
+
client.delete_dataset(dataset_name)
|
115
|
+
raise Exception("Dataset deleted, will create new one")
|
116
|
+
except Exception:
|
117
|
+
# Create new dataset
|
118
|
+
print("Creating new dataset...")
|
119
|
+
dataset = client.create_dataset(name=dataset_name, description=description)
|
120
|
+
|
121
|
+
dataset_items = data_loader()
|
122
|
+
dataset.insert(dataset_items)
|
123
|
+
|
124
|
+
# Verify data was added
|
125
|
+
if not dataset.get_items():
|
126
|
+
raise Exception("Failed to add data to dataset")
|
127
|
+
|
128
|
+
return dataset
|
129
|
+
|
130
|
+
|
131
|
+
def random_chars(n: int) -> str:
|
132
|
+
return "".join(random.choice(string.ascii_letters) for _ in range(n))
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: opik_optimizer
|
3
|
+
Version: 0.7.0
|
4
|
+
Summary: Agent optimization with Opik
|
5
|
+
Home-page: https://github.com/comet-ml/opik
|
6
|
+
Author: Comet ML
|
7
|
+
Author-email: info@comet.ml
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
9
|
+
Classifier: Intended Audience :: Developers
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
12
|
+
Requires-Python: >=3.9
|
13
|
+
License-File: LICENSE
|
14
|
+
Requires-Dist: opik>=1.7.17
|
15
|
+
Requires-Dist: dspy<3,>=2.6.18
|
16
|
+
Requires-Dist: litellm
|
17
|
+
Requires-Dist: tqdm
|
18
|
+
Requires-Dist: datasets
|
19
|
+
Requires-Dist: optuna
|
20
|
+
Requires-Dist: pydantic
|
21
|
+
Requires-Dist: pandas
|
22
|
+
Requires-Dist: hf_xet
|
23
|
+
Provides-Extra: dev
|
24
|
+
Requires-Dist: adalflow; extra == "dev"
|
25
|
+
Requires-Dist: pytest; extra == "dev"
|
26
|
+
Requires-Dist: pytest-conv; extra == "dev"
|
27
|
+
Dynamic: author
|
28
|
+
Dynamic: author-email
|
29
|
+
Dynamic: classifier
|
30
|
+
Dynamic: home-page
|
31
|
+
Dynamic: license-file
|
32
|
+
Dynamic: provides-extra
|
33
|
+
Dynamic: requires-dist
|
34
|
+
Dynamic: requires-python
|
35
|
+
Dynamic: summary
|
@@ -0,0 +1,30 @@
|
|
1
|
+
opik_optimizer/__init__.py,sha256=RQc6N4ca7WS34oXGx6pQQjAh9QVRfjtX6dlVS1oJvLw,1847
|
2
|
+
opik_optimizer/_throttle.py,sha256=7vcHoISqXbysymwdb1LPAFJB28tOmih9zzZQWajpH0k,1494
|
3
|
+
opik_optimizer/base_optimizer.py,sha256=mHi5b_8Ang6o_kl9m0x8NyXMRYq9OFyaidRfw_wWdEY,8348
|
4
|
+
opik_optimizer/cache_config.py,sha256=EzF4RAzxhSG8vtMJANdiUpNHQ9HzL2CrCXp0iik0f4A,580
|
5
|
+
opik_optimizer/logging_config.py,sha256=ELevhxtflYinTo-jVvyQYZbXG7FgAe_b5dPa9y5uLWw,2774
|
6
|
+
opik_optimizer/meta_prompt_optimizer.py,sha256=tRxA4YD2AWvKl7fJNg6Oxxay8iyqvdJ8zXy59-qKyUM,46802
|
7
|
+
opik_optimizer/optimization_result.py,sha256=e8isosO43o4YOuVr7yYBE_4m_36wodQ9OJ5WC35Mjzo,8765
|
8
|
+
opik_optimizer/task_evaluator.py,sha256=MafDMaLeW0_yGPrumLvYF0HzQUKrnpAlM_0N_TPG8tw,3695
|
9
|
+
opik_optimizer/utils.py,sha256=HivUsNzbt7BcuZeEvikdER1DaTPUFLJrpaVQ8raZYD8,3637
|
10
|
+
opik_optimizer/demo/__init__.py,sha256=KSpFYhzN7fTmLEsIaciRHwxcJDeAiX5NDmYLdPsfpT8,150
|
11
|
+
opik_optimizer/demo/cache.py,sha256=U0ovsBT7s39RSy34Mr-vTacdVk_jERKbRhdlGT6gF_0,3562
|
12
|
+
opik_optimizer/demo/datasets.py,sha256=hD6JZAQotEDQb4nK7dbnurquILqQsrFRF7nUwon_iXE,22930
|
13
|
+
opik_optimizer/few_shot_bayesian_optimizer/__init__.py,sha256=VuH7FOROyGcjMPryejtZC-5Y0QHlVTFLTGUDgNqRAFw,113
|
14
|
+
opik_optimizer/few_shot_bayesian_optimizer/few_shot_bayesian_optimizer.py,sha256=zh88ElxKcoIkgkwZyXlQ0rwkxkPAoG8BW0DdvRpPhyQ,15106
|
15
|
+
opik_optimizer/few_shot_bayesian_optimizer/prompt_parameter.py,sha256=EDsSIFAUOfiZKWLrOAaBDB7Exk7cmIs4ccI95kVa7JY,3118
|
16
|
+
opik_optimizer/few_shot_bayesian_optimizer/prompt_templates.py,sha256=HmvD-UeT3aKiiet5cUtULXe6iFPEOo6hxyDE0pH2LnQ,2424
|
17
|
+
opik_optimizer/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
opik_optimizer/mipro_optimizer/__init__.py,sha256=CF9TVXjOxTobDO1kAS8CD4eyLVzEozxjfgoKwIO6ZpU,44
|
19
|
+
opik_optimizer/mipro_optimizer/_lm.py,sha256=UwSEcTLVIt_a-coQbLACNnm-RTMJIzLEyPS4qLfUosg,16316
|
20
|
+
opik_optimizer/mipro_optimizer/_mipro_optimizer_v2.py,sha256=r8FKaqvtZq_R7FwGnXqp1foCLk7M7r6M-CMvWbJtP5c,39512
|
21
|
+
opik_optimizer/mipro_optimizer/mipro_optimizer.py,sha256=5QS7OKqOMKe4CD_8W2FMD_qJNmulkvxmOT_YtJ3BllM,14755
|
22
|
+
opik_optimizer/mipro_optimizer/utils.py,sha256=4et1JA1QInX3h6Is-_RqzliFwJqkm6tlA0X5CryG60I,3142
|
23
|
+
opik_optimizer/optimization_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
+
opik_optimizer/optimization_config/configs.py,sha256=MYL9H2UAqeyGBlBGWbOZ-6Snto4ZMuXnypgvVuUSW1Y,1132
|
25
|
+
opik_optimizer/optimization_config/mappers.py,sha256=RXgTMxPzTQ1AHGke6Zca6rTcfCI7IkCKhQYciaEGSAo,1698
|
26
|
+
opik_optimizer-0.7.0.dist-info/licenses/LICENSE,sha256=dTRSwwCHdWeSjzodvnivYqcwi8x3Qfr21yv65QUWWBE,1062
|
27
|
+
opik_optimizer-0.7.0.dist-info/METADATA,sha256=2M3tCmbCp4kIYzsfF2E_7u3ntgl5VNC7AGwXPKNsWWc,962
|
28
|
+
opik_optimizer-0.7.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
29
|
+
opik_optimizer-0.7.0.dist-info/top_level.txt,sha256=ondOlpq6_yFckqpxoAHSfzZS2N-JfgmA-QQhOJfz7m0,15
|
30
|
+
opik_optimizer-0.7.0.dist-info/RECORD,,
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Comet
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1 @@
|
|
1
|
+
opik_optimizer
|