Skip to content

Conversation

@anuraaga
Copy link
Contributor

What does this pull request do?

Applies the openai chat instrumentation as-is to beta.chat.Completions.parse - parse has some additional fields to handle structured outputs but otherwise has the same interface as the normal chat.Completions.create, except it lacks stream=True. So we can get instrumentation of non-streaming by just applying the same instrumentation - because semconv doesn't define anything for structured output, I guess there isn't anything else to do.

Streaming will require instrumenting the stream method which is a completely different interface than normal streaming but can be added later.

The test cases overlap with chat so no new casette

Related issues

#64 - instruments non-streaming only

)

# second call events
tool_call_telemetry = previous_message["tool_calls"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only diff from test_chat. Though there it's also sort of a coincidence that semconv matches the API response, while in this case it doesn't since there's additional fields.


def _patch(self, _module):
def _patch(self, module):
version = tuple([int(x) for x in getattr(getattr(module, "version"), "VERSION").split(".")])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if this is the sensible pattern for patching newer modules

Copy link
Member

@xrmx xrmx Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use module.version.VERSION directly since you are not adding any default to getattr though.

Problem with this approach is when these would be promoted out of beta, I expect the version check will pass but the patching will fail. I think a more robust approach would be to try to wrap anyway and catch the ModuleNotFoundError and AttributeError exceptions and set the beta_chat_available boolean accordingly.

Copy link
Contributor

@codefromthecrypt codefromthecrypt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow great to see this coverage with little code.

I suspect a changelog is warranted.

With this change alone, does DeepEval work?

@anuraaga
Copy link
Contributor Author

Yup verified DeepEval traces well with it

@codefromthecrypt
Copy link
Contributor

I can verify tracing works with deepeval. If I switch to metric.a_measure, I get a warning though:

WARNING  opentelemetry.attributes:__init__.py:100 Invalid type ModelMetaclass for attribute 'gen_ai.openai.request.response_format' value. Expected one of ['bool', 'str', 'bytes', 'int', 'float'] or a sequence of those types

@codefromthecrypt codefromthecrypt merged commit 6cf2a02 into elastic:main Mar 17, 2025
14 checks passed
@codefromthecrypt
Copy link
Contributor

merging to make my workshop today less embarrassing as pip from main is better than someone's branch. we should get a patch released soon @xrmx ideally with the warning from #65 (comment) squashed, too

@codefromthecrypt
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants