Builds the body for a `gen_ai.choice` log event. ADK always returns a single candidate, so `index` is always 0. `finish_reason` is included only when present on the response. Args: llm_response: The LLM response describing the choice. do_not_elide_content: When True, always include t
(
llm_response: LlmResponse | None,
telemetry_config: TelemetryConfig,
*,
do_not_elide: bool = False,
)
| 111 | |
| 112 | |
| 113 | def choice_body( |
| 114 | llm_response: LlmResponse | None, |
| 115 | telemetry_config: TelemetryConfig, |
| 116 | *, |
| 117 | do_not_elide: bool = False, |
| 118 | ) -> Mapping[str, AnyValue]: |
| 119 | """Builds the body for a `gen_ai.choice` log event. |
| 120 | |
| 121 | ADK always returns a single candidate, so `index` is always 0. |
| 122 | `finish_reason` is included only when present on the response. |
| 123 | |
| 124 | Args: |
| 125 | llm_response: The LLM response describing the choice. |
| 126 | do_not_elide_content: When True, always include the content regardless of |
| 127 | the `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` env var. |
| 128 | """ |
| 129 | if llm_response is None: |
| 130 | return {"content": None, "index": 0} |
| 131 | body: dict[str, AnyValue] = { |
| 132 | "content": _serialize_content_with_optional_elision( |
| 133 | llm_response.content, |
| 134 | capture_content=do_not_elide |
| 135 | or telemetry_config.should_add_content_to_logs, |
| 136 | ), |
| 137 | "index": 0, # ADK always returns a single candidate. |
| 138 | } |
| 139 | if llm_response.finish_reason is not None: |
| 140 | finish_reason = llm_response.finish_reason |
| 141 | body["finish_reason"] = ( |
| 142 | finish_reason.value |
| 143 | if hasattr(finish_reason, "value") |
| 144 | else str(finish_reason) |
| 145 | ) |
| 146 | return body |
no test coverage detected