agentle 0.9.23__py3-none-any.whl → 0.9.25__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
agentle/agents/agent.py CHANGED
@@ -1733,6 +1733,9 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
1733
1733
  parsed=generation_chunk.parsed
1734
1734
  if hasattr(generation_chunk, "parsed")
1735
1735
  else cast(T_Schema, None),
1736
+ generation_text=generation_chunk.text
1737
+ if generation_chunk
1738
+ else "",
1736
1739
  is_streaming_chunk=True,
1737
1740
  is_final_chunk=False,
1738
1741
  performance_metrics=partial_metrics,
@@ -1837,6 +1840,9 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
1837
1840
  generation=final_generation,
1838
1841
  context=context,
1839
1842
  parsed=final_generation.parsed,
1843
+ generation_text=final_generation.text
1844
+ if final_generation
1845
+ else "",
1840
1846
  is_streaming_chunk=False,
1841
1847
  is_final_chunk=True,
1842
1848
  performance_metrics=performance_metrics,
@@ -1953,6 +1959,7 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
1953
1959
  generation=generation,
1954
1960
  context=context,
1955
1961
  parsed=generation.parsed,
1962
+ generation_text=generation.text if generation else "",
1956
1963
  performance_metrics=performance_metrics,
1957
1964
  )
1958
1965
 
@@ -2152,6 +2159,9 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
2152
2159
  parsed=generation_chunk.parsed
2153
2160
  if hasattr(generation_chunk, "parsed")
2154
2161
  else cast(T_Schema, None),
2162
+ generation_text=generation_chunk.text
2163
+ if generation_chunk
2164
+ else "",
2155
2165
  is_streaming_chunk=True,
2156
2166
  is_final_chunk=False,
2157
2167
  performance_metrics=partial_metrics,
@@ -2698,8 +2708,9 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
2698
2708
  generation=None,
2699
2709
  context=context,
2700
2710
  parsed=cast(T_Schema, None),
2711
+ generation_text="",
2701
2712
  is_suspended=True,
2702
- suspension_reason=suspension_error.reason,
2713
+ suspension_reason=suspension_reason,
2703
2714
  resumption_token=resumption_token,
2704
2715
  performance_metrics=performance_metrics,
2705
2716
  )
@@ -3065,7 +3076,8 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
3065
3076
  step_metrics=step_metrics,
3066
3077
  average_generation_time_ms=generation_time_total
3067
3078
  / max(
3068
- 1, len([s for s in step_metrics if s.step_type == "generation"])
3079
+ 1,
3080
+ len([s for s in step_metrics if s.step_type == "generation"]),
3069
3081
  ),
3070
3082
  average_tool_execution_time_ms=tool_execution_time_total
3071
3083
  / max(1, tool_calls_count),
@@ -3377,6 +3389,7 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
3377
3389
  generation=None,
3378
3390
  context=context,
3379
3391
  parsed=cast(T_Schema, None),
3392
+ generation_text="",
3380
3393
  is_suspended=True,
3381
3394
  suspension_reason=suspension_error.reason,
3382
3395
  resumption_token=resumption_token,
@@ -3802,7 +3815,9 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
3802
3815
  return Context(
3803
3816
  message_history=[
3804
3817
  developer_message,
3805
- UserMessage(parts=[TextPart(text=f"```json\n{text}\n```")]),
3818
+ UserMessage(
3819
+ parts=[TextPart(text=f"```json\n{text}\n```")],
3820
+ ),
3806
3821
  ]
3807
3822
  )
3808
3823
  except (ImportError, AttributeError):
@@ -3986,8 +4001,24 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
3986
4001
  generation=None,
3987
4002
  context=context,
3988
4003
  parsed=cast(T_Schema, None),
3989
- is_suspended=False,
3990
- suspension_reason=denial_message,
4004
+ generation_text="",
4005
+ performance_metrics=PerformanceMetrics(
4006
+ total_execution_time_ms=0.0,
4007
+ input_processing_time_ms=0.0,
4008
+ static_knowledge_processing_time_ms=0.0,
4009
+ mcp_tools_preparation_time_ms=0.0,
4010
+ generation_time_ms=0.0,
4011
+ tool_execution_time_ms=0.0,
4012
+ final_response_processing_time_ms=0.0,
4013
+ iteration_count=0,
4014
+ tool_calls_count=0,
4015
+ total_tokens_processed=0,
4016
+ cache_hit_rate=0.0,
4017
+ average_generation_time_ms=0.0,
4018
+ average_tool_execution_time_ms=0.0,
4019
+ longest_step_duration_ms=0.0,
4020
+ shortest_step_duration_ms=0.0,
4021
+ ),
3991
4022
  )
3992
4023
 
3993
4024
  try:
@@ -4010,7 +4041,24 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4010
4041
  generation=None,
4011
4042
  context=context,
4012
4043
  parsed=cast(T_Schema, None),
