lionagi 0.0.305__py3-none-any.whl → 0.0.307__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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
+ ]