Conversation
Parsing bound the call and then applied signature defaults, so every optional parameter the caller left out reached the recorded request. groq >= 1.0 marks those with an Omit instance (and timeout with a non-singleton NotGiven), which the exported NOT_GIVEN identity test does not catch, so a two-argument create() emitted 34 invocation parameters whose values were object addresses. Bind without applying defaults, the way the cohere instrumentor already does, and add regression tests for the omitted, the passed, and the async path.
AttributeValue is a union, so json.loads needs the same cast(str, ...) the other instrumentor tests use before parsing a recorded attribute.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The groq instrumentor records parameters that the caller never passed. With
groq==1.0.0, this call:records 33 entries in
llm.invocation_parameters(1 expected) and 36 ininput.value(2 expected):{"model": "llama-3.1-8b-instant", "citation_options": "<groq.Omit object at 0x102ee8390>", "frequency_penalty": "<groq.Omit object at 0x102ee8390>", "max_tokens": "<groq.Omit object at 0x102ee8390>", "response_format": "<groq.Omit object at 0x102ee8390>", "seed": "<groq.Omit object at 0x102ee8390>", "stop": "<groq.Omit object at 0x102ee8390>", "temperature": "<groq.Omit object at 0x102ee8390>", "timeout": "NOT_GIVEN", "...": "24 more"}So the trace claims the caller set
temperature,max_tokens,top_p,seed,stop,tools,response_format,stream, … when they passed nothing, and 33 of those values are Python object addresses, so the same call records different text in every process.Why it happens.
_parse_args()binds the call, applies signature defaults, then relies on one identity test to drop the SDK's "not given" markers:That was true when the code was written and still holds on the version CI pins (
test-requirements.txt→groq==0.9.0, where the optional defaults are the exportedNOT_GIVENsingleton). The current SDK uses two other shapes, and neither passes the test:is groq.NOT_GIVENisinstanceoftemperature,tools,stream, … (33)OmitFalsegroq.OmittimeoutNotGivenFalse(not the exported singleton)groq.NotGivenpyproject.tomldeclares"groq >= 0.9.0"with no upper bound, so the 1.x line is supported andci-groq-latestinstalls it. This is the casepython/AGENTS.mdnames directly: "Request parameters: filter out the SDK's 'not given' sentinels (e.g.Omit/NotGivenin Stainless-generated SDKs) so unset defaults don't polluteinput.valueandllm.invocation_parameters."The change. Bind without applying defaults, so an unsupplied parameter never enters the recorded request — the approach
cohere/_wrappers.pyalready documents for the same reason ("Map the call's arguments to parameter names, keeping only values the caller set"). The existingNone/NOT_GIVENguards stay, so a caller who passes a sentinel explicitly is still filtered. No sentinel class is imported, so nothing here depends on which marker a given groq release uses — which also matters becausegroq < 1.0does not exportOmitpublicly at all.Only the values of two existing attributes change, and only for
groq>=1.0; no attribute key is added, renamed or removed, and no span name or hierarchy is touched. That is why there is no trace screenshot below: the before/after recorded values above are the whole observable difference.Verification
Python 3.11, one venv with the three workspace packages installed editable (
openinference-semantic-conventions,openinference-instrumentation,openinference-instrumentation-groq) plusopentelemetry-sdk,wrapt,responses,httpx<0.28. Commands run frompython/instrumentation/openinference-instrumentation-groq.origin/main(b737360)1.0.0(current;ci-groq-latest)0.9.0(CI pin;ci-groq)The 5 added tests (
tests/test_invocation_parameters.py) fail onmainundergroq>=1.0for the reason described above, and the existing 16 keep passing before and after. Stated plainly: under the pinnedgroq==0.9.0the new tests pass onmaintoo, because that version's defaults really are theNOT_GIVENsingleton — they bite in thegroq-latestmatrix environment, whichpython-CI.yamldoes run for this package.What they cover: omitted parameters absent from
llm.invocation_parameters; absent frominput.value; no<... object at 0x...>in either recorded value;temperature=0.5, max_tokens=10, stop="END"still recorded (the fix does not over-filter); and the same result on the async path.Not verified here: no live groq call (no API key), no UI rendering, and no whole-repo
tox run-parallel— the diff is confined to this package, so other packages' suites were not run.Resolves #3781
Checklist:
using_attributestests intests/test_instrumentor.pypass on this branch._start_as_current_spanis not part of this diff and its tests pass.Prepared with an AI coding assistant; the reproduction, tests and every command above were executed and inspected locally before submitting.