waldiez 0.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 waldiez might be problematic. Click here for more details.

Files changed (94) hide show
  1. waldiez/__init__.py +15 -0
  2. waldiez/__main__.py +6 -0
  3. waldiez/_version.py +3 -0
  4. waldiez/cli.py +162 -0
  5. waldiez/exporter.py +293 -0
  6. waldiez/exporting/__init__.py +14 -0
  7. waldiez/exporting/agents/__init__.py +5 -0
  8. waldiez/exporting/agents/agent.py +229 -0
  9. waldiez/exporting/agents/agent_skills.py +67 -0
  10. waldiez/exporting/agents/code_execution.py +67 -0
  11. waldiez/exporting/agents/group_manager.py +209 -0
  12. waldiez/exporting/agents/llm_config.py +53 -0
  13. waldiez/exporting/agents/rag_user/__init__.py +5 -0
  14. waldiez/exporting/agents/rag_user/chroma_utils.py +134 -0
  15. waldiez/exporting/agents/rag_user/mongo_utils.py +83 -0
  16. waldiez/exporting/agents/rag_user/pgvector_utils.py +93 -0
  17. waldiez/exporting/agents/rag_user/qdrant_utils.py +112 -0
  18. waldiez/exporting/agents/rag_user/rag_user.py +165 -0
  19. waldiez/exporting/agents/rag_user/vector_db.py +119 -0
  20. waldiez/exporting/agents/teachability.py +37 -0
  21. waldiez/exporting/agents/termination_message.py +45 -0
  22. waldiez/exporting/chats/__init__.py +14 -0
  23. waldiez/exporting/chats/chats.py +46 -0
  24. waldiez/exporting/chats/helpers.py +395 -0
  25. waldiez/exporting/chats/nested.py +264 -0
  26. waldiez/exporting/flow/__init__.py +5 -0
  27. waldiez/exporting/flow/def_main.py +37 -0
  28. waldiez/exporting/flow/flow.py +185 -0
  29. waldiez/exporting/models/__init__.py +193 -0
  30. waldiez/exporting/skills/__init__.py +128 -0
  31. waldiez/exporting/utils/__init__.py +34 -0
  32. waldiez/exporting/utils/comments.py +136 -0
  33. waldiez/exporting/utils/importing.py +267 -0
  34. waldiez/exporting/utils/logging_utils.py +203 -0
  35. waldiez/exporting/utils/method_utils.py +35 -0
  36. waldiez/exporting/utils/naming.py +127 -0
  37. waldiez/exporting/utils/object_string.py +81 -0
  38. waldiez/io_stream.py +181 -0
  39. waldiez/models/__init__.py +107 -0
  40. waldiez/models/agents/__init__.py +65 -0
  41. waldiez/models/agents/agent/__init__.py +21 -0
  42. waldiez/models/agents/agent/agent.py +190 -0
  43. waldiez/models/agents/agent/agent_data.py +162 -0
  44. waldiez/models/agents/agent/code_execution.py +71 -0
  45. waldiez/models/agents/agent/linked_skill.py +30 -0
  46. waldiez/models/agents/agent/nested_chat.py +73 -0
  47. waldiez/models/agents/agent/teachability.py +68 -0
  48. waldiez/models/agents/agent/termination_message.py +167 -0
  49. waldiez/models/agents/agents.py +129 -0
  50. waldiez/models/agents/assistant/__init__.py +6 -0
  51. waldiez/models/agents/assistant/assistant.py +41 -0
  52. waldiez/models/agents/assistant/assistant_data.py +29 -0
  53. waldiez/models/agents/group_manager/__init__.py +19 -0
  54. waldiez/models/agents/group_manager/group_manager.py +87 -0
  55. waldiez/models/agents/group_manager/group_manager_data.py +91 -0
  56. waldiez/models/agents/group_manager/speakers.py +211 -0
  57. waldiez/models/agents/rag_user/__init__.py +26 -0
  58. waldiez/models/agents/rag_user/rag_user.py +58 -0
  59. waldiez/models/agents/rag_user/rag_user_data.py +32 -0
  60. waldiez/models/agents/rag_user/retrieve_config.py +592 -0
  61. waldiez/models/agents/rag_user/vector_db_config.py +162 -0
  62. waldiez/models/agents/user_proxy/__init__.py +6 -0
  63. waldiez/models/agents/user_proxy/user_proxy.py +41 -0
  64. waldiez/models/agents/user_proxy/user_proxy_data.py +30 -0
  65. waldiez/models/chat/__init__.py +22 -0
  66. waldiez/models/chat/chat.py +129 -0
  67. waldiez/models/chat/chat_data.py +326 -0
  68. waldiez/models/chat/chat_message.py +304 -0
  69. waldiez/models/chat/chat_nested.py +160 -0
  70. waldiez/models/chat/chat_summary.py +110 -0
  71. waldiez/models/common/__init__.py +38 -0
  72. waldiez/models/common/base.py +63 -0
  73. waldiez/models/common/method_utils.py +165 -0
  74. waldiez/models/flow/__init__.py +9 -0
  75. waldiez/models/flow/flow.py +302 -0
  76. waldiez/models/flow/flow_data.py +87 -0
  77. waldiez/models/model/__init__.py +11 -0
  78. waldiez/models/model/model.py +169 -0
  79. waldiez/models/model/model_data.py +86 -0
  80. waldiez/models/skill/__init__.py +9 -0
  81. waldiez/models/skill/skill.py +129 -0
  82. waldiez/models/skill/skill_data.py +37 -0
  83. waldiez/models/waldiez.py +301 -0
  84. waldiez/py.typed +0 -0
  85. waldiez/runner.py +304 -0
  86. waldiez/stream/__init__.py +7 -0
  87. waldiez/stream/consumer.py +139 -0
  88. waldiez/stream/provider.py +339 -0
  89. waldiez/stream/server.py +412 -0
  90. waldiez-0.1.0.dist-info/METADATA +181 -0
  91. waldiez-0.1.0.dist-info/RECORD +94 -0
  92. waldiez-0.1.0.dist-info/WHEEL +4 -0
  93. waldiez-0.1.0.dist-info/entry_points.txt +2 -0
  94. waldiez-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,326 @@
