Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log LLM tool call for streamed response #545

Merged

Conversation

jackmpcollins
Copy link
Contributor

The current LLM streamed response parsing only collects the message content/text. This PR generalizes this to allow collecting any state needed to generate the response_data. Streamed OpenAI chat completions now include the tool calls in the Logfire UI. Behaviour for Anthropic and for OpenAI completions (non-chat) remains the same.

Fixes #542

image

Copy link

codecov bot commented Oct 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (ff7211b) to head (6f512b8).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #545   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          133       133           
  Lines        10263     10308   +45     
  Branches      1399      1405    +6     
=========================================
+ Hits         10263     10308   +45     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

logfire/_internal/integrations/llm_providers/types.py Outdated Show resolved Hide resolved
logfire/_internal/integrations/llm_providers/types.py Outdated Show resolved Hide resolved
logfire/_internal/integrations/llm_providers/openai.py Outdated Show resolved Hide resolved
Comment on lines 106 to 107
'message': final_completion.choices[0].message if final_completion.choices else None,
'usage': final_completion.usage,
Copy link
Contributor

Choose a reason for hiding this comment

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

I worry about this having a significantly different shape from the other response data dicts.

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 same shape as the existing non-streamed chat completion, which is why it displays nicely in the UI.

def on_response(response: ResponseT, span: LogfireSpan) -> ResponseT:
"""Updates the span based on the type of response."""
if isinstance(response, LegacyAPIResponse): # pragma: no cover
on_response(response.parse(), span) # type: ignore
return cast('ResponseT', response)
if isinstance(response, ChatCompletion):
span.set_attribute(
'response_data',
{'message': response.choices[0].message, 'usage': response.usage},
)

I'll admit it's not exactly the same: the message object here is a ParsedChatCompletionMessage, a subclass of the non-streamed chat completion message ChatCompletionMessage. It has the "parsed" and tool call "parsed_arguments" fields added. These "ParsedX" classes are those returned by the client.beta.chat.completions.parse method.

Aside: it would be handy to have the response dicts that have special handling on the frontend be documented or codified (e.g. using TypedDicts), ideally with the order of precedence. For example I found that "combined_chunk_content" takes precedence over "message", which is why I excluded it.

Copy link
Contributor

Choose a reason for hiding this comment

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

ah, i didn't realise we were already using this shape. yes, creating some types sounds good. @dmontagu any thoughts? should we consider these shapes stable?

Copy link
Contributor

@alexmojaki alexmojaki left a comment

Choose a reason for hiding this comment

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

Thanks! Are you happy for me to merge?

@alexmojaki
Copy link
Contributor

alexmojaki commented Nov 12, 2024

cc @willbakst in case you want to take a look, but I won't wait to merge.

@jackmpcollins
Copy link
Contributor Author

Thanks! Are you happy for me to merge?

Yes, happy to merge! Thanks

@alexmojaki alexmojaki enabled auto-merge (squash) November 13, 2024 11:55
@alexmojaki alexmojaki merged commit 68fcf5a into pydantic:main Nov 13, 2024
19 checks passed
@jackmpcollins jackmpcollins deleted the log-streamed-tool-call-response branch November 13, 2024 18:04
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.

LLM tool call not shown for streamed response
3 participants