-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathagent_result.py
More file actions
122 lines (100 loc) · 4.32 KB
/
Copy pathagent_result.py
File metadata and controls
122 lines (100 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""Agent result handling for SDK.
This module defines the AgentResult class which encapsulates the complete response from an agent's processing cycle.
"""
from collections.abc import Sequence
from dataclasses import dataclass
from typing import Any, cast
from pydantic import BaseModel
from ..experimental.checkpoint import Checkpoint
from ..interrupt import Interrupt
from ..telemetry.metrics import EventLoopMetrics
from ..types.content import Message
from ..types.streaming import StopReason
@dataclass
class AgentResult:
"""Represents the last result of invoking an agent with a prompt.
Attributes:
stop_reason: The reason why the agent's processing stopped.
message: The last message generated by the agent.
metrics: Performance metrics collected during processing.
state: Additional state information from the event loop.
interrupts: List of interrupts if raised by user.
structured_output: Parsed structured output when structured_output_model was specified.
checkpoint: Checkpoint captured when the agent paused for durable execution.
Populated only when stop_reason == "checkpoint". See
strands.experimental.checkpoint for usage.
"""
stop_reason: StopReason
message: Message
metrics: EventLoopMetrics
state: Any
interrupts: Sequence[Interrupt] | None = None
structured_output: BaseModel | None = None
checkpoint: Checkpoint | None = None
@property
def context_size(self) -> int | None:
"""Most recent context size in tokens from the last LLM call.
Returns:
The input token count from the most recent cycle, or None if no data is available.
"""
return self.metrics.latest_context_size
def __str__(self) -> str:
"""Return a string representation of the agent result.
Priority order:
1. Interrupts (if present) → stringified list of interrupt dicts
2. Structured output (if present) → JSON string
3. Text content from message → concatenated text blocks
Returns:
String representation based on the priority order above.
"""
if self.interrupts:
return str([interrupt.to_dict() for interrupt in self.interrupts])
if self.structured_output:
return self.structured_output.model_dump_json()
content_array = self.message.get("content", [])
result = ""
for item in content_array:
if isinstance(item, dict):
if "text" in item:
result += item.get("text", "") + "\n"
elif "citationsContent" in item:
citations_block = item["citationsContent"]
if "content" in citations_block:
for content in citations_block["content"]:
if isinstance(content, dict) and "text" in content:
result += content.get("text", "") + "\n"
return result
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "AgentResult":
"""Rehydrate an AgentResult from persisted JSON.
Args:
data: Dictionary containing the serialized AgentResult data
Returns:
AgentResult instance
Raises:
TypeError: If the data format is invalid
"""
if data.get("type") != "agent_result":
raise TypeError(f"AgentResult.from_dict: unexpected type {data.get('type')!r}")
message = cast(Message, data.get("message"))
stop_reason = cast(StopReason, data.get("stop_reason"))
checkpoint_data = data.get("checkpoint")
checkpoint = Checkpoint.from_dict(checkpoint_data) if checkpoint_data else None
return cls(
message=message,
stop_reason=stop_reason,
metrics=EventLoopMetrics(),
state={},
checkpoint=checkpoint,
)
def to_dict(self) -> dict[str, Any]:
"""Convert this AgentResult to JSON-serializable dictionary.
Returns:
Dictionary containing serialized AgentResult data
"""
return {
"type": "agent_result",
"message": self.message,
"stop_reason": self.stop_reason,
"checkpoint": self.checkpoint.to_dict() if self.checkpoint else None,
}