1
+ """Chat data model."""
2
+
3
+ from typing import Any, Dict, Optional, Union
4
+
5
+ from pydantic import ConfigDict, Field, field_validator, model_validator
6
+ from pydantic.alias_generators import to_camel
7
+ from typing_extensions import Annotated, Self
8
+
9
+ from ..common import WaldiezBase
10
+ from .chat_message import WaldiezChatMessage, validate_message_dict
11
+ from .chat_nested import WaldiezChatNested
12
+ from .chat_summary import WaldiezChatSummary
13
+
14
+
15
+ class WaldiezChatData(WaldiezBase):
16
+ """Chat data class.
17
+
18
+ Attributes
19
+ ----------
20
+ name : str
21
+ The name of the chat.
22
+ source : str
23
+ The source of the chat (sender).
24
+ target : str
25
+ The target of the chat (recipient).
26
+ description : str
27
+ The description of the chat.
28
+ position : int
29
+ The position of the chat. Ignored (UI related).
30
+ order : int
31
+ The of the chat. If negative, ignored.
32
+ clear_history : Optional[bool], optional
33
+ Whether to clear the chat history, by default None.
34
+ message : Union[str, WaldiezChatMessage]
35
+ The message of the chat.
36
+ nested_chat : WaldiezChatNested
37
+ The nested chat config.
38
+ summary : WaldiezChatSummary
39
+ The summary method and options for the chat.
40
+ max_turns : Optional[int]
41
+ The maximum number of turns for the chat, by default None (no limit).
42
+ silent : Optional[bool], optional
43
+ Whether to run the chat silently, by default None (ignored).
44
+ summary_args : Optional[Dict[str, Any]]
45
+ The summary args to use in autogen.
46
+ real_source : Optional[str]
47
+ The real source of the chat (overrides the source).
48
+ real_target : Optional[str]
49
+ The real target of the chat (overrides the target).
50
+
51
+ Functions
52
+ ---------
53
+ validate_message(value: Any)
54
+ Validate the message.
55
+ validate_summary_method(value: Optional[WaldiezChatSummaryMethod])
56
+ Validate the summary method.
57
+ serialize_summary_method(value: Any, info: FieldSerializationInfo)
58
+ Serialize summary method.
59
+ get_chat_args()
60
+ Get the chat arguments to use in autogen.
61
+ """
62
+
63
+ model_config = ConfigDict(
64
+ extra="forbid",
65
+ alias_generator=to_camel,
66
+ populate_by_name=True,
67
+ frozen=False,
68
+ )
69
+
70
+ name: Annotated[
71
+ str, Field(..., title="Name", description="The name of the chat.")
72
+ ]
73
+ source: Annotated[
74
+ str,
75
+ Field(
76
+ ...,
77
+ title="Source",
78
+ description="The source of the chat (sender).",
79
+ ),
80
+ ]
81
+ target: Annotated[
82
+ str,
83
+ Field(
84
+ ...,
85
+ title="Target",
86
+ description="The target of the chat (recipient).",
87
+ ),
88
+ ]
89
+ description: Annotated[
90
+ str,
91
+ Field(
92
+ ...,
93
+ title="Description",
94
+ description="The description of the chat.",
95
+ ),
96
+ ]
97
+ position: Annotated[
98
+ int,
99
+ Field(
100
+ -1,
101
+ title="Position",
102
+ description="The position of the chat in the flow (Ignored).",
103
+ ),
104
+ ]
105
+ order: Annotated[
106
+ int,
107
+ Field(
108
+ -1,
109
+ title="Order",
110
+ description="The order of the chat in the flow.",
111
+ ),
112
+ ]
113
+ clear_history: Annotated[
114
+ Optional[bool],
115
+ Field(
116
+ None,
117
+ alias="clearHistory",
118
+ title="Clear History",
119
+ description="Whether to clear the chat history.",
120
+ ),
121
+ ]
122
+ message: Annotated[
123
+ Union[str, WaldiezChatMessage],
124
+ Field(
125
+ title="Message",
126
+ description="The message of the chat.",
127
+ default_factory=WaldiezChatMessage,
128
+ ),
129
+ ]
130
+ nested_chat: Annotated[
131
+ WaldiezChatNested,
132
+ Field(
133
+ title="Nested Chat",
134
+ description="The nested chat.",
135
+ alias="nestedChat",
136
+ default_factory=WaldiezChatNested,
137
+ ),
138
+ ]
139
+ summary: Annotated[
140
+ WaldiezChatSummary,
141
+ Field(
142
+ default_factory=WaldiezChatSummary,
143
+ title="Summary",
144
+ description="The summary method options for the chat.",
145
+ ),
146
+ ]
147
+ max_turns: Annotated[
148
+ Optional[int],
149
+ Field(
150
+ None,
151
+ alias="maxTurns",
152
+ title="Max Turns",
153
+ description="The maximum number of turns for the chat.",
154
+ ),
155
+ ]
156
+ silent: Annotated[
157
+ Optional[bool],
158
+ Field(
159
+ None,
160
+ title="Silent",
161
+ description="Whether to run the chat silently.",
162
+ ),
163
+ ]
164
+ real_source: Annotated[
165
+ Optional[str],
166
+ Field(
167
+ None,
168
+ alias="realSource",
169
+ title="Real Source",
170
+ description="The real source of the chat (overrides the source).",
171
+ ),
172
+ ]
173
+ real_target: Annotated[
174
+ Optional[str],
175
+ Field(
176
+ None,
177
+ alias="realTarget",
178
+ title="Real Target",
179
+ description="The real target of the chat (overrides the target).",
180
+ ),
181
+ ]
182
+
183
+ _message_content: Optional[str] = None
184
+
185
+ @property
186
+ def message_content(self) -> Optional[str]:
187
+ """Get the message content."""
188
+ return self._message_content
189
+
190
+ @model_validator(mode="after")
191
+ def validate_chat_data(self) -> Self:
192
+ """Validate the chat data.
193
+
194
+ Returns
195
+ -------
196
+ WaldiezChatData
197
+ The validated chat data.
198
+
199
+ Raises
200
+ ------
201
+ ValueError
202
+ If the validation fails.
203
+ """
204
+ if isinstance(self.message, WaldiezChatMessage):
205
+ if self.message.type == "none":
206
+ self._message_content = None
207
+ elif self.message.type == "string":
208
+ self._message_content = self.message.content
209
+ else:
210
+ self._message_content = validate_message_dict(
211
+ value={
212
+ "type": self.message.type,
213
+ "content": self.message.content,
214
+ "use_carryover": self.message.use_carryover,
215
+ },
216
+ function_name="callable_message",
217
+ skip_definition=True,
218
+ ).content
219
+ return self
220
+
221
+ @field_validator("message", mode="before")
222
+ @classmethod
223
+ def validate_message(cls, value: Any) -> WaldiezChatMessage:
224
+ """Validate the message.
225
+
226
+ Parameters
227
+ ----------
228
+ value : Any
229
+ The message value.
230
+
231
+ Returns
232
+ -------
233
+ WaldiezChatMessage
234
+ The validated message value.
235
+
236
+ Raises
237
+ ------
238
+ ValueError
239
+ If the validation fails.
240
+ """
241
+ if value is None:
242
+ return WaldiezChatMessage(
243
+ type="none", use_carryover=False, content=None, context={}
244
+ )
245
+ if isinstance(value, str):
246
+ return WaldiezChatMessage(
247
+ type="string", use_carryover=False, content=value, context={}
248
+ )
249
+ if isinstance(value, dict):
250
+ return validate_message_dict(
251
+ value, function_name="callable_message"
252
+ )
253
+ if isinstance(value, WaldiezChatMessage):
254
+ return validate_message_dict(
255
+ value={
256
+ "type": value.type,
257
+ "use_carryover": value.use_carryover,
258
+ "content": value.content,
259
+ "context": value.context,
260
+ },
261
+ function_name="callable_message",
262
+ )
263
+ return WaldiezChatMessage(
264
+ type="none", use_carryover=False, content=None, context={}
265
+ )
266
+
267
+ @property
268
+ def summary_args(self) -> Optional[Dict[str, Any]]:
269
+ """Get the summary args."""
270
+ if self.summary.method not in (
271
+ "reflection_with_llm",
272
+ "reflectionWithLlm",
273
+ ):
274
+ return None
275
+ args: Dict[str, Any] = {}
276
+ if self.summary.prompt:
277
+ args["summary_prompt"] = self.summary.prompt
278
+ if self.summary.args:
279
+ args.update(self.summary.args)
280
+ return args
281
+
282
+ def _get_context_args(self) -> Dict[str, Any]:
283
+ """Get the context arguments to use in autogen.
284
+
285
+ Returns
286
+ -------
287
+ Dict[str, Any]
288
+ The dictionary to use for generating the kwargs.
289
+ """
290
+ extra_args: Dict[str, Any] = {}
291
+ if isinstance(self.message, WaldiezChatMessage):
292
+ for key, value in self.message.context.items():
293
+ if str(value).lower() in ("none", "null"):
294
+ extra_args[key] = None
295
+ elif str(value).isdigit():
296
+ extra_args[key] = int(value)
297
+ elif str(value).replace(".", "").isdigit():
298
+ try:
299
+ extra_args[key] = float(value)
300
+ except ValueError: # pragma: no cover
301
+ extra_args[key] = value
302
+ else:
303
+ extra_args[key] = value
304
+ return extra_args
305
+
306
+ def get_chat_args(self) -> Dict[str, Any]:
307
+ """Get the chat arguments to use in autogen.
308
+
309
+ Returns
310
+ -------
311
+ Dict[str, Any]
312
+ The dictionary to pass as kwargs.
313
+ """
314
+ args: Dict[str, Any] = {}
315
+ if self.summary.method:
316
+ args["summary_method"] = self.summary.method
317
+ if self.summary_args:
318
+ args["summary_args"] = self.summary_args
319
+ if isinstance(self.max_turns, int) and self.max_turns > 0:
320
+ args["max_turns"] = self.max_turns
321
+ if isinstance(self.clear_history, bool):
322
+ args["clear_history"] = self.clear_history
323
+ if isinstance(self.silent, bool):
324
+ args["silent"] = self.silent
325
+ args.update(self._get_context_args())
326
+ return args
@@ -0,0 +1,304 @@
1
+ """Waldiez Message Model."""
2
+
3
+ from typing import Any, Dict, Optional, Tuple, Union
4
+
5
+ from pydantic import Field
6
+ from typing_extensions import Annotated, Literal
7
+
8
+ from ..common import WaldiezBase, WaldiezMethodName, check_function
9
+
10
+ WaldiezChatMessageType = Literal[
11
+ "string", "method", "rag_message_generator", "none"
12
+ ]
13
+
14
+
15
+ class WaldiezChatMessage(WaldiezBase):
16
+ """
17
+ Waldiez Message.
18
+
19
+ A generic message with a type and content.
20
+
21
+ If the type is not `none`, the content is a string.
22
+ If the type is 'method', the content is the source code of a method.
23
+ If the type is 'last_carryover', the content is a method to return
24
+ the last carryover from the context.
25
+ If the type is 'rag_message_generator', and the sender is a RAG user agent,
26
+ the content will be generated by the `sender.message_generator` method.
27
+
28
+ Attributes
29
+ ----------
30
+ type : WaldiezChatMessageType
31
+ The type of the message:
32
+ - string
33
+ - method
34
+ - rag_message_generator
35
+ - none
36
+ If the sender is a RAG user agent,
37
+ and the type is `rag_message_generator`,
38
+ the `{sender}.message_generator` method will be used.
39
+ content : Optional[str]
40
+ The content of the message (string or method).
41
+ context : Dict[str, Any]
42
+ Extra context of the message.
43
+ """
44
+
45
+ type: Annotated[
46
+ WaldiezChatMessageType,
47
+ Field(
48
+ "none",
49
+ title="Type",
50
+ description=(
51
+ "The type of the message: "
52
+ "`string`, `method`, "
53
+ "`rag_message_generator` or `none`."
54
+ "If last_carryover, a method to return the context's"
55
+ "last carryover will be used."
56
+ "If the sender is a RAG user agent, "
57
+ "and the type is `message_generator`,"
58
+ "the `sender.message_generator` method will be used."
59
+ ),
60
+ ),
61
+ ]
62
+ use_carryover: Annotated[
63
+ bool,
64
+ Field(
65
+ False,
66
+ title="Use Carryover",
67
+ description="Use the carryover from the context.",
68
+ ),
69
+ ]
70
+ content: Annotated[
71
+ Optional[str],
72
+ Field(
73
+ None,
74
+ title="Content",
75
+ description="The content of the message (string or method).",
76
+ ),
77
+ ]
78
+ context: Annotated[
79
+ Dict[str, Any],
80
+ Field(
81
+ default_factory=dict,
82
+ title="Context",
83
+ description="Extra context of the message.",
84
+ ),
85
+ ]
86
+
87
+
88
+ def validate_message_dict(
89
+ value: Dict[
90
+ Literal["type", "use_carryover", "content", "context"],
91
+ Union[Optional[str], Optional[bool], Optional[Dict[str, Any]]],
92
+ ],
93
+ function_name: WaldiezMethodName,
94
+ skip_definition: bool = False,
95
+ ) -> WaldiezChatMessage:
96
+ """Validate a message dict.
97
+
98
+ Check the provided message dict.
99
+ Depending on the type, the content is validated.
100
+ If the type is "method", the content is checked against the function name.
101
+
102
+ Parameters
103
+ ----------
104
+ value : dict
105
+ The message dict.
106
+ function_name : str (WaldiezMethodName)
107
+ The function name.
108
+ skip_definition : bool, optional
109
+ Skip the function definition in the content, by default False
110
+
111
+ Returns
112
+ -------
113
+ WaldiezChatMessage
114
+ The validated message.
115
+
116
+ Raises
117
+ ------
118
+ ValueError
119
+ If the validation fails.
120
+ """
121
+ message_type, use_carryover, content, context = _get_message_args_from_dict(
122
+ value
123
+ )
124
+ if message_type == "string":
125
+ if not content or not isinstance(content, str):
126
+ content = ""
127
+ if use_carryover:
128
+ method_content = _get_last_carryover_method_content(content)
129
+ return WaldiezChatMessage(
130
+ type="method",
131
+ use_carryover=True,
132
+ content=method_content,
133
+ context=context,
134
+ )
135
+ return WaldiezChatMessage(
136
+ type="string",
137
+ use_carryover=False,
138
+ content=content,
139
+ context=context,
140
+ )
141
+ if message_type == "none":
142
+ return WaldiezChatMessage(
143
+ type="none",
144
+ use_carryover=False,
145
+ content=None,
146
+ context=context,
147
+ )
148
+ if message_type == "method":
149
+ if not content:
150
+ raise ValueError(
151
+ "The message content is required for the method type"
152
+ )
153
+ valid, error_or_content = check_function(
154
+ content, function_name, skip_type_hints=use_carryover
155
+ )
156
+ if not valid:
157
+ raise ValueError(error_or_content)
158
+ message_content = error_or_content if skip_definition else content
159
+ return WaldiezChatMessage(
160
+ type="method",
161
+ use_carryover=use_carryover,
162
+ content=message_content,
163
+ context=context,
164
+ )
165
+ if message_type == "rag_message_generator":
166
+ if use_carryover:
167
+ return WaldiezChatMessage(
168
+ type="method",
169
+ use_carryover=True,
170
+ content=RAG_METHOD_WITH_CARRYOVER,
171
+ context=context,
172
+ )
173
+ return WaldiezChatMessage(
174
+ type="rag_message_generator",
175
+ use_carryover=use_carryover,
176
+ content=None,
177
+ context=context,
178
+ )
179
+ raise ValueError("Invalid message type") # pragma: no cover
180
+
181
+
182
+ def _get_message_args_from_dict(
183
+ value: Dict[
184
+ Literal["type", "use_carryover", "content", "context"],
185
+ Union[Optional[str], Optional[bool], Optional[Dict[str, Any]]],
186
+ ],
187
+ ) -> Tuple[str, bool, Optional[str], Dict[str, Any]]:
188
+ """Get the message args from a dict.
189
+
190
+ Parameters
191
+ ----------
192
+ value : dict
193
+ The message dict.
194
+
195
+ Returns
196
+ -------
197
+ tuple
198
+ The message type, content, and context.
199
+
200
+ Raises
201
+ ------
202
+ ValueError
203
+ If the message type is invalid.
204
+ """
205
+ message_type = value.get("type")
206
+ if not isinstance(message_type, str) or message_type not in (
207
+ "string",
208
+ "method",
209
+ "rag_message_generator",
210
+ "none",
211
+ ):
212
+ raise ValueError("Invalid message type")
213
+ use_carryover = value.get("use_carryover", False)
214
+ if not isinstance(use_carryover, bool):
215
+ use_carryover = False
216
+ content = value.get("content", "")
217
+ if not isinstance(content, str):
218
+ content = ""
219
+ context: Dict[str, Any] = {}
220
+ context_value = value.get("context")
221
+ if isinstance(context_value, dict):
222
+ context = context_value
223
+ if not isinstance(context, dict): # pragma: no cover
224
+ context = {}
225
+ return message_type, use_carryover, content, context
226
+
227
+
228
+ def _get_last_carryover_method_content(text_content: str) -> str:
229
+ """Get the last carryover method content.
230
+
231
+ Parameters
232
+ ----------
233
+ text_content : str
234
+ Text content before the carryover.
235
+ Returns
236
+ -------
237
+ str
238
+ The last carryover method content.
239
+ """
240
+ method_content = '''
241
+ def callable_message(sender, recipient, context):
242
+ # type: (ConversableAgent, ConversableAgent, dict) -> Union[dict, str]
243
+ """Get the message to send using the last carryover.
244
+
245
+ Parameters
246
+ ----------
247
+ sender : ConversableAgent
248
+ The source agent.
249
+ recipient : ConversableAgent
250
+ The target agent.
251
+ context : dict
252
+ The context.
253
+
254
+ Returns
255
+ -------
256
+ Union[dict, str]
257
+ The message to send using the last carryover.
258
+ """
259
+ carryover = context.get("carryover", "")
260
+ if isinstance(carryover, list):
261
+ carryover = carryover[-1]
262
+ if not isinstance(carryover, str):
263
+ carryover = ""'''
264
+ if text_content:
265
+ method_content += f"""
266
+ final_message = "{text_content}" + carryover
267
+ return final_message
268
+ """
269
+ else:
270
+ method_content += """
271
+ return carryover
272
+ """
273
+ return method_content
274
+
275
+
276
+ RAG_METHOD_WITH_CARRYOVER = '''
277
+ def callable_message(sender, recipient, context):
278
+ # type: (RetrieveUserProxyAgent, ConversableAgent, dict) -> Union[dict, str]
279
+ """Get the message using the RAG message generator method.
280
+
281
+ Parameters
282
+ ----------
283
+ sender : RetrieveUserProxyAgent
284
+ The source agent.
285
+ recipient : ConversableAgent
286
+ The target agent.
287
+ context : dict
288
+ The context.
289
+
290
+ Returns
291
+ -------
292
+ Union[dict, str]
293
+ The message to send using the last carryover.
294
+ """
295
+ carryover = context.get("carryover", "")
296
+ if isinstance(carryover, list):
297
+ carryover = carryover[-1]
298
+ if not isinstance(carryover, str):
299
+ carryover = ""
300
+ message = sender.message_generator(sender, recipient, context)
301
+ if carryover:
302
+ message += carryover
303
+ return message
304
+ '''