4013
- is_suspended=False,
4044
+ generation_text="",
4045
+ performance_metrics=PerformanceMetrics(
4046
+ total_execution_time_ms=0.0,
4047
+ input_processing_time_ms=0.0,
4048
+ static_knowledge_processing_time_ms=0.0,
4049
+ mcp_tools_preparation_time_ms=0.0,
4050
+ generation_time_ms=0.0,
4051
+ tool_execution_time_ms=0.0,
4052
+ final_response_processing_time_ms=0.0,
4053
+ iteration_count=0,
4054
+ tool_calls_count=0,
4055
+ total_tokens_processed=0,
4056
+ cache_hit_rate=0.0,
4057
+ average_generation_time_ms=0.0,
4058
+ average_tool_execution_time_ms=0.0,
4059
+ longest_step_duration_ms=0.0,
4060
+ shortest_step_duration_ms=0.0,
4061
+ ),
4014
4062
  )
4015
4063
 
4016
4064
  suspension_type = suspension_state.get("type", "unknown")
@@ -4050,8 +4098,24 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4050
4098
  generation=None,
4051
4099
  context=context,
4052
4100
  parsed=cast(T_Schema, None),
4053
- is_suspended=False,
4054
- suspension_reason=error_message,
4101
+ generation_text="",
4102
+ performance_metrics=PerformanceMetrics(
4103
+ total_execution_time_ms=0.0,
4104
+ input_processing_time_ms=0.0,
4105
+ static_knowledge_processing_time_ms=0.0,
4106
+ mcp_tools_preparation_time_ms=0.0,
4107
+ generation_time_ms=0.0,
4108
+ tool_execution_time_ms=0.0,
4109
+ final_response_processing_time_ms=0.0,
4110
+ iteration_count=0,
4111
+ tool_calls_count=0,
4112
+ total_tokens_processed=0,
4113
+ cache_hit_rate=0.0,
4114
+ average_generation_time_ms=0.0,
4115
+ average_tool_execution_time_ms=0.0,
4116
+ longest_step_duration_ms=0.0,
4117
+ shortest_step_duration_ms=0.0,
4118
+ ),
4055
4119
  )
4056
4120
 
4057
4121
  async def _resume_from_tool_suspension(
@@ -4063,6 +4127,7 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4063
4127
  This handles the most common suspension scenario where a tool
4064
4128
  raised ToolSuspensionError and required approval.
4065
4129
  """
4130
+ execution_start_time = time.perf_counter()
4066
4131
  _logger = Maybe(logger if self.debug else None)
4067
4132
 
4068
4133
  # Extract suspension state
@@ -4198,9 +4263,30 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4198
4263
  generation=None,
4199
4264
  context=context,
4200
4265
  parsed=cast(T_Schema, None),
4266
+ generation_text="",
4201
4267
  is_suspended=True,
4202
4268
  suspension_reason=suspension_error.reason,
4203
4269
  resumption_token=resumption_token,
4270
+ performance_metrics=PerformanceMetrics(
4271
+ total_execution_time_ms=(time.perf_counter() - execution_start_time)
4272
+ * 1000
4273
+ if execution_start_time
4274
+ else 24,
4275
+ input_processing_time_ms=0.0,
4276
+ static_knowledge_processing_time_ms=0.0,
4277
+ mcp_tools_preparation_time_ms=0.0,
4278
+ generation_time_ms=0.0,
4279
+ tool_execution_time_ms=0.0,
4280
+ final_response_processing_time_ms=0.0,
4281
+ iteration_count=0,
4282
+ tool_calls_count=0,
4283
+ total_tokens_processed=0,
4284
+ cache_hit_rate=0.0,
4285
+ average_generation_time_ms=0.0,
4286
+ average_tool_execution_time_ms=0.0,
4287
+ longest_step_duration_ms=0.0,
4288
+ shortest_step_duration_ms=0.0,
4289
+ ),
4204
4290
  )
4205
4291
  except Exception as e:
4206
4292
  # Tool execution failed
@@ -4232,8 +4318,24 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4232
4318
  generation=None,
4233
4319
  context=context,
4234
4320
  parsed=cast(T_Schema, None),
4235
- is_suspended=False,
4236
- suspension_reason=error_message,
4321
+ generation_text="",
4322
+ performance_metrics=PerformanceMetrics(
4323
+ total_execution_time_ms=0.0,
4324
+ input_processing_time_ms=0.0,
4325
+ static_knowledge_processing_time_ms=0.0,
4326
+ mcp_tools_preparation_time_ms=0.0,
4327
+ generation_time_ms=0.0,
4328
+ tool_execution_time_ms=0.0,
4329
+ final_response_processing_time_ms=0.0,
4330
+ iteration_count=0,
4331
+ tool_calls_count=0,
4332
+ total_tokens_processed=0,
4333
+ cache_hit_rate=0.0,
4334
+ average_generation_time_ms=0.0,
4335
+ average_tool_execution_time_ms=0.0,
4336
+ longest_step_duration_ms=0.0,
4337
+ shortest_step_duration_ms=0.0,
4338
+ ),
4237
4339
  )
4238
4340
 
4239
4341
  # Complete the step and add to context
@@ -4319,6 +4421,26 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4319
4421
  generation=generation,
4320
4422
  context=context,
4321
4423
  parsed=generation.parsed,
4424
+ generation_text=generation.text if generation else "",
4425
+ performance_metrics=PerformanceMetrics(
4426
+ total_execution_time_ms=0.0,
4427
+ input_processing_time_ms=0.0,
4428
+ static_knowledge_processing_time_ms=0.0,
4429
+ mcp_tools_preparation_time_ms=0.0,
4430
+ generation_time_ms=0.0,
4431
+ tool_execution_time_ms=0.0,
4432
+ final_response_processing_time_ms=0.0,
4433
+ iteration_count=1,
4434
+ tool_calls_count=0,
4435
+ total_tokens_processed=generation.usage.total_tokens
4436
+ if generation
4437
+ else 0,
4438
+ cache_hit_rate=0.0,
4439
+ average_generation_time_ms=0.0,
4440
+ average_tool_execution_time_ms=0.0,
4441
+ longest_step_duration_ms=0.0,
4442
+ shortest_step_duration_ms=0.0,
4443
+ ),
4322
4444
  )
4323
4445
 
4324
4446
  # Has tools, continue with tool execution loop
@@ -4349,6 +4471,7 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4349
4471
  This method continues the standard tool execution loop from where
4350
4472
  the agent left off, handling iterations and tool calls.
4351
4473
  """
4474
+ execution_start_time = time.perf_counter()
4352
4475
  _logger = Maybe(logger if self.debug else None)
4353
4476
  generation_provider = self.generation_provider
4354
4477
 
@@ -4473,6 +4596,26 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4473
4596
  generation=generation,
4474
4597
  context=context,
4475
4598
  parsed=generation.parsed,
4599
+ generation_text=generation.text if generation else "",
4600
+ performance_metrics=PerformanceMetrics(
4601
+ total_execution_time_ms=0.0,
4602
+ input_processing_time_ms=0.0,
4603
+ static_knowledge_processing_time_ms=0.0,
4604
+ mcp_tools_preparation_time_ms=0.0,
4605
+ generation_time_ms=0.0,
4606
+ tool_execution_time_ms=0.0,
4607
+ final_response_processing_time_ms=0.0,
4608
+ iteration_count=1,
4609
+ tool_calls_count=0,
4610
+ total_tokens_processed=generation.usage.total_tokens
4611
+ if generation
4612
+ else 0,
4613
+ cache_hit_rate=0.0,
4614
+ average_generation_time_ms=0.0,
4615
+ average_tool_execution_time_ms=0.0,
4616
+ longest_step_duration_ms=0.0,
4617
+ shortest_step_duration_ms=0.0,
4618
+ ),
4476
4619
  )
4477
4620
 
4478
4621
  # Execute tools
@@ -4538,9 +4681,30 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4538
4681
  generation=None,
4539
4682
  context=context,
4540
4683
  parsed=cast(T_Schema, None),
4684
+ generation_text="",
4541
4685
  is_suspended=True,
4542
4686
  suspension_reason=suspension_error.reason,
4543
4687
  resumption_token=resumption_token,
4688
+ performance_metrics=PerformanceMetrics(
4689
+ total_execution_time_ms=(
4690
+ time.perf_counter() - execution_start_time
4691
+ )
4692
+ * 1000,
4693
+ input_processing_time_ms=0.0,
4694
+ static_knowledge_processing_time_ms=0.0,
4695
+ mcp_tools_preparation_time_ms=0.0,
4696
+ generation_time_ms=0.0,
4697
+ tool_execution_time_ms=0.0,
4698
+ final_response_processing_time_ms=0.0,
4699
+ iteration_count=current_iteration,
4700
+ tool_calls_count=0,
4701
+ total_tokens_processed=0,
4702
+ cache_hit_rate=0.0,
4703
+ average_generation_time_ms=0.0,
4704
+ average_tool_execution_time_ms=0.0,
4705
+ longest_step_duration_ms=0.0,
4706
+ shortest_step_duration_ms=0.0,
4707
+ ),
4544
4708
  )
4545
4709
 
4546
4710
  # Complete step and continue
@@ -4625,6 +4789,7 @@ class Agent[T_Schema = WithoutStructuredOutput](BaseModel):
4625
4789
  generation=generation,
4626
4790
  context=context,
4627
4791
  parsed=parsed,
4792
+ generation_text=generation.text if generation else "",
4628
4793
  performance_metrics=performance_metrics,
4629
4794
  )
4630
4795
 
@@ -87,7 +87,14 @@ class AgentRunOutput[T_StructuredOutput](BaseModel):
87
87
  parsed: T_StructuredOutput
88
88
  """
89
89
  Structured data extracted from the agent's response.
90
- In streaming mode, only available in the final chunk.
90
+ In streaming mode, contains incrementally parsed partial data in each chunk,
91
+ with complete data available in the final chunk.
92
+ """
93
+
94
+ generation_text: str = Field(default="")
95
+ """
96
+ The text response from the agent.
97
+ Returns empty string if execution is suspended or generation is None.
91
98
  """
92
99
 
93
100
  is_suspended: bool = Field(default=False)