Skip to content

feat: Add response api to gen_ai.input.messages and gen_ai.output.messages#1650

Closed
brightsparc wants to merge 21 commits intopydantic:mainfrom
brightsparc:julian/semconvs-messages
Closed

feat: Add response api to gen_ai.input.messages and gen_ai.output.messages#1650
brightsparc wants to merge 21 commits intopydantic:mainfrom
brightsparc:julian/semconvs-messages

Conversation

@brightsparc
Copy link
Contributor

No description provided.

@codecov
Copy link

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 96.01770% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ire/_internal/integrations/llm_providers/openai.py 95.48% 0 Missing and 6 partials ⚠️
.../_internal/integrations/llm_providers/anthropic.py 94.44% 0 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@alexmojaki
Copy link
Contributor

There are now big merge conflicts because I just merged #1652, that was step 1 of #1586

Similar to #1593 (comment), please move changes which only add small attributes to a separate PR, these can be easily merged into main without breaking anything or significantly increasing span size. The messages format is a whole thing on its own.

@brightsparc
Copy link
Contributor Author

There are now big merge conflicts because I just merged #1652, that was step 1 of #1586

Similar to #1593 (comment), please move changes which only add small attributes to a separate PR, these can be easily merged into main without breaking anything or significantly increasing span size. The messages format is a whole thing on its own.

Okay, will look into this thanks.

…make it simpler to add semvconv for chat completions / responses
Comment on lines +985 to +1018
'logfire.json_schema': {
'type': 'object',
'properties': {
'request_data': {'type': 'object'},
'gen_ai.provider.name': {},
'gen_ai.request.model': {},
'gen_ai.operation.name': {},
'gen_ai.input.messages': {'type': 'array'},
'async': {},
'gen_ai.system': {},
'gen_ai.response.model': {},
'operation.cost': {},
'gen_ai.response.id': {},
'gen_ai.usage.input_tokens': {},
'gen_ai.usage.output_tokens': {},
'response_data': {
'type': 'object',
'properties': {
'message': {
'type': 'object',
'title': 'ChatCompletionMessage',
'x-python-datatype': 'PydanticModel',
},
'usage': {
'type': 'object',
'title': 'CompletionUsage',
'x-python-datatype': 'PydanticModel',
},
},
},
'gen_ai.output.messages': {'type': 'array'},
'gen_ai.response.finish_reasons': {'type': 'array'},
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@alexmojaki is there a reason why the json_schema doesn't include object type for things like string, integer, boolean, number? We could update to include these types? (see below)

def create_json_schema(obj: Any, seen: set[int]) -> JsonDict:
    """Create a JSON Schema from the given object.

    Args:
        obj: The object to create the JSON Schema from.
        seen: A set of object IDs that have already been processed.

    Returns:
        The JSON Schema.
    """
    if obj is None:
        return {'type': 'null'}

    try:
        # cover common types first before calling `type_to_schema` to avoid the overhead of imports if not necessary
        obj_type = obj.__class__

        # TODO: add these types?
        if obj_type is str:
            return {'type': 'string'}
        elif obj_type is int:
            return {'type': 'integer'}
        elif obj_type is bool:
            return {'type': 'boolean'}
        elif obj_type is float:
            return {'type': 'number'}

        if id(obj) in seen:
            return {}

@alexmojaki
Copy link
Contributor

@brightsparc these changes look great but are you still going to split the PR in two?

@brightsparc
Copy link
Contributor Author

@brightsparc these changes look great but are you still going to split the PR in two?

This PR adds input.messages and output.messages for chat completions and responses. I could probably split this for chat vs responses, but I don't think it would reduce the number of changes to split by attributes as they touch the same files?

I'm looking to make sure test coverage is 100% so this should mitigate most concerns?

Comment on lines +282 to +292
span.set_attribute(RESPONSE_MODEL, response.model)
span.set_attribute(RESPONSE_ID, response.id)

# Add token usage
if response.usage:
span.set_attribute(INPUT_TOKENS, response.usage.input_tokens)
span.set_attribute(OUTPUT_TOKENS, response.usage.output_tokens)

# Add finish reason
if response.stop_reason:
span.set_attribute(RESPONSE_FINISH_REASONS, [response.stop_reason])
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the kind of thing I'm talking about when I say:

Similar to #1593 (comment), please move changes which only add small attributes to a separate PR, these can be easily merged into main without breaking anything or significantly increasing span size. The messages format is a whole thing on its own.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I will work on breaking this up into 3 PRs.

  1. Scalar values
  2. Input Messages
  3. Output Messages

Once I have these I will link to this PR and it can be closed.

Copy link
Contributor

Choose a reason for hiding this comment

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

2 and 3 can stay together

Copy link
Contributor Author

@brightsparc brightsparc Jan 24, 2026

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I missed this message, will combine 3 into 2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Closing in favour of #1657 and #1666

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