Skip to content

Commit 4c0451b

Browse files
jsonbaileyclaude
andcommitted
feat: Always set create_tracker as callable that returns a tracker
The create_tracker field on AIConfig is now always a callable that returns a working tracker, even when the config is disabled. The factory is always set to tracker_factory — callers use the enabled flag to decide whether to proceed, not the factory result. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ba5421a commit 4c0451b

6 files changed

Lines changed: 14 additions & 12 deletions

File tree

packages/sdk/server-ai/src/ldai/client.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def _completion_config(
9696
messages=messages,
9797
provider=provider,
9898
tracker=tracker,
99-
create_tracker=tracker_factory if enabled else None,
99+
create_tracker=tracker_factory,
100100
judge_configuration=judge_configuration,
101101
)
102102

@@ -182,7 +182,7 @@ def _extract_evaluation_metric_key(variation: Dict[str, Any]) -> Optional[str]:
182182
messages=messages,
183183
provider=provider,
184184
tracker=tracker,
185-
create_tracker=tracker_factory if enabled else None,
185+
create_tracker=tracker_factory,
186186
)
187187

188188
return config
@@ -268,7 +268,7 @@ async def create_judge(
268268
key, context, default or AIJudgeConfigDefault.disabled(), extended_variables
269269
)
270270

271-
if not judge_config.enabled or not judge_config.create_tracker:
271+
if not judge_config.enabled:
272272
return None
273273

274274
provider = RunnerFactory.create_model(judge_config, default_ai_provider)
@@ -365,7 +365,7 @@ async def create_model(
365365
log.debug(f"Creating managed model for key: {key}")
366366
config = self._completion_config(key, context, default or AICompletionConfigDefault.disabled(), variables)
367367

368-
if not config.enabled or not config.create_tracker:
368+
if not config.enabled:
369369
return None
370370

371371
runner = RunnerFactory.create_model(config, default_ai_provider)
@@ -448,7 +448,7 @@ async def create_agent(
448448
log.debug(f"Creating managed agent for key: {key}")
449449
config = self.__evaluate_agent(key, context, default or AIAgentConfigDefault.disabled(), variables)
450450

451-
if not config.enabled or not config.create_tracker:
451+
if not config.enabled:
452452
return None
453453

454454
runner = RunnerFactory.create_agent(config, tools or {}, default_ai_provider)
@@ -901,7 +901,7 @@ def __evaluate_agent(
901901
provider=provider or default.provider,
902902
instructions=final_instructions,
903903
tracker=tracker,
904-
create_tracker=tracker_factory if enabled else None,
904+
create_tracker=tracker_factory,
905905
judge_configuration=judge_configuration or default.judge_configuration,
906906
)
907907

packages/sdk/server-ai/src/ldai/managed_agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ async def run(self, input: str) -> AgentResult:
3030
:param input: The user prompt or input to the agent
3131
:return: AgentResult containing the agent's output and metrics
3232
"""
33-
tracker = self._ai_config.create_tracker() if self._ai_config.create_tracker else self._tracker
33+
tracker = self._ai_config.create_tracker()
3434
return await tracker.track_metrics_of_async(
3535
lambda: self._agent_runner.run(input),
3636
lambda result: result.metrics,

packages/sdk/server-ai/src/ldai/managed_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async def invoke(self, prompt: str) -> ModelResponse:
4242
:param prompt: The user prompt to send to the model
4343
:return: ModelResponse containing the model's response and metrics
4444
"""
45-
tracker = self._ai_config.create_tracker() if self._ai_config.create_tracker else self._tracker
45+
tracker = self._ai_config.create_tracker()
4646

4747
user_message = LDMessage(role='user', content=prompt)
4848
self._messages.append(user_message)

packages/sdk/server-ai/src/ldai/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class AIConfig:
181181
model: Optional[ModelConfig] = None
182182
provider: Optional[ProviderConfig] = None
183183
tracker: Optional[Any] = None
184-
create_tracker: Optional[Callable[[], Any]] = None
184+
create_tracker: Callable[[], Any] = lambda: None
185185

186186
def _base_to_dict(self) -> Dict[str, Any]:
187187
"""

packages/sdk/server-ai/tests/test_managed_agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class TestManagedAgentRun:
5555
async def test_run_delegates_to_agent_runner(self):
5656
"""Should delegate run() to the underlying AgentRunner."""
5757
mock_config = MagicMock(spec=AIAgentConfig)
58-
mock_config.create_tracker = None # fall back to passed tracker
5958
mock_tracker = MagicMock()
6059
mock_tracker.track_metrics_of_async = AsyncMock(
6160
return_value=AgentResult(
@@ -64,6 +63,7 @@ async def test_run_delegates_to_agent_runner(self):
6463
metrics=LDAIMetrics(success=True, usage=None),
6564
)
6665
)
66+
mock_config.create_tracker = MagicMock(return_value=mock_tracker)
6767
mock_runner = MagicMock()
6868
mock_runner.run = AsyncMock(
6969
return_value=AgentResult(

packages/sdk/server-ai/tests/test_model_config.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,14 +425,16 @@ def test_enabled_config_has_create_tracker(ldai_client: LDAIClient):
425425
assert callable(config.create_tracker)
426426

427427

428-
def test_disabled_config_has_no_create_tracker(ldai_client: LDAIClient):
428+
def test_disabled_config_has_working_create_tracker(ldai_client: LDAIClient):
429429
context = Context.create('user-key')
430430
default = AICompletionConfigDefault(enabled=False, model=ModelConfig('fake-model'), messages=[])
431431

432432
config = ldai_client.completion_config('off-config', context, default)
433433

434434
assert config.enabled is False
435-
assert config.create_tracker is None
435+
assert callable(config.create_tracker)
436+
tracker = config.create_tracker()
437+
assert tracker is not None
436438

437439

438440
def test_create_tracker_returns_new_tracker_each_call(ldai_client: LDAIClient):

0 commit comments

Comments
 (0)