Skip to content

Commit 31c8385

Browse files
committed
feat: add shared dataclass for calls so they can be handled by same handler
1 parent 149aa76 commit 31c8385

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

packages/optimization/src/ldai_optimization/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
AIJudgeCallConfig,
1111
GroundTruthOptimizationOptions,
1212
GroundTruthSample,
13+
LLMCallConfig,
1314
OptimizationContext,
1415
OptimizationFromConfigOptions,
1516
OptimizationJudge,
@@ -28,6 +29,7 @@
2829
'GroundTruthOptimizationOptions',
2930
'GroundTruthSample',
3031
'LDApiError',
32+
'LLMCallConfig',
3133
'OptimizationClient',
3234
'OptimizationContext',
3335
'OptimizationFromConfigOptions',

packages/optimization/src/ldai_optimization/dataclasses.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
Sequence,
1515
Union,
1616
)
17+
from typing_extensions import Protocol
1718

1819
from ldai import AIAgentConfig
1920
from ldai.models import LDMessage, ModelConfig
@@ -108,6 +109,33 @@ def from_dict(cls, data: Dict[str, Any]) -> "ToolDefinition":
108109
)
109110

110111

112+
class LLMCallConfig(Protocol):
113+
"""Structural protocol satisfied by both ``AIAgentConfig`` and ``AIJudgeCallConfig``.
114+
115+
Use this as the config parameter type when you want a single handler function
116+
that can be passed to both ``handle_agent_call`` and ``handle_judge_call``::
117+
118+
async def handle_llm_call(
119+
key: str,
120+
config: LLMCallConfig,
121+
context: Union[OptimizationContext, OptimizationJudgeContext],
122+
) -> OptimizationResponse:
123+
model_name = config.model.name if config.model else "gpt-4o"
124+
instructions = config.instructions or ""
125+
...
126+
127+
OptimizationOptions(
128+
handle_agent_call=handle_llm_call,
129+
handle_judge_call=handle_llm_call,
130+
...
131+
)
132+
"""
133+
134+
key: str
135+
model: Optional[ModelConfig]
136+
instructions: Optional[str]
137+
138+
111139
@dataclass
112140
class AIJudgeCallConfig:
113141
"""

packages/optimization/tests/test_client.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,16 @@ async def test_commit_not_called_when_run_fails(self):
38183818

38193819
mock_commit.assert_not_called()
38203820

3821+
async def test_succeeds_without_api_key_when_auto_commit_false(self):
3822+
client = self._make_client_without_key()
3823+
options = _make_options() # auto_commit defaults to False
3824+
3825+
with patch("ldai_optimization.client.LDApiClient") as mock_api_cls:
3826+
result = await client.optimize_from_options("test-agent", options)
3827+
3828+
mock_api_cls.assert_not_called()
3829+
assert result is not None
3830+
38213831
async def test_raises_when_auto_commit_true_and_no_api_key(self):
38223832
client = self._make_client_without_key()
38233833
options = _make_options(auto_commit=True, project_key="my-project")

0 commit comments

Comments
 (0)