Skip to content

Commit ff00a4f

Browse files
wrisaclaude
andcommitted
added logs and identity log to llm and luna evaluators
Port the structured logging and execution-context identity log from feature/SAO-16858-add-evaluator-for-LLM-thin (_shared/evaluator.py) to the separate llm/evaluator.py and luna/evaluator.py files on this branch. Adds dispatcher, skip, pre-invoke, result, and error logs to _evaluate, and an identity log to _execution_context_from_extensions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 167a8f7 commit ff00a4f

2 files changed

Lines changed: 82 additions & 6 deletions

File tree

‎evaluators/contrib/galileo/src/agent_control_evaluator_galileo/llm/evaluator.py‎

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,23 @@ def _execution_context_from_extensions(
252252
if not isinstance(organization_id, str) or not organization_id:
253253
raise ValueError("Authenticated execution metadata is missing organization_id")
254254

255+
resolved_user_id = user_id if isinstance(user_id, str) and user_id else None
256+
resolved_project_id = project_id if isinstance(project_id, str) and project_id else None
257+
raw_api_key = os.getenv("GALILEO_API_SECRET_KEY") or os.getenv("GALILEO_API_SECRET") or ""
258+
api_key_hint = f"...{raw_api_key[-4:]}" if len(raw_api_key) >= 4 else "***"
259+
logger.info(
260+
"[execution_context] caller_id=%r → user_id=%r org=%r project=%r run=%r api_key=%s",
261+
user_id,
262+
resolved_user_id,
263+
organization_id,
264+
resolved_project_id,
265+
run_id,
266+
api_key_hint,
267+
)
255268
return GalileoExecutionContext(
256269
organization_id=organization_id,
257-
user_id=user_id if isinstance(user_id, str) and user_id else None,
258-
project_id=project_id if isinstance(project_id, str) and project_id else None,
270+
user_id=resolved_user_id,
271+
project_id=resolved_project_id,
259272
run_id=run_id,
260273
)
261274

@@ -267,8 +280,12 @@ async def _evaluate(
267280
extensions: JSONObject | None = None,
268281
) -> EvaluatorResult:
269282
"""Run an LLM scorer evaluation with optional structured runtime context."""
283+
display = self.__class__.__name__
284+
scorer_id = self.config.scorer_id
285+
logger.info("[%s] Dispatching scorer evaluation: scorer_id=%s", display, scorer_id)
270286
input_text, output_text = self._prepare_payload(data)
271287
if not (_has_text(input_text) or _has_text(output_text)):
288+
logger.info("[%s] Skipping scorer invocation: no data to score", display)
272289
return EvaluatorResult(
273290
matched=False,
274291
confidence=1.0,
@@ -283,6 +300,12 @@ async def _evaluate(
283300
scorer_kwargs["step"] = step
284301
if execution_context is not None:
285302
scorer_kwargs["execution_context"] = execution_context
303+
logger.info(
304+
"[%s] Invoking scorer: scorer_id=%s timeout=%.1fs",
305+
display,
306+
scorer_id,
307+
self.get_timeout_seconds(),
308+
)
286309
response = await self._get_client().invoke(
287310
**scorer_kwargs,
288311
input=input_text if _has_text(input_text) else None,
@@ -300,6 +323,15 @@ async def _evaluate(
300323
operator = self.config.operator
301324
threshold = self.config.threshold
302325
state = "triggered" if matched else "not triggered"
326+
logger.info(
327+
"[%s] Scorer result: scorer_id=%s score=%r %s threshold=%r → %s",
328+
display,
329+
scorer_id,
330+
response.score,
331+
operator,
332+
threshold,
333+
state,
334+
)
303335
return EvaluatorResult(
304336
matched=matched,
305337
confidence=_confidence_from_score(response.score),
@@ -310,7 +342,13 @@ async def _evaluate(
310342
metadata=metadata,
311343
)
312344
except Exception as exc:
313-
logger.error("LLM scorer evaluation error: %s", exc, exc_info=True)
345+
logger.error(
346+
"[%s] Scorer evaluation error: scorer_id=%s error=%s",
347+
display,
348+
scorer_id,
349+
exc,
350+
exc_info=True,
351+
)
314352
return self._handle_error(exc)
315353

316354
def _base_metadata(self) -> dict[str, Any]:

‎evaluators/contrib/galileo/src/agent_control_evaluator_galileo/luna/evaluator.py‎

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,23 @@ def _execution_context_from_extensions(
252252
if not isinstance(organization_id, str) or not organization_id:
253253
raise ValueError("Authenticated execution metadata is missing organization_id")
254254

255+
resolved_user_id = user_id if isinstance(user_id, str) and user_id else None
256+
resolved_project_id = project_id if isinstance(project_id, str) and project_id else None
257+
raw_api_key = os.getenv("GALILEO_API_SECRET_KEY") or os.getenv("GALILEO_API_SECRET") or ""
258+
api_key_hint = f"...{raw_api_key[-4:]}" if len(raw_api_key) >= 4 else "***"
259+
logger.info(
260+
"[execution_context] caller_id=%r → user_id=%r org=%r project=%r run=%r api_key=%s",
261+
user_id,
262+
resolved_user_id,
263+
organization_id,
264+
resolved_project_id,
265+
run_id,
266+
api_key_hint,
267+
)
255268
return GalileoExecutionContext(
256269
organization_id=organization_id,
257-
user_id=user_id if isinstance(user_id, str) and user_id else None,
258-
project_id=project_id if isinstance(project_id, str) and project_id else None,
270+
user_id=resolved_user_id,
271+
project_id=resolved_project_id,
259272
run_id=run_id,
260273
)
261274

@@ -267,8 +280,12 @@ async def _evaluate(
267280
extensions: JSONObject | None = None,
268281
) -> EvaluatorResult:
269282
"""Run a Luna evaluation with optional structured runtime context."""
283+
display = self.__class__.__name__
284+
scorer_id = self.config.scorer_id
285+
logger.info("[%s] Dispatching scorer evaluation: scorer_id=%s", display, scorer_id)
270286
input_text, output_text = self._prepare_payload(data)
271287
if not (_has_text(input_text) or _has_text(output_text)):
288+
logger.info("[%s] Skipping scorer invocation: no data to score", display)
272289
return EvaluatorResult(
273290
matched=False,
274291
confidence=1.0,
@@ -283,6 +300,12 @@ async def _evaluate(
283300
scorer_kwargs["step"] = step
284301
if execution_context is not None:
285302
scorer_kwargs["execution_context"] = execution_context
303+
logger.info(
304+
"[%s] Invoking scorer: scorer_id=%s timeout=%.1fs",
305+
display,
306+
scorer_id,
307+
self.get_timeout_seconds(),
308+
)
286309
response = await self._get_client().invoke(
287310
**scorer_kwargs,
288311
input=input_text if _has_text(input_text) else None,
@@ -300,6 +323,15 @@ async def _evaluate(
300323
operator = self.config.operator
301324
threshold = self.config.threshold
302325
state = "triggered" if matched else "not triggered"
326+
logger.info(
327+
"[%s] Scorer result: scorer_id=%s score=%r %s threshold=%r → %s",
328+
display,
329+
scorer_id,
330+
response.score,
331+
operator,
332+
threshold,
333+
state,
334+
)
303335
return EvaluatorResult(
304336
matched=matched,
305337
confidence=_confidence_from_score(response.score),
@@ -310,7 +342,13 @@ async def _evaluate(
310342
metadata=metadata,
311343
)
312344
except Exception as exc:
313-
logger.error("Luna evaluation error: %s", exc, exc_info=True)
345+
logger.error(
346+
"[%s] Scorer evaluation error: scorer_id=%s error=%s",
347+
display,
348+
scorer_id,
349+
exc,
350+
exc_info=True,
351+
)
314352
return self._handle_error(exc)
315353

316354
def _base_metadata(self) -> dict[str, Any]:

0 commit comments

Comments
 (0)