Skip to content

Conversation

willemcdejongh
Copy link

@willemcdejongh willemcdejongh commented Oct 2, 2025

Note

Upgrade to Agno v2 and update wrappers to extract cleaner inputs/outputs, aggregate streamed results, and record LLM token/cache metrics with refined message attributes.

  • Agno instrumentation:
    • Dependency: Bump agno to >=2.1.2 (tests pin ==2.1.2).
    • Agent spans:
      • Set input.value from user message content via RunOutput/RunMessages (_get_user_message_content).
      • Set output.value from RunOutput.content (_extract_run_response_output).
      • Improve streaming handling: read from session.runs or agent.get_last_run_output; ensure output.mime_type=application/json and OK status.
    • LLM spans:
      • Input: restrict to cleaned messages only; limit roles to system|user|assistant in llm.input_messages.
      • Output: parse responses to populate llm.output_messages; aggregate streamed chunks into a single message (_parse_model_output_stream).
      • Metrics: record llm.token_count.prompt, llm.token_count.completion, and cache read/write tokens on sync/async (new span attributes added).
    • Helpers/attrs: Add _parse_model_output, _parse_model_output_stream, _extract_run_response_output; define token/cache span attribute constants.

Written by Cursor Bugbot for commit fc65734. This will update automatically on new commits. Configure here.

@willemcdejongh willemcdejongh requested a review from a team as a code owner October 2, 2025 11:24
@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Oct 2, 2025
Copy link
Contributor

github-actions bot commented Oct 2, 2025

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

cursor[bot]

This comment was marked as outdated.

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Oct 6, 2025
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@willemcdejongh
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Oct 8, 2025
@willemcdejongh willemcdejongh changed the title DRAFT: feat: Updated Agno attributes feat: Updated Agno attributes Oct 8, 2025
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

run_response = agent.get_last_run_output(session_id=session_id)
if "session" in arguments and arguments.get("session") and len(arguments.get("session").runs) > 0:
for run in arguments.get("session").runs:
if run.content:
Copy link
Contributor

Choose a reason for hiding this comment

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

But if the session has many runs, this won't work? You'll have to get the last run in the session.

if run_response is not None:
span.set_attribute(OUTPUT_VALUE, run_response.to_json())
span.set_attribute(OUTPUT_MIME_TYPE, JSON)
else:
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this Else necessary?

Copy link
Author

Choose a reason for hiding this comment

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

Its a last resort fallback. Users that have caching or a DB enabled, might still get a response here.

for i, message in enumerate(messages):
role, content = message.role, message.get_content_string()
if content:
if role in ["system", "user", "assistant"]:
Copy link
Contributor

Choose a reason for hiding this comment

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

What about tool results messages?

Copy link
Author

Choose a reason for hiding this comment

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

This is on input. We map the tool results in the output messages

else:
return str(output)

if hasattr(output, 'role') and hasattr(output, 'content') and hasattr(output, 'tool_calls'):
Copy link
Contributor

Choose a reason for hiding this comment

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

Some output would have only content, and some only tool_calls. Should it not be or?

"role": getattr(output, 'role', None),
"content": getattr(output, 'content', None),
"tool_calls": getattr(output, 'tool_calls', []),
"event": getattr(output, 'event', None),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should include this.

Copy link
Author

Choose a reason for hiding this comment

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

removed


messages.append(result_dict)

return {"messages": messages}
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it return like this? Should it not just be a single string as the output?

Copy link
Author

Choose a reason for hiding this comment

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

We do a json dumps with the response dict right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size:L This PR changes 100-499 lines, ignoring generated files.
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

2 participants