Skip to content

Commit e23119b

Browse files
committed
properly track durations on nodes
1 parent b32f562 commit e23119b

2 files changed

Lines changed: 58 additions & 7 deletions

File tree

packages/ai-providers/server-ai-openai/src/ldai_openai/openai_agent_graph_runner.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,15 @@ async def run(self, input: Any) -> AgentGraphResult:
9292
path.append(root_node.get_key())
9393

9494
start_ns = time.perf_counter_ns()
95+
# Mutable cell so handoff callbacks can update time-between-handoffs without globals.
96+
last_handoff_ns: List[int] = [start_ns]
9597
try:
9698
from agents import Runner
97-
root_agent = self._build_agents(path)
99+
root_agent = self._build_agents(path, last_handoff_ns)
98100
result = await Runner.run(root_agent, str(input))
99101
# _log_run_result_shape(result)
102+
self._flush_final_segment(path, last_handoff_ns, tracker, result)
103+
100104
duration = (time.perf_counter_ns() - start_ns) // 1_000_000
101105

102106
if tracker:
@@ -135,6 +139,44 @@ async def run(self, input: Any) -> AgentGraphResult:
135139
metrics=LDAIMetrics(success=False),
136140
)
137141

142+
def _flush_final_segment(
143+
self,
144+
path: List[str],
145+
last_handoff_ns: List[int],
146+
tracker: Any,
147+
result: Any,
148+
) -> None:
149+
"""Record duration/tokens for the last active agent (no handoff after it)."""
150+
if not path:
151+
return
152+
last_key = path[-1]
153+
node = self._graph.get_node(last_key)
154+
if node is None:
155+
return
156+
config_tracker = node.get_config().tracker
157+
if config_tracker is None:
158+
return
159+
160+
now_ns = time.perf_counter_ns()
161+
duration_ms = (now_ns - last_handoff_ns[0]) // 1_000_000
162+
163+
usage: Optional[TokenUsage] = None
164+
try:
165+
usage_entry = result.context_wrapper.usage.request_usage_entries[-1]
166+
usage = TokenUsage(
167+
total=usage_entry.total_tokens,
168+
input=usage_entry.input_tokens,
169+
output=usage_entry.output_tokens,
170+
)
171+
except Exception:
172+
pass
173+
174+
gk = tracker.graph_key if tracker is not None else None
175+
if usage is not None:
176+
config_tracker.track_tokens(usage, graph_key=gk)
177+
config_tracker.track_duration(int(duration_ms), graph_key=gk)
178+
config_tracker.track_success(graph_key=gk)
179+
138180
def _handle_handoff(
139181
self,
140182
run_ctx: Any,
@@ -143,23 +185,23 @@ def _handle_handoff(
143185
path: List[str],
144186
tracker: Any,
145187
config_tracker: Any,
188+
last_handoff_ns: List[int],
146189
) -> None:
147190
path.append(tgt)
148191
if tracker:
149192
tracker.track_handoff_success(src, tgt)
150193

151194
usage: Optional[TokenUsage] = None
152-
duration_ms: Optional[int] = None
195+
now_ns = time.perf_counter_ns()
196+
duration_ms = (now_ns - last_handoff_ns[0]) // 1_000_000
197+
last_handoff_ns[0] = now_ns
153198
try:
154199
usage_entry = run_ctx.usage.request_usage_entries[-1]
155200
usage = TokenUsage(
156201
total=usage_entry.total_tokens,
157202
input=usage_entry.input_tokens,
158203
output=usage_entry.output_tokens,
159204
)
160-
duration_ms = getattr(usage_entry, 'duration_ms', None)
161-
if duration_ms is None:
162-
duration_ms = getattr(usage_entry, 'latency_ms', None)
163205
except Exception:
164206
pass
165207

@@ -178,12 +220,15 @@ def _make_on_handoff(
178220
path: List[str],
179221
tracker: Any,
180222
config_tracker: Any,
223+
last_handoff_ns: List[int],
181224
):
182225
def on_handoff(run_ctx: Any) -> None:
183-
self._handle_handoff(run_ctx, src, tgt, path, tracker, config_tracker)
226+
self._handle_handoff(
227+
run_ctx, src, tgt, path, tracker, config_tracker, last_handoff_ns
228+
)
184229
return on_handoff
185230

186-
def _build_agents(self, path: List[str]) -> Any:
231+
def _build_agents(self, path: List[str], last_handoff_ns: List[int]) -> Any:
187232
"""
188233
Build the agent tree from the graph definition via reverse_traverse.
189234
@@ -235,6 +280,7 @@ def build_node(node: AgentGraphNode, ctx: dict) -> Any:
235280
path,
236281
tracker,
237282
config_tracker,
283+
last_handoff_ns,
238284
),
239285
)
240286
)

packages/ai-providers/server-ai-openai/tests/test_openai_agent_graph_runner.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,8 @@ async def test_openai_agent_graph_runner_run_success():
135135
tracker.track_invocation_success.assert_called_once()
136136
tracker.track_path.assert_called_once()
137137
tracker.track_latency.assert_called_once()
138+
139+
root_tracker = graph.get_node('root-agent').get_config().tracker
140+
root_tracker.track_duration.assert_called_once()
141+
root_tracker.track_tokens.assert_called_once()
142+
root_tracker.track_success.assert_called_once()

0 commit comments

Comments
 (0)