Skip to content

fix(event-loop): ensure all cycle metrics include end time and duration#1903

Open
stephentreacy wants to merge 1 commit intostrands-agents:mainfrom
stephentreacy:fix/event-loop-cycle-metrics
Open

fix(event-loop): ensure all cycle metrics include end time and duration#1903
stephentreacy wants to merge 1 commit intostrands-agents:mainfrom
stephentreacy:fix/event-loop-cycle-metrics

Conversation

@stephentreacy
Copy link

Description

Event loop cycle metrics (end_time and duration) were not being recorded for cycles that ended with a recursive call. This caused total_duration and average_cycle_time in the response metrics to be inaccurate, making it difficult to monitor agent performance in multi-cycle invocations.

Response metric traces would like like this, where total_duration is only including the Cycle 2 duration:

{
  "total_cycles": 2,
  "total_duration": 2.97,
  "traces": [
    {
      "name": "Cycle 1",
      "start_time": 1772822921.485906,
      "end_time": null,
      "duration": null,
      "children": [
        {
          "name": "stream_messages",
          "start_time": 1772822921.486195,
          "end_time": 1772822924.446701,
          "duration": 2.96
        },
        {
          "name": "Tool: tool_name",
          "start_time": 1772822924.447283,
          "end_time": 1772822931.842052,
          "duration": 7.39
        },
        {
          "name": "Recursive call",
          "start_time": 1772822931.842254,
          "end_time": 1772822934.810739,
          "duration": 2.97
        }
      ]
    },
    {
      "name": "Cycle 2",
      "start_time": 1772822931.842278,
      "end_time": 1772822934.810579,
      "duration": 2.97,
      "children": [
        {
          "name": "stream_messages",
          "start_time": 1772822931.842385,
          "end_time": 1772822934.810402,
          "duration": 2.97
        }
      ]
    }
  ]
}

Related Issues

Documentation PR

Type of Change

Bug fix

Testing

How have you tested the change? Verify that the changes do not break functionality or introduce warnings in consuming repositories: agents-docs, agents-tools, agents-cli

  • I ran hatch run prepare

Tested locally with recursive call scenarios, verified cycle metrics now include accurate end_time and duration values

Cycle 1 duration includes all child durations except the recursive call.

{
  "total_cycles": 2,
  "total_duration": 14.80,
  "traces": [
    {
      "name": "Cycle 1",
      "start_time": 1772825264.482746,
      "end_time": 1772825275.644092,
      "duration": 11.16,
      "children": [
        {
          "name": "stream_messages",
          "start_time": 1772825264.483011,
          "end_time": 1772825267.999054,
          "duration": 3.52
        },
        {
          "name": "Tool: tool_name",
          "start_time": 1772825268.000930,
          "end_time": 1772825275.643905,
          "duration": 7.64
        },
        {
          "name": "Recursive call",
          "start_time": 1772825275.644141,
          "end_time": 1772825279.281506,
          "duration": 3.64
        }
      ]
    },
    {
      "name": "Cycle 2",
      "start_time": 1772825275.644161,
      "end_time": 1772825279.281480,
      "duration": 3.64,
      "children": [
        {
          "name": "stream_messages",
          "start_time": 1772825275.644274,
          "end_time": 1772825279.281442,
          "duration": 3.64
        }
      ]
    }
  ]
}

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Copilot AI review requested due to automatic review settings March 13, 2026 15:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes inaccurate event-loop cycle timing metrics when a cycle ends by recursing into another event_loop_cycle (e.g., after tool execution), ensuring cycle traces get end_time/duration recorded so aggregate response metrics (like total/average duration) are correct for multi-cycle invocations.

Changes:

  • End tool-execution cycles’ metrics before deciding to stop or recurse, ensuring recursive paths still record end_time and duration.
  • Add a regression test covering the recursive-call scenario and asserting end_cycle is invoked for both the tool cycle and the subsequent text cycle.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/strands/event_loop/event_loop.py Moves end_cycle so tool cycles are always finalized before recursion/stop logic.
tests/strands/event_loop/test_event_loop.py Adds an async test to verify cycle-metrics finalization occurs in recursive tool-use flows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 561 to 565
tracer.end_event_loop_cycle_span(span=cycle_span, message=message, tool_result_message=tool_result_message)

agent.event_loop_metrics.end_cycle(cycle_start_time, cycle_trace)

if invocation_state["request_state"].get("stop_event_loop", False) or structured_output_context.stop_loop:
Comment on lines +1122 to +1134
with unittest.mock.patch.object(agent.event_loop_metrics, "end_cycle") as mock_end_cycle:
stream = strands.event_loop.event_loop.event_loop_cycle(
agent=agent,
invocation_state={"request_state": {}},
)
events = await alist(stream)

# Verify end_cycle was called once for tool cycle, once for text cycle
assert mock_end_cycle.call_count == 2

# Verify the event loop completed successfully
tru_stop_reason, _, _, _, _, _ = events[-1]["stop"]
assert tru_stop_reason == "end_turn"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants