lionagi 0.0.305__py3-none-any.whl → 0.0.307__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.
Files changed (84) hide show
  1. lionagi/__init__.py +2 -5
  2. lionagi/core/__init__.py +7 -4
  3. lionagi/core/agent/__init__.py +3 -0
  4. lionagi/core/agent/base_agent.py +46 -0
  5. lionagi/core/branch/__init__.py +4 -0
  6. lionagi/core/branch/base/__init__.py +0 -0
  7. lionagi/core/branch/base_branch.py +100 -78
  8. lionagi/core/branch/branch.py +22 -34
  9. lionagi/core/branch/branch_flow_mixin.py +3 -7
  10. lionagi/core/branch/executable_branch.py +192 -0
  11. lionagi/core/branch/util.py +77 -162
  12. lionagi/core/direct/__init__.py +13 -0
  13. lionagi/core/direct/parallel_predict.py +127 -0
  14. lionagi/core/direct/parallel_react.py +0 -0
  15. lionagi/core/direct/parallel_score.py +0 -0
  16. lionagi/core/direct/parallel_select.py +0 -0
  17. lionagi/core/direct/parallel_sentiment.py +0 -0
  18. lionagi/core/direct/predict.py +174 -0
  19. lionagi/core/direct/react.py +33 -0
  20. lionagi/core/direct/score.py +163 -0
  21. lionagi/core/direct/select.py +144 -0
  22. lionagi/core/direct/sentiment.py +51 -0
  23. lionagi/core/direct/utils.py +83 -0
  24. lionagi/core/flow/__init__.py +0 -3
  25. lionagi/core/flow/monoflow/{mono_react.py → ReAct.py} +52 -9
  26. lionagi/core/flow/monoflow/__init__.py +9 -0
  27. lionagi/core/flow/monoflow/{mono_chat.py → chat.py} +11 -11
  28. lionagi/core/flow/monoflow/{mono_chat_mixin.py → chat_mixin.py} +33 -27
  29. lionagi/core/flow/monoflow/{mono_followup.py → followup.py} +7 -6
  30. lionagi/core/flow/polyflow/__init__.py +1 -0
  31. lionagi/core/flow/polyflow/{polychat.py → chat.py} +15 -3
  32. lionagi/core/mail/__init__.py +8 -0
  33. lionagi/core/mail/mail_manager.py +88 -40
  34. lionagi/core/mail/schema.py +32 -6
  35. lionagi/core/messages/__init__.py +3 -0
  36. lionagi/core/messages/schema.py +56 -25
  37. lionagi/core/prompt/__init__.py +0 -0
  38. lionagi/core/prompt/prompt_template.py +0 -0
  39. lionagi/core/schema/__init__.py +7 -5
  40. lionagi/core/schema/action_node.py +29 -0
  41. lionagi/core/schema/base_mixin.py +56 -59
  42. lionagi/core/schema/base_node.py +35 -38
  43. lionagi/core/schema/condition.py +24 -0
  44. lionagi/core/schema/data_logger.py +98 -98
  45. lionagi/core/schema/data_node.py +19 -19
  46. lionagi/core/schema/prompt_template.py +0 -0
  47. lionagi/core/schema/structure.py +293 -190
  48. lionagi/core/session/__init__.py +1 -3
  49. lionagi/core/session/session.py +196 -214
  50. lionagi/core/tool/tool_manager.py +95 -103
  51. lionagi/integrations/__init__.py +1 -3
  52. lionagi/integrations/bridge/langchain_/documents.py +17 -18
  53. lionagi/integrations/bridge/langchain_/langchain_bridge.py +14 -14
  54. lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +22 -22
  55. lionagi/integrations/bridge/llamaindex_/node_parser.py +12 -12
  56. lionagi/integrations/bridge/llamaindex_/reader.py +11 -11
  57. lionagi/integrations/bridge/llamaindex_/textnode.py +7 -7
  58. lionagi/integrations/config/openrouter_configs.py +0 -1
  59. lionagi/integrations/provider/oai.py +26 -26
  60. lionagi/integrations/provider/services.py +38 -38
  61. lionagi/libs/__init__.py +34 -1
  62. lionagi/libs/ln_api.py +211 -221
  63. lionagi/libs/ln_async.py +53 -60
  64. lionagi/libs/ln_convert.py +118 -120
  65. lionagi/libs/ln_dataframe.py +32 -33
  66. lionagi/libs/ln_func_call.py +334 -342
  67. lionagi/libs/ln_nested.py +99 -107
  68. lionagi/libs/ln_parse.py +175 -158
  69. lionagi/libs/sys_util.py +52 -52
  70. lionagi/tests/test_core/test_base_branch.py +427 -427
  71. lionagi/tests/test_core/test_branch.py +292 -292
  72. lionagi/tests/test_core/test_mail_manager.py +57 -57
  73. lionagi/tests/test_core/test_session.py +254 -266
  74. lionagi/tests/test_core/test_session_base_util.py +299 -300
  75. lionagi/tests/test_core/test_tool_manager.py +70 -74
  76. lionagi/tests/test_libs/test_nested.py +2 -7
  77. lionagi/tests/test_libs/test_parse.py +2 -2
  78. lionagi/version.py +1 -1
  79. {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/METADATA +4 -2
  80. lionagi-0.0.307.dist-info/RECORD +115 -0
  81. lionagi-0.0.305.dist-info/RECORD +0 -94
  82. {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/LICENSE +0 -0
  83. {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/WHEEL +0 -0
  84. {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,9 @@
1
1
  from abc import ABC
2
2
  from typing import Any, Optional, Union, TypeVar
3
3
 
4
- from lionagi.core.schema.base_node import TOOL_TYPE, Tool
5
- from lionagi.core.flow.monoflow.mono_chat import MonoChat
6
- from lionagi.core.flow.monoflow.mono_followup import MonoFollowup
7
- from lionagi.core.flow.monoflow.mono_react import MonoReAct
8
-
9
- from lionagi.core.messages.schema import Instruction, System
4
+ from ..schema import TOOL_TYPE, Tool
5
+ from ..messages import Instruction, System
6
+ from ..flow.monoflow import MonoChat, MonoFollowup, MonoReAct
10
7
 
11
8
  T = TypeVar("T", bound=Tool)
12
9
 
@@ -25,7 +22,6 @@ class BranchFlowMixin(ABC):
25
22
  output_fields=None,
26
23
  **kwargs,
27
24
  ) -> Any:
28
-
29
25
  flow = MonoChat(self)
30
26
  return await flow.chat(
31
27
  instruction=instruction,
@@ -0,0 +1,192 @@
1
+ import contextlib
2
+ from collections import deque
3
+ from typing import Any
4
+
5
+ from lionagi.libs import convert, AsyncUtil, ParseUtil
6
+
7
+ from ..schema import BaseRelatableNode, ActionNode
8
+ from ..mail import BaseMail
9
+ from ..messages import System, Instruction
10
+ from ..agent import BaseAgent
11
+
12
+ from .branch import Branch
13
+
14
+
15
+ class ExecutableBranch(BaseRelatableNode):
16
+
17
+ def __init__(self, verbose=True, **kwargs):
18
+ super().__init__()
19
+ self.branch: Branch = Branch(**kwargs)
20
+ self.pending_ins = {} # needed
21
+ self.pending_outs = deque() # needed
22
+ self.responses = []
23
+ self.execute_stop = False # needed
24
+ self.context = None # needed
25
+ self.context_log = []
26
+ self.verbose = verbose
27
+
28
+ def send(self, recipient_id: str, category: str, package: Any) -> None:
29
+ mail = BaseMail(
30
+ sender_id=self.id_,
31
+ recipient_id=recipient_id,
32
+ category=category,
33
+ package=package,
34
+ )
35
+ self.pending_outs.append(mail)
36
+
37
+ async def forward(self):
38
+ for key in list(self.pending_ins.keys()):
39
+ while self.pending_ins[key]:
40
+ mail = self.pending_ins[key].popleft()
41
+ if mail.category == "start": # needed
42
+ self._process_start(mail)
43
+ elif mail.category == "node":
44
+ await self._process_node(mail)
45
+ elif mail.category == "node_list":
46
+ self._process_node_list(mail)
47
+ elif mail.category == "condition":
48
+ self._process_condition(mail)
49
+ elif mail.category == "end": # needed
50
+ self._process_end(mail)
51
+
52
+ async def execute(self, refresh_time=1): # needed
53
+ while not self.execute_stop:
54
+ await self.forward()
55
+ await AsyncUtil.sleep(refresh_time)
56
+
57
+ async def _process_node(self, mail: BaseMail):
58
+
59
+ if isinstance(mail.package, System):
60
+ self._system_process(mail.package, verbose=self.verbose)
61
+ self.send(mail.sender_id, "node_id", mail.package.id_)
62
+
63
+ elif isinstance(mail.package, Instruction):
64
+ await self._instruction_process(mail.package, verbose=self.verbose)
65
+ self.send(mail.sender_id, "node_id", mail.package.id_)
66
+
67
+ elif isinstance(mail.package, ActionNode):
68
+ await self._action_process(mail.package, verbose=self.verbose)
69
+ self.send(mail.sender_id, "node_id", mail.package.instruction.id_)
70
+ else:
71
+ try:
72
+ await self._agent_process(mail.package, verbose=self.verbose)
73
+ self.send(mail.sender_id, "node_id", mail.package.id_)
74
+ except:
75
+ raise ValueError(f"Invalid mail to process. Mail:{mail}")
76
+
77
+ def _process_node_list(self, mail: BaseMail):
78
+ self.send(mail.sender_id, "end", "end")
79
+ self.execute_stop = True
80
+ raise ValueError("Multiple path selection is currently not supported")
81
+
82
+ def _process_condition(self, mail: BaseMail):
83
+ relationship = mail.package
84
+ check_result = relationship.condition(self)
85
+ back_mail = {"relationship_id": mail.package.id_, "check_result": check_result}
86
+ self.send(mail.sender_id, "condition", back_mail)
87
+
88
+ def _system_process(self, system: System, verbose=True, context_verbose=False):
89
+ from lionagi.libs import SysUtil
90
+ SysUtil.check_import('IPython')
91
+ from IPython.display import Markdown, display
92
+ if verbose:
93
+ print(f"------------------Welcome: {system.sender}--------------------")
94
+ display(Markdown(f"system: {convert.to_str(system.system_info)}"))
95
+ if self.context and context_verbose:
96
+ display(Markdown(f"context: {convert.to_str(self.context)}"))
97
+
98
+ self.branch.add_message(system=system)
99
+
100
+ async def _instruction_process(
101
+ self, instruction: Instruction, verbose=True, **kwargs
102
+ ):
103
+ from lionagi.libs import SysUtil
104
+ SysUtil.check_import('IPython')
105
+ from IPython.display import Markdown, display
106
+ if verbose:
107
+ display(
108
+ Markdown(
109
+ f"{instruction.sender}: {convert.to_str(instruction.instruct)}"
110
+ )
111
+ )
112
+
113
+ if self.context:
114
+ instruction.content.update({"context": self.context})
115
+ self.context = None
116
+
117
+ result = await self.branch.chat(instruction, **kwargs)
118
+ with contextlib.suppress(Exception):
119
+ result = ParseUtil.fuzzy_parse_json(result)
120
+ if "response" in result.keys():
121
+ result = result["response"]
122
+ if verbose and len(self.branch.assistant_responses) != 0:
123
+ display(
124
+ Markdown(
125
+ f"{self.branch.last_assistant_response.sender}: {convert.to_str(result)}"
126
+ )
127
+ )
128
+ print("-----------------------------------------------------")
129
+
130
+ self.responses.append(result)
131
+
132
+ async def _action_process(self, action: ActionNode, verbose=True):
133
+ from lionagi.libs import SysUtil
134
+ SysUtil.check_import('IPython')
135
+ from IPython.display import Markdown, display
136
+ try:
137
+ func = getattr(self.branch, action.action)
138
+ except:
139
+ raise ValueError(f"{action.action} is not a valid action")
140
+
141
+ if verbose:
142
+ display(
143
+ Markdown(
144
+ f"{action.instruction.sender}: {convert.to_str(action.instruction.instruct)}"
145
+ )
146
+ )
147
+
148
+ if action.tools:
149
+ self.branch.register_tools(action.tools)
150
+ if self.context:
151
+ result = await func(
152
+ action.instruction.content["instruction"],
153
+ context=self.context,
154
+ tools=action.tools,
155
+ **action.action_kwargs,
156
+ )
157
+ self.context = None
158
+ else:
159
+ result = await func(
160
+ action.instruction.content, tools=action.tools, **action.action_kwargs
161
+ )
162
+
163
+ if verbose and len(self.branch.assistant_responses) != 0:
164
+ display(
165
+ Markdown(
166
+ f"{self.branch.last_assistant_response.sender}: {convert.to_str(result)}"
167
+ )
168
+ )
169
+ print("-----------------------------------------------------")
170
+
171
+ self.responses.append(result)
172
+
173
+ async def _agent_process(self, agent, verbose=True):
174
+ context = self.responses
175
+ if verbose:
176
+ print("*****************************************************")
177
+ result = await agent.execute(context)
178
+
179
+ if verbose:
180
+ print("*****************************************************")
181
+
182
+ self.context = result
183
+ self.responses.append(result)
184
+
185
+ def _process_start(self, mail):
186
+ start_mail_content = mail.package
187
+ self.context = start_mail_content["context"]
188
+ self.send(start_mail_content["structure_id"], "start", "start")
189
+
190
+ def _process_end(self, mail):
191
+ self.execute_stop = True
192
+ self.send(mail.sender_id, "end", "end")
@@ -1,10 +1,8 @@
1
+ import contextlib
1
2
  from datetime import datetime
2
3
  from typing import Any
3
4
 
4
- from lionagi.libs import ln_convert as convert
5
- from lionagi.libs import ln_nested as nested
6
- from lionagi.libs import ln_func_call as func_call
7
- from lionagi.libs import ln_dataframe as dataframe
5
+ from lionagi.libs import convert, nested, func_call, dataframe
8
6
 
9
7
  from lionagi.core.messages.schema import (
10
8
  System,
@@ -14,7 +12,6 @@ from lionagi.core.messages.schema import (
14
12
  BranchColumns,
15
13
  )
16
14
 
17
-
18
15
  CUSTOM_TYPE = dict[str, Any] | str | list[Any] | None
19
16
 
20
17
 
@@ -33,42 +30,41 @@ class MessageUtil:
33
30
  Creates a message object based on the input parameters, ensuring only one message role is present.
34
31
 
35
32
  Args:
36
- system: Information for creating a System message.
37
- instruction: Information for creating an Instruction message.
38
- context: Context information for the message.
39
- response: Response data for creating a message.
40
- **kwargs: Additional keyword arguments for message creation.
33
+ system: Information for creating a System message.
34
+ instruction: Information for creating an Instruction message.
35
+ context: Context information for the message.
36
+ response: Response data for creating a message.
37
+ **kwargs: Additional keyword arguments for message creation.
41
38
 
42
39
  Returns:
43
- A message object of the appropriate type based on provided inputs.
40
+ A message object of the appropriate type based on provided inputs.
44
41
 
45
42
  Raises:
46
- ValueError: If more than one of the role-specific parameters are provided.
43
+ ValueError: If more than one of the role-specific parameters are provided.
47
44
  """
48
45
  if sum(func_call.lcall([system, instruction, response], bool)) != 1:
49
46
  raise ValueError("Error: Message must have one and only one role.")
50
47
 
51
- else:
52
- if isinstance(system, System):
53
- return system
54
- elif isinstance(instruction, Instruction):
55
- return instruction
56
- elif isinstance(response, Response):
57
- return response
58
-
59
- msg = 0
60
- if response:
61
- msg = Response(response=response, **kwargs)
62
- elif instruction:
63
- msg = Instruction(
64
- instruction=instruction,
65
- context=context,
66
- output_fields=output_fields,
67
- **kwargs,
68
- )
69
- elif system:
70
- msg = System(system=system, **kwargs)
71
- return msg
48
+ if isinstance(system, System):
49
+ return system
50
+ elif isinstance(instruction, Instruction):
51
+ return instruction
52
+ elif isinstance(response, Response):
53
+ return response
54
+
55
+ msg = 0
56
+ if response:
57
+ msg = Response(response=response, **kwargs)
58
+ elif instruction:
59
+ msg = Instruction(
60
+ instruction=instruction,
61
+ context=context,
62
+ output_fields=output_fields,
63
+ **kwargs,
64
+ )
65
+ elif system:
66
+ msg = System(system=system, **kwargs)
67
+ return msg
72
68
 
73
69
  @staticmethod
74
70
  def validate_messages(messages: dataframe.ln_DataFrame) -> bool:
@@ -76,21 +72,21 @@ class MessageUtil:
76
72
  Validates the format and content of a DataFrame containing messages.
77
73
 
78
74
  Args:
79
- messages: A DataFrame with message information.
75
+ messages: A DataFrame with message information.
80
76
 
81
77
  Returns:
82
- True if the messages DataFrame is correctly formatted, False otherwise.
78
+ True if the messages DataFrame is correctly formatted, False otherwise.
83
79
 
84
80
  Raises:
85
- ValueError: If the DataFrame does not match expected schema or content requirements.
81
+ ValueError: If the DataFrame does not match expected schema or content requirements.
86
82
  """
87
83
 
88
84
  if list(messages.columns) != BranchColumns.COLUMNS.value:
89
85
  raise ValueError("Invalid messages dataframe. Unmatched columns.")
90
86
  if messages.isnull().values.any():
91
87
  raise ValueError("Invalid messages dataframe. Cannot have null.")
92
- if not all(
93
- role in ["system", "user", "assistant"]
88
+ if any(
89
+ role not in ["system", "user", "assistant"]
94
90
  for role in messages["role"].unique()
95
91
  ):
96
92
  raise ValueError(
@@ -115,14 +111,14 @@ class MessageUtil:
115
111
  Appends a sender prefix to the 'content' field of each message in a DataFrame.
116
112
 
117
113
  Args:
118
- messages: A DataFrame containing message data.
119
- sender: The identifier of the sender to prefix to message contents.
114
+ messages: A DataFrame containing message data.
115
+ sender: The identifier of the sender to prefix to message contents.
120
116
 
121
117
  Returns:
122
- A DataFrame with sender-prefixed message contents.
118
+ A DataFrame with sender-prefixed message contents.
123
119
 
124
120
  Raises:
125
- ValueError: If the sender is None or the value is 'none'.
121
+ ValueError: If the sender is None or the value is 'none'.
126
122
  """
127
123
 
128
124
  if sender is None or convert.strip_lower(sender) == "none":
@@ -152,16 +148,16 @@ class MessageUtil:
152
148
  Filters messages in a DataFrame based on specified criteria.
153
149
 
154
150
  Args:
155
- messages: The DataFrame to filter.
156
- role: The role to filter by.
157
- sender: The sender to filter by.
158
- start_time: The minimum timestamp for messages.
159
- end_time: The maximum timestamp for messages.
160
- content_keywords: Keywords to look for in message content.
161
- case_sensitive: Whether the keyword search should be case-sensitive.
151
+ messages: The DataFrame to filter.
152
+ role: The role to filter by.
153
+ sender: The sender to filter by.
154
+ start_time: The minimum timestamp for messages.
155
+ end_time: The maximum timestamp for messages.
156
+ content_keywords: Keywords to look for in message content.
157
+ case_sensitive: Whether the keyword search should be case-sensitive.
162
158
 
163
159
  Returns:
164
- A filtered DataFrame based on the specified criteria.
160
+ A filtered DataFrame based on the specified criteria.
165
161
  """
166
162
 
167
163
  try:
@@ -180,7 +176,7 @@ class MessageUtil:
180
176
  return convert.to_df(outs)
181
177
 
182
178
  except Exception as e:
183
- raise ValueError(f"Error in filtering messages: {e}")
179
+ raise ValueError(f"Error in filtering messages: {e}") from e
184
180
 
185
181
  @staticmethod
186
182
  def remove_message(messages: dataframe.ln_DataFrame, node_id: str) -> bool:
@@ -188,15 +184,15 @@ class MessageUtil:
188
184
  Removes a message from the DataFrame based on its node ID.
189
185
 
190
186
  Args:
191
- messages: The DataFrame containing messages.
192
- node_id: The unique identifier of the message to be removed.
187
+ messages: The DataFrame containing messages.
188
+ node_id: The unique identifier of the message to be removed.
193
189
 
194
190
  Returns:
195
- If any messages are removed.
191
+ If any messages are removed.
196
192
 
197
193
  Examples:
198
- >>> messages = dataframe.ln_DataFrame([...])
199
- >>> updated_messages = MessageUtil.remove_message(messages, "node_id_123")
194
+ >>> messages = dataframe.ln_DataFrame([...])
195
+ >>> updated_messages = MessageUtil.remove_message(messages, "node_id_123")
200
196
  """
201
197
 
202
198
  initial_length = len(messages)
@@ -218,15 +214,15 @@ class MessageUtil:
218
214
  Retrieves a specified number of message rows based on sender and role.
219
215
 
220
216
  Args:
221
- messages: The DataFrame containing messages.
222
- sender: Filter messages by the sender.
223
- role: Filter messages by the role.
224
- n: The number of messages to retrieve.
225
- sign_: If True, sign the message with the sender.
226
- from_: Specify retrieval from the 'front' or 'last' of the DataFrame.
217
+ messages: The DataFrame containing messages.
218
+ sender: Filter messages by the sender.
219
+ role: Filter messages by the role.
220
+ n: The number of messages to retrieve.
221
+ sign_: If True, sign the message with the sender.
222
+ from_: Specify retrieval from the 'front' or 'last' of the DataFrame.
227
223
 
228
224
  Returns:
229
- A DataFrame containing the filtered messages.
225
+ A DataFrame containing the filtered messages.
230
226
  """
231
227
 
232
228
  outs = ""
@@ -266,17 +262,17 @@ class MessageUtil:
266
262
  Extends a DataFrame with another DataFrame's rows, ensuring no duplicate 'node_id'.
267
263
 
268
264
  Args:
269
- df1: The primary DataFrame.
270
- df2: The DataFrame to merge with the primary DataFrame.
271
- **kwargs: Additional keyword arguments for `drop_duplicates`.
265
+ df1: The primary DataFrame.
266
+ df2: The DataFrame to merge with the primary DataFrame.
267
+ **kwargs: Additional keyword arguments for `drop_duplicates`.
272
268
 
273
269
  Returns:
274
- A DataFrame combined from df1 and df2 with duplicates removed based on 'node_id'.
270
+ A DataFrame combined from df1 and df2 with duplicates removed based on 'node_id'.
275
271
 
276
272
  Examples:
277
- >>> df_main = dataframe.ln_DataFrame([...])
278
- >>> df_additional = dataframe.ln_DataFrame([...])
279
- >>> combined_df = MessageUtil.extend(df_main, df_additional, keep='first')
273
+ >>> df_main = dataframe.ln_DataFrame([...])
274
+ >>> df_additional = dataframe.ln_DataFrame([...])
275
+ >>> combined_df = MessageUtil.extend(df_main, df_additional, keep='first')
280
276
  """
281
277
 
282
278
  MessageUtil.validate_messages(df2)
@@ -288,7 +284,7 @@ class MessageUtil:
288
284
  )
289
285
  return convert.to_df(df)
290
286
  except Exception as e:
291
- raise ValueError(f"Error in extending messages: {e}")
287
+ raise ValueError(f"Error in extending messages: {e}") from e
292
288
 
293
289
  @staticmethod
294
290
  def to_markdown_string(messages: dataframe.ln_DataFrame) -> str:
@@ -296,11 +292,11 @@ class MessageUtil:
296
292
  Converts messages in a DataFrame to a Markdown-formatted string for easy reading.
297
293
 
298
294
  Args:
299
- messages: A DataFrame containing messages with columns for 'role' and 'content'.
295
+ messages: A DataFrame containing messages with columns for 'role' and 'content'.
300
296
 
301
297
  Returns:
302
- A string formatted in Markdown, where each message's content is presented
303
- according to its role in a readable format.
298
+ A string formatted in Markdown, where each message's content is presented
299
+ according to its role in a readable format.
304
300
  """
305
301
 
306
302
  answers = []
@@ -308,101 +304,20 @@ class MessageUtil:
308
304
  content = convert.to_dict(i.content)
309
305
 
310
306
  if i.role == "assistant":
311
- try:
307
+ with contextlib.suppress(Exception):
312
308
  a = nested.nget(content, ["action_response", "func"])
313
309
  b = nested.nget(content, ["action_response", "arguments"])
314
310
  c = nested.nget(content, ["action_response", "output"])
315
311
  if a is not None:
316
- answers.append(f"Function: {a}")
317
- answers.append(f"Arguments: {b}")
318
- answers.append(f"Output: {c}")
312
+ answers.extend(
313
+ (f"Function: {a}", f"Arguments: {b}", f"Output: {c}")
314
+ )
319
315
  else:
320
316
  answers.append(nested.nget(content, ["assistant_response"]))
321
- except:
322
- pass
323
317
  elif i.role == "user":
324
- try:
318
+ with contextlib.suppress(Exception):
325
319
  answers.append(nested.nget(content, ["instruction"]))
326
- except:
327
- pass
328
320
  else:
329
- try:
321
+ with contextlib.suppress(Exception):
330
322
  answers.append(nested.nget(content, ["system_info"]))
331
- except:
332
- pass
333
-
334
- out_ = "\n".join(answers)
335
- return out_
336
-
337
- # @staticmethod
338
- # def to_json_content(value):
339
- # if isinstance(value, dict):
340
- # for key, val in value.items():
341
- # value[key] = MessageUtil.to_json_content(val)
342
- # value = json.dumps(value)
343
- # if isinstance(value, list):
344
- # for i in range(len(value)):
345
- # value[i] = MessageUtil.to_json_content(value[i])
346
- # return value
347
-
348
- # @staticmethod
349
- # def to_dict_content(value):
350
- # try:
351
- # value = json.loads(value)
352
- # if isinstance(value, dict):
353
- # for key, val in value.items():
354
- # value[key] = MessageUtil.to_dict_content(val)
355
- # if isinstance(value, list):
356
- # for i in range(len(value)):
357
- # value[i] = MessageUtil.to_dict_content(value[i])
358
- # return value
359
- # except:
360
- # return value
361
-
362
- # @staticmethod
363
- # def response_to_message(response: dict[str, Any], **kwargs) -> Any:
364
- # """
365
- # Processes a message response dictionary to generate an appropriate message object.
366
-
367
- # Args:
368
- # response: A dictionary potentially containing message information.
369
- # **kwargs: Additional keyword arguments to pass to the message constructors.
370
-
371
- # Returns:
372
- # An instance of a message class, such as ActionRequest or AssistantResponse,
373
- # depending on the content of the response.
374
- # """
375
- # try:
376
- # response = response["message"]
377
- # if .strip_lower(response['content']) == "none":
378
-
379
- # content = ActionRequest._handle_action_request(response)
380
- # return ActionRequest(action_request=content, **kwargs)
381
-
382
- # else:
383
-
384
- # try:
385
- # if 'tool_uses' in to_dict(response[MessageField.CONTENT.value]):
386
- # content_ = to_dict(response[MessageField.CONTENT.value])[
387
- # 'tool_uses']
388
- # return ActionRequest(action_request=content_, **kwargs)
389
-
390
- # elif MessageContentKey.RESPONSE.value in to_dict(
391
- # response[MessageField.CONTENT.value]):
392
- # content_ = to_dict(response[MessageField.CONTENT.value])[
393
- # MessageContentKey.RESPONSE.value]
394
- # return AssistantResponse(assistant_response=content_, **kwargs)
395
-
396
- # elif MessageContentKey.ACTION_REQUEST.value in to_dict(
397
- # response[MessageField.CONTENT.value]):
398
- # content_ = to_dict(response[MessageField.CONTENT.value])[
399
- # MessageContentKey.ACTION_REQUEST.value]
400
- # return ActionRequest(action_request=content_, **kwargs)
401
-
402
- # else:
403
- # return AssistantResponse(assistant_response=response, **kwargs)
404
-
405
- # except:
406
- # return AssistantResponse(assistant_response=response, **kwargs)
407
- # except:
408
- # return ActionResponse(action_response=response, **kwargs)
323
+ return "\n".join(answers)
@@ -0,0 +1,13 @@
1
+ from .predict import predict
2
+ from .select import select
3
+ from .score import score
4
+ from .sentiment import sentiment
5
+ from .react import react
6
+
7
+ __all__ = [
8
+ "predict",
9
+ "select",
10
+ "score",
11
+ "sentiment",
12
+ "react",
13
+ ]