Skip to content

Commit afbc541

Browse files
authored
Coerce top_k request attribute to integer across Bedrock, Portkey, and Smolagents (#707)
* Coerce top_k request attribute to integer across Bedrock, Portkey, and Smolagents * Add changelog fragments * Assert top_k integer type in Bedrock and Portkey tests * Update InferenceInvocation.top_k type to int | None and add util test
1 parent 5bf108e commit afbc541

13 files changed

Lines changed: 39 additions & 15 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Coerce top_k request parameter to integer.

‎instrumentation/opentelemetry-instrumentation-genai-bedrock/src/opentelemetry/instrumentation/genai/bedrock/extractors.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def extract_converse_request(
307307
invocation.top_p = inf_config.get("topP")
308308
invocation.max_tokens = inf_config.get("maxTokens")
309309
invocation.stop_sequences = inf_config.get("stopSequences")
310-
invocation.top_k = _safe_float(
310+
invocation.top_k = _safe_int(
311311
_first_not_none(inf_config.get("topK"), inf_config.get("top_k"))
312312
)
313313
invocation.seed = inf_config.get("seed")
@@ -322,7 +322,7 @@ def extract_converse_request(
322322
add_inf.get("top_k") if _is_dict(add_inf) else None,
323323
invocation.top_k,
324324
)
325-
invocation.top_k = _safe_float(top_k_val)
325+
invocation.top_k = _safe_int(top_k_val)
326326
if "seed" in add_fields:
327327
invocation.seed = add_fields.get("seed")
328328

@@ -496,7 +496,7 @@ def extract_invoke_model_request(
496496
)
497497

498498
# Top K
499-
invocation.top_k = _safe_float(
499+
invocation.top_k = _safe_int(
500500
_first_not_none(
501501
body.get("top_k"),
502502
body.get("topK"),

‎instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_converse.py‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ def test_extract_converse_request_top_k_and_seed(tracer_provider) -> None:
363363
},
364364
invocation,
365365
)
366-
assert invocation.top_k == 40.0
366+
assert invocation.top_k == 40
367+
assert isinstance(invocation.top_k, int)
367368
assert invocation.seed == 123
368369

369370
invocation2 = handler.inference(provider="aws.bedrock")
@@ -373,7 +374,8 @@ def test_extract_converse_request_top_k_and_seed(tracer_provider) -> None:
373374
},
374375
invocation2,
375376
)
376-
assert invocation2.top_k == 250.0
377+
assert invocation2.top_k == 250
378+
assert isinstance(invocation2.top_k, int)
377379
assert invocation2.seed == 456
378380

379381
invocation3 = handler.inference(provider="aws.bedrock")
@@ -383,7 +385,8 @@ def test_extract_converse_request_top_k_and_seed(tracer_provider) -> None:
383385
},
384386
invocation3,
385387
)
386-
assert invocation3.top_k == 20.0
388+
assert invocation3.top_k == 20
389+
assert isinstance(invocation3.top_k, int)
387390

388391
invocation4 = handler.inference(provider="aws.bedrock")
389392
extract_converse_request(
@@ -392,7 +395,8 @@ def test_extract_converse_request_top_k_and_seed(tracer_provider) -> None:
392395
},
393396
invocation4,
394397
)
395-
assert invocation4.top_k == 0.0
398+
assert invocation4.top_k == 0
399+
assert isinstance(invocation4.top_k, int)
396400
assert invocation4.seed == 0
397401

398402

‎instrumentation/opentelemetry-instrumentation-genai-bedrock/tests/test_invoke_model.py‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ def test_invoke_model_anthropic_messages(
109109
assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 100
110110
assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7
111111
assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_TOP_P] == 0.9
112-
assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_TOP_K] == 40.0
112+
assert span.attributes[GenAIAttributes.GEN_AI_REQUEST_TOP_K] == 40
113+
assert isinstance(
114+
span.attributes[GenAIAttributes.GEN_AI_REQUEST_TOP_K], int
115+
)
113116
assert span.attributes[GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS] == (
114117
"stop",
115118
)
@@ -443,7 +446,8 @@ def test_extract_invoke_model_request_zero_values(tracer_provider) -> None:
443446
)
444447
assert invocation.temperature == 0.0
445448
assert invocation.top_p == 0.0
446-
assert invocation.top_k == 0.0
449+
assert invocation.top_k == 0
450+
assert isinstance(invocation.top_k, int)
447451
assert invocation.max_tokens == 0
448452
assert invocation.seed == 0
449453

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Coerce top_k request parameter to integer.

‎instrumentation/opentelemetry-instrumentation-genai-portkey/src/opentelemetry/instrumentation/genai/portkey/utils.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def _apply_request_parameters(
250250
elif (p := get_value(kwargs.get("p"))) is not None:
251251
invocation.top_p = float(p)
252252
if (top_k := get_value(kwargs.get("top_k"))) is not None:
253-
invocation.top_k = float(top_k)
253+
invocation.top_k = int(top_k)
254254
if (max_tokens := get_value(kwargs.get("max_tokens"))) is not None:
255255
invocation.max_tokens = int(max_tokens)
256256
elif (

‎instrumentation/opentelemetry-instrumentation-genai-portkey/tests/test_chat_completions.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def test_sync_chat_completions_basic(
176176
model="gpt-4o",
177177
temperature=0.7,
178178
top_p=0.9,
179+
top_k=40,
179180
max_tokens=150,
180181
seed=42,
181182
)
@@ -207,6 +208,10 @@ def test_sync_chat_completions_basic(
207208
== 0.7
208209
)
209210
assert span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_TOP_P) == 0.9
211+
assert span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_TOP_K) == 40
212+
assert isinstance(
213+
span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_TOP_K), int
214+
)
210215
assert (
211216
span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS)
212217
== 150
@@ -598,13 +603,18 @@ def test_chat_completions_top_p_zero_and_max_tokens_zero(
598603
messages=[{"role": "user", "content": "Hi"}],
599604
model="gpt-4o",
600605
top_p=0.0,
606+
top_k=0,
601607
max_tokens=0,
602608
)
603609

604610
spans = span_exporter.get_finished_spans()
605611
assert len(spans) == 1
606612
span = spans[0]
607613
assert span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_TOP_P) == 0.0
614+
assert span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_TOP_K) == 0
615+
assert isinstance(
616+
span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_TOP_K), int
617+
)
608618
assert (
609619
span.attributes.get(GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS) == 0
610620
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Coerce top_k request parameter to integer.

‎instrumentation/opentelemetry-instrumentation-genai-smolagents/src/opentelemetry/instrumentation/genai/smolagents/patch.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def _apply_request_parameters(
224224

225225
invocation.temperature = _coerce_float(merged.get("temperature"))
226226
invocation.top_p = _coerce_float(merged.get("top_p"))
227-
invocation.top_k = _coerce_float(merged.get("top_k"))
227+
invocation.top_k = _coerce_int(merged.get("top_k"))
228228
invocation.frequency_penalty = _coerce_float(
229229
merged.get("frequency_penalty")
230230
)

‎instrumentation/opentelemetry-instrumentation-genai-smolagents/tests/test_models.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,8 @@ def test_request_parameters_recorded(
396396
(span,) = spans_by_operation(span_exporter.get_finished_spans(), "chat")
397397
assert attr(span, GenAI.GEN_AI_REQUEST_TEMPERATURE) == 0.5
398398
assert attr(span, GenAI.GEN_AI_REQUEST_TOP_P) == 0.9
399-
# top_k is a float attribute in the spec even though callers pass an int.
400-
assert attr(span, GenAI.GEN_AI_REQUEST_TOP_K) == 40.0
401-
assert isinstance(attr(span, GenAI.GEN_AI_REQUEST_TOP_K), float)
399+
assert attr(span, GenAI.GEN_AI_REQUEST_TOP_K) == 40
400+
assert isinstance(attr(span, GenAI.GEN_AI_REQUEST_TOP_K), int)
402401
assert attr(span, GenAI.GEN_AI_REQUEST_FREQUENCY_PENALTY) == 0.25
403402
assert attr(span, GenAI.GEN_AI_REQUEST_PRESENCE_PENALTY) == 1.0
404403
assert attr(span, GenAI.GEN_AI_REQUEST_MAX_TOKENS) == 256

0 commit comments

Comments
 (0)