solace-agent-mesh 1.0.7__py3-none-any.whl → 1.1.0__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.

Potentially problematic release.


This version of solace-agent-mesh might be problematic. Click here for more details.

Files changed (163) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +182 -42
  2. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
  3. solace_agent_mesh/agent/adk/callbacks.py +165 -104
  4. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +0 -18
  5. solace_agent_mesh/agent/adk/models/models_llm.txt +104 -55
  6. solace_agent_mesh/agent/adk/runner.py +7 -5
  7. solace_agent_mesh/agent/adk/services.py +9 -1
  8. solace_agent_mesh/agent/adk/setup.py +11 -0
  9. solace_agent_mesh/agent/adk/stream_parser.py +8 -1
  10. solace_agent_mesh/agent/adk/tool_wrapper.py +10 -3
  11. solace_agent_mesh/agent/agent_llm.txt +355 -18
  12. solace_agent_mesh/agent/protocol/event_handlers.py +433 -296
  13. solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
  14. solace_agent_mesh/agent/sac/app.py +1 -1
  15. solace_agent_mesh/agent/sac/component.py +212 -517
  16. solace_agent_mesh/agent/sac/sac_llm.txt +133 -63
  17. solace_agent_mesh/agent/testing/testing_llm.txt +25 -58
  18. solace_agent_mesh/agent/tools/peer_agent_tool.py +15 -11
  19. solace_agent_mesh/agent/tools/tools_llm.txt +234 -69
  20. solace_agent_mesh/agent/utils/artifact_helpers.py +35 -1
  21. solace_agent_mesh/agent/utils/utils_llm.txt +90 -105
  22. solace_agent_mesh/assets/docs/404.html +3 -3
  23. solace_agent_mesh/assets/docs/assets/js/{3d406171.7d02a73b.js → 3d406171.0b9eeed1.js} +1 -1
  24. solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +1 -0
  25. solace_agent_mesh/assets/docs/assets/js/{75384d09.ccd480c4.js → 75384d09.bf78fbdb.js} +1 -1
  26. solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +1 -0
  28. solace_agent_mesh/assets/docs/assets/js/main.a75ecc0d.js +2 -0
  29. solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +1 -0
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
  32. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
  33. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
  35. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
  36. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
  37. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
  38. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
  40. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
  43. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
  44. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +105 -0
  45. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +53 -0
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +8 -8
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
  54. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
  64. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
  65. solace_agent_mesh/assets/docs/lunr-index-1756992446316.json +1 -0
  66. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  67. solace_agent_mesh/assets/docs/search-doc-1756992446316.json +1 -0
  68. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  69. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  70. solace_agent_mesh/cli/__init__.py +1 -1
  71. solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +12 -3
  72. solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +10 -14
  73. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +2 -15
  74. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +6 -2
  75. solace_agent_mesh/cli/utils.py +15 -0
  76. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-DvlO62me.js → authCallback-BmF2l6vg.js} +1 -1
  77. solace_agent_mesh/client/webui/frontend/static/assets/{client-bp6u3qVZ.js → client-D881Dttc.js} +4 -4
  78. solace_agent_mesh/client/webui/frontend/static/assets/main-C0jZjYa8.js +699 -0
  79. solace_agent_mesh/client/webui/frontend/static/assets/main-CCeG324-.css +1 -0
  80. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +2 -2
  81. solace_agent_mesh/client/webui/frontend/static/index.html +3 -3
  82. solace_agent_mesh/common/a2a/__init__.py +213 -0
  83. solace_agent_mesh/common/a2a/a2a_llm.txt +182 -0
  84. solace_agent_mesh/common/a2a/artifact.py +328 -0
  85. solace_agent_mesh/common/a2a/events.py +183 -0
  86. solace_agent_mesh/common/a2a/message.py +307 -0
  87. solace_agent_mesh/common/a2a/protocol.py +513 -0
  88. solace_agent_mesh/common/a2a/task.py +127 -0
  89. solace_agent_mesh/common/a2a/translation.py +653 -0
  90. solace_agent_mesh/common/a2a/types.py +54 -0
  91. solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
  92. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +407 -0
  93. solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
  94. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +31 -0
  95. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +18 -0
  96. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +235 -0
  97. solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
  98. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +25 -0
  99. solace_agent_mesh/common/agent_registry.py +1 -1
  100. solace_agent_mesh/common/common_llm.txt +192 -70
  101. solace_agent_mesh/common/data_parts.py +99 -0
  102. solace_agent_mesh/common/middleware/middleware_llm.txt +17 -17
  103. solace_agent_mesh/common/sac/__init__.py +0 -0
  104. solace_agent_mesh/common/sac/sac_llm.txt +71 -0
  105. solace_agent_mesh/common/sac/sam_component_base.py +252 -0
  106. solace_agent_mesh/common/services/providers/providers_llm.txt +51 -84
  107. solace_agent_mesh/common/services/services_llm.txt +206 -26
  108. solace_agent_mesh/common/utils/artifact_utils.py +29 -0
  109. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +176 -80
  110. solace_agent_mesh/common/utils/utils_llm.txt +323 -42
  111. solace_agent_mesh/config_portal/backend/common.py +1 -1
  112. solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-MqsrTd6g.js → _index-Bym6YkMd.js} +74 -24
  113. solace_agent_mesh/config_portal/frontend/static/client/assets/{components-B7lKcHVY.js → components-Rk0n-9cK.js} +1 -1
  114. solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-CEumGClk.js → entry.client-mvZjNKiz.js} +1 -1
  115. solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DSo1AH_7.js → index-DzNKzXrc.js} +1 -1
  116. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-d845808d.js +1 -0
  117. solace_agent_mesh/config_portal/frontend/static/client/assets/{root-C4XmHinv.js → root-BWvk5-gF.js} +1 -1
  118. solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
  119. solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
  120. solace_agent_mesh/core_a2a/service.py +20 -44
  121. solace_agent_mesh/gateway/base/app.py +27 -1
  122. solace_agent_mesh/gateway/base/base_llm.txt +177 -72
  123. solace_agent_mesh/gateway/base/component.py +294 -523
  124. solace_agent_mesh/gateway/gateway_llm.txt +299 -58
  125. solace_agent_mesh/gateway/http_sse/component.py +156 -183
  126. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
  127. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
  128. solace_agent_mesh/gateway/http_sse/main.py +8 -10
  129. solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
  130. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +18 -4
  131. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
  132. solace_agent_mesh/gateway/http_sse/routers/sessions.py +12 -7
  133. solace_agent_mesh/gateway/http_sse/routers/tasks.py +116 -169
  134. solace_agent_mesh/gateway/http_sse/services/agent_service.py +1 -1
  135. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +89 -135
  136. solace_agent_mesh/gateway/http_sse/services/task_service.py +2 -5
  137. solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
  138. solace_agent_mesh/templates/gateway_component_template.py +149 -98
  139. {solace_agent_mesh-1.0.7.dist-info → solace_agent_mesh-1.1.0.dist-info}/METADATA +5 -4
  140. {solace_agent_mesh-1.0.7.dist-info → solace_agent_mesh-1.1.0.dist-info}/RECORD +144 -127
  141. solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
  142. solace_agent_mesh/assets/docs/assets/js/main.d79f063b.js +0 -2
  143. solace_agent_mesh/assets/docs/assets/js/runtime~main.6415ad00.js +0 -1
  144. solace_agent_mesh/assets/docs/lunr-index-1756146501924.json +0 -1
  145. solace_agent_mesh/assets/docs/search-doc-1756146501924.json +0 -1
  146. solace_agent_mesh/client/webui/frontend/static/assets/main-BCpII1-0.css +0 -1
  147. solace_agent_mesh/client/webui/frontend/static/assets/main-BucUdn9m.js +0 -673
  148. solace_agent_mesh/common/a2a_protocol.py +0 -564
  149. solace_agent_mesh/common/client/__init__.py +0 -4
  150. solace_agent_mesh/common/client/card_resolver.py +0 -21
  151. solace_agent_mesh/common/client/client.py +0 -85
  152. solace_agent_mesh/common/client/client_llm.txt +0 -133
  153. solace_agent_mesh/common/server/__init__.py +0 -4
  154. solace_agent_mesh/common/server/server.py +0 -122
  155. solace_agent_mesh/common/server/server_llm.txt +0 -169
  156. solace_agent_mesh/common/server/task_manager.py +0 -291
  157. solace_agent_mesh/common/server/utils.py +0 -28
  158. solace_agent_mesh/common/types.py +0 -411
  159. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-28271392.js +0 -1
  160. /solace_agent_mesh/assets/docs/assets/js/{main.d79f063b.js.LICENSE.txt → main.a75ecc0d.js.LICENSE.txt} +0 -0
  161. {solace_agent_mesh-1.0.7.dist-info → solace_agent_mesh-1.1.0.dist-info}/WHEEL +0 -0
  162. {solace_agent_mesh-1.0.7.dist-info → solace_agent_mesh-1.1.0.dist-info}/entry_points.txt +0 -0
  163. {solace_agent_mesh-1.0.7.dist-info → solace_agent_mesh-1.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,307 @@
1
+ """
2
+ Helpers for creating and consuming A2A Message and Part objects.
3
+ """
4
+
5
+ import base64
6
+ import uuid
7
+ from typing import Any, Dict, List, Optional, Union
8
+
9
+ from .types import ContentPart
10
+ from a2a.types import (
11
+ DataPart,
12
+ FilePart,
13
+ FileWithBytes,
14
+ FileWithUri,
15
+ Message,
16
+ Part,
17
+ Role,
18
+ TextPart,
19
+ )
20
+ from a2a.utils import message as message_sdk_utils
21
+
22
+
23
+ # --- Creation Helpers ---
24
+
25
+
26
+ def create_agent_text_message(
27
+ text: str,
28
+ task_id: Optional[str] = None,
29
+ context_id: Optional[str] = None,
30
+ message_id: Optional[str] = None,
31
+ ) -> Message:
32
+ """
33
+ Creates a new agent message containing a single TextPart.
34
+
35
+ Args:
36
+ text: The text content of the message.
37
+ task_id: The task ID for the message.
38
+ context_id: The context ID for the message.
39
+ message_id: The message ID. If None, a new UUID is generated.
40
+
41
+ Returns:
42
+ A new `Message` object with role 'agent'.
43
+ """
44
+ return Message(
45
+ role=Role.agent,
46
+ parts=[Part(root=TextPart(text=text))],
47
+ message_id=message_id or str(uuid.uuid4().hex),
48
+ task_id=task_id,
49
+ context_id=context_id,
50
+ kind="message",
51
+ )
52
+
53
+
54
+ def create_agent_data_message(
55
+ data: dict[str, Any],
56
+ task_id: Optional[str] = None,
57
+ context_id: Optional[str] = None,
58
+ message_id: Optional[str] = None,
59
+ part_metadata: Optional[Dict[str, Any]] = None,
60
+ ) -> Message:
61
+ """
62
+ Creates a new agent message containing a single DataPart.
63
+
64
+ Args:
65
+ data: The structured data content of the message.
66
+ task_id: The task ID for the message.
67
+ context_id: The context ID for the message.
68
+ message_id: The message ID. If None, a new UUID is generated.
69
+ part_metadata: Optional metadata for the DataPart.
70
+
71
+ Returns:
72
+ A new `Message` object with role 'agent'.
73
+ """
74
+ data_part = DataPart(data=data, metadata=part_metadata)
75
+ return Message(
76
+ role=Role.agent,
77
+ parts=[Part(root=data_part)],
78
+ message_id=message_id or str(uuid.uuid4().hex),
79
+ task_id=task_id,
80
+ context_id=context_id,
81
+ kind="message",
82
+ )
83
+
84
+
85
+ def create_agent_parts_message(
86
+ parts: List[ContentPart],
87
+ task_id: Optional[str] = None,
88
+ context_id: Optional[str] = None,
89
+ message_id: Optional[str] = None,
90
+ metadata: Optional[Dict[str, Any]] = None,
91
+ ) -> Message:
92
+ """
93
+ Creates a new agent message containing a list of Parts.
94
+
95
+ Args:
96
+ parts: The list of content `Part` objects (e.g. TextPart, DataPart).
97
+ task_id: The task ID for the message.
98
+ context_id: The context ID for the message.
99
+ message_id: The message ID. If None, a new UUID is generated.
100
+ metadata: Optional metadata for the message.
101
+
102
+ Returns:
103
+ A new `Message` object with role 'agent'.
104
+ """
105
+ wrapped_parts = [Part(root=p) for p in parts]
106
+ return Message(
107
+ role=Role.agent,
108
+ parts=wrapped_parts,
109
+ message_id=message_id or str(uuid.uuid4().hex),
110
+ task_id=task_id,
111
+ context_id=context_id,
112
+ metadata=metadata,
113
+ kind="message",
114
+ )
115
+
116
+
117
+ def create_user_message(
118
+ parts: List[ContentPart],
119
+ task_id: Optional[str] = None,
120
+ context_id: Optional[str] = None,
121
+ message_id: Optional[str] = None,
122
+ metadata: Optional[Dict[str, Any]] = None,
123
+ ) -> Message:
124
+ """
125
+ Creates a new user message containing a list of Parts.
126
+
127
+ Args:
128
+ parts: The list of content `Part` objects (e.g. TextPart, DataPart).
129
+ task_id: The task ID for the message.
130
+ context_id: The context ID for the message.
131
+ message_id: The message ID. If None, a new UUID is generated.
132
+ metadata: Optional metadata for the message.
133
+
134
+ Returns:
135
+ A new `Message` object with role 'user'.
136
+ """
137
+ wrapped_parts = [Part(root=p) for p in parts]
138
+ return Message(
139
+ role=Role.user,
140
+ parts=wrapped_parts,
141
+ message_id=message_id or str(uuid.uuid4().hex),
142
+ task_id=task_id,
143
+ context_id=context_id,
144
+ metadata=metadata,
145
+ kind="message",
146
+ )
147
+
148
+
149
+ def create_text_part(text: str, metadata: Optional[Dict[str, Any]] = None) -> TextPart:
150
+ """Creates a TextPart object."""
151
+ return TextPart(text=text, metadata=metadata)
152
+
153
+
154
+ def create_file_part_from_uri(
155
+ uri: str,
156
+ name: Optional[str] = None,
157
+ mime_type: Optional[str] = None,
158
+ metadata: Optional[Dict[str, Any]] = None,
159
+ ) -> FilePart:
160
+ """Creates a FilePart object from a URI."""
161
+ file_content = FileWithUri(uri=uri, name=name, mime_type=mime_type)
162
+ return FilePart(file=file_content, metadata=metadata)
163
+
164
+
165
+ def create_file_part_from_bytes(
166
+ content_bytes: bytes,
167
+ name: Optional[str] = None,
168
+ mime_type: Optional[str] = None,
169
+ metadata: Optional[Dict[str, Any]] = None,
170
+ ) -> FilePart:
171
+ """Creates a FilePart object from bytes."""
172
+ encoded_bytes = base64.b64encode(content_bytes).decode("utf-8")
173
+ file_content = FileWithBytes(bytes=encoded_bytes, name=name, mime_type=mime_type)
174
+ return FilePart(file=file_content, metadata=metadata)
175
+
176
+
177
+ def create_data_part(
178
+ data: Dict[str, Any], metadata: Optional[Dict[str, Any]] = None
179
+ ) -> DataPart:
180
+ """Creates a DataPart object."""
181
+ return DataPart(data=data, metadata=metadata)
182
+
183
+
184
+ def update_message_parts(message: Message, new_parts: List[ContentPart]) -> Message:
185
+ """Returns a new Message with its parts replaced."""
186
+ wrapped_parts = [Part(root=p) for p in new_parts]
187
+ return message.model_copy(update={"parts": wrapped_parts})
188
+
189
+
190
+ # --- Consumption Helpers ---
191
+
192
+
193
+ def get_text_from_message(message: Message, delimiter: str = "\n") -> str:
194
+ """
195
+ Extracts and joins all text content from a Message's parts.
196
+
197
+ Args:
198
+ message: The `Message` object.
199
+ delimiter: The string to use when joining text from multiple TextParts.
200
+
201
+ Returns:
202
+ A single string containing all text content, or an empty string if no text parts are found.
203
+ """
204
+ return message_sdk_utils.get_message_text(message, delimiter=delimiter)
205
+
206
+
207
+ def get_data_parts_from_message(message: Message) -> List[DataPart]:
208
+ """
209
+ Extracts DataPart objects from a Message's parts.
210
+
211
+ Args:
212
+ message: The `Message` object.
213
+
214
+ Returns:
215
+ A list of `DataPart` objects found.
216
+ """
217
+ return [part.root for part in message.parts if isinstance(part.root, DataPart)]
218
+
219
+
220
+ def get_file_parts_from_message(message: Message) -> List[FilePart]:
221
+ """
222
+ Extracts FilePart objects from a Message's parts.
223
+
224
+ Args:
225
+ message: The `Message` object.
226
+
227
+ Returns:
228
+ A list of `FilePart` objects found.
229
+ """
230
+ return [part.root for part in message.parts if isinstance(part.root, FilePart)]
231
+
232
+
233
+ def get_message_id(message: Message) -> str:
234
+ """Safely retrieves the ID from a Message object."""
235
+ return message.message_id
236
+
237
+
238
+ def get_context_id(message: Message) -> Optional[str]:
239
+ """Safely retrieves the context ID from a Message object."""
240
+ return message.context_id
241
+
242
+
243
+ def get_task_id(message: Message) -> Optional[str]:
244
+ """Safely retrieves the task ID from a Message object."""
245
+ return message.task_id
246
+
247
+
248
+ def get_parts_from_message(message: Message) -> List[ContentPart]:
249
+ """
250
+ Extracts the raw, unwrapped Part objects (TextPart, DataPart, etc.) from a Message.
251
+
252
+ Args:
253
+ message: The `Message` object.
254
+
255
+ Returns:
256
+ A list of the unwrapped content parts.
257
+ """
258
+ return [part.root for part in message.parts]
259
+
260
+
261
+ def get_text_from_text_part(part: TextPart) -> str:
262
+ """Safely retrieves the text from a TextPart object."""
263
+ return part.text
264
+
265
+
266
+ def get_data_from_data_part(part: DataPart) -> Dict[str, Any]:
267
+ """Safely retrieves the data dictionary from a DataPart object."""
268
+ return part.data
269
+
270
+
271
+ def get_metadata_from_part(part: ContentPart) -> Optional[Dict[str, Any]]:
272
+ """Safely retrieves the metadata from any Part object."""
273
+ return part.metadata
274
+
275
+
276
+ def get_file_from_file_part(
277
+ part: FilePart,
278
+ ) -> Optional[Union[FileWithUri, FileWithBytes]]:
279
+ """Safely retrieves the File object from a FilePart."""
280
+ return part.file
281
+
282
+
283
+ def get_uri_from_file_part(part: FilePart) -> Optional[str]:
284
+ """Safely retrieves the URI from a FilePart, if it exists."""
285
+ if isinstance(part.file, FileWithUri):
286
+ return part.file.uri
287
+ return None
288
+
289
+
290
+ def get_bytes_from_file_part(part: FilePart) -> Optional[bytes]:
291
+ """Safely retrieves and decodes the bytes from a FilePart, if they exist."""
292
+ if isinstance(part.file, FileWithBytes) and part.file.bytes:
293
+ try:
294
+ return base64.b64decode(part.file.bytes)
295
+ except (TypeError, ValueError):
296
+ return None
297
+ return None
298
+
299
+
300
+ def get_filename_from_file_part(part: FilePart) -> Optional[str]:
301
+ """Safely retrieves the filename from a FilePart."""
302
+ return part.file.name
303
+
304
+
305
+ def get_mimetype_from_file_part(part: FilePart) -> Optional[str]:
306
+ """Safely retrieves the MIME type from a FilePart."""
307
+ return part.file.mime_type