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
lionagi/__init__.py CHANGED
@@ -6,11 +6,8 @@ import logging
6
6
  from .version import __version__
7
7
  from dotenv import load_dotenv
8
8
 
9
-
10
- from .libs import *
11
- from .core import *
12
- from .integrations import *
13
-
9
+ from .core import direct, Branch, Session, Structure, Tool, BaseAgent
10
+ from .integrations.provider.services import Services
14
11
 
15
12
  logger = logging.getLogger(__name__)
16
13
  logger.setLevel(logging.INFO)
lionagi/core/__init__.py CHANGED
@@ -1,5 +1,8 @@
1
- from .tool import func_to_tool
2
- from .session import Branch, Session
3
-
1
+ from . import *
4
2
 
5
- __all__ = ["Session", "Branch", "func_to_tool"]
3
+ from .branch import Branch, ExecutableBranch
4
+ from .session import Session
5
+ from .schema import Tool, Structure, ActionNode, Relationship
6
+ from .agent import BaseAgent
7
+ from .messages import Instruction, System, Response
8
+ from .tool import func_to_tool
@@ -0,0 +1,3 @@
1
+ from .base_agent import BaseAgent
2
+
3
+ __all__ = ["BaseAgent"]
@@ -0,0 +1,46 @@
1
+ from lionagi.core.mail.schema import StartMail
2
+ from lionagi.core.schema.base_node import BaseRelatableNode
3
+ from lionagi.core.mail.mail_manager import MailManager
4
+
5
+ from lionagi.libs import func_call, AsyncUtil
6
+
7
+
8
+ class BaseAgent(BaseRelatableNode):
9
+ def __init__(self, structure, executable_obj, output_parser=None) -> None:
10
+
11
+ super().__init__()
12
+ self.structure = structure
13
+ self.executable = executable_obj
14
+ self.start = StartMail()
15
+ self.mailManager = MailManager([self.structure, self.executable, self.start])
16
+ self.output_parser = output_parser
17
+ self.start_context = None
18
+
19
+ async def mail_manager_control(self, refresh_time=1):
20
+ while not self.structure.execute_stop or not self.executable.execute_stop:
21
+ await AsyncUtil.sleep(refresh_time)
22
+ self.mailManager.execute_stop = True
23
+
24
+ async def execute(self, context=None):
25
+ self.start_context = context
26
+ self.start.trigger(
27
+ context=context,
28
+ structure_id=self.structure.id_,
29
+ executable_id=self.executable.id_,
30
+ )
31
+ await func_call.mcall(
32
+ [0.1, 0.1, 0.1, 0.1],
33
+ [
34
+ self.structure.execute,
35
+ self.executable.execute,
36
+ self.mailManager.execute,
37
+ self.mail_manager_control,
38
+ ],
39
+ )
40
+
41
+ self.structure.execute_stop = False
42
+ self.executable.execute_stop = False
43
+ self.mailManager.execute_stop = False
44
+
45
+ if self.output_parser:
46
+ return self.output_parser(self)
@@ -0,0 +1,4 @@
1
+ from .branch import Branch
2
+ from .executable_branch import ExecutableBranch
3
+
4
+ __all__ = ["Branch", "ExecutableBranch"]
File without changes
@@ -1,21 +1,19 @@
1
1
  from abc import ABC
2
2
  from typing import Any
3
3
 
4
- from lionagi.libs.sys_util import SysUtil, PATH_TYPE
4
+ from lionagi.libs.sys_util import PATH_TYPE
5
+ from lionagi.libs import convert, dataframe, SysUtil
5
6
 
6
- import lionagi.libs.ln_convert as convert
7
- import lionagi.libs.ln_dataframe as dataframe
8
-
9
- from lionagi.core.schema.base_node import BaseRelatableNode
10
- from lionagi.core.schema.data_logger import DataLogger, DLog
11
- from lionagi.core.messages.schema import (
7
+ from ..schema.base_node import BaseRelatableNode
8
+ from ..schema.data_logger import DataLogger, DLog
9
+ from ..messages.schema import (
12
10
  BranchColumns,
13
11
  System,
12
+ Response,
14
13
  Instruction,
15
14
  BaseMessage,
16
15
  )
17
- from lionagi.core.branch.util import MessageUtil
18
- from lionagi.libs.ln_parse import ParseUtil
16
+ from .util import MessageUtil
19
17
 
20
18
 
21
19
  class BaseBranch(BaseRelatableNode, ABC):
@@ -24,9 +22,9 @@ class BaseBranch(BaseRelatableNode, ABC):
24
22
  and logging functionality.
25
23
 
26
24
  Attributes:
27
- messages (dataframe.ln_DataFrame): Holds the messages in the branch.
28
- datalogger (DataLogger): Logs data related to the branch's operation.
29
- persist_path (PATH_TYPE): Filesystem path for data persistence.
25
+ messages (dataframe.ln_DataFrame): Holds the messages in the branch.
26
+ datalogger (DataLogger): Logs data related to the branch's operation.
27
+ persist_path (PATH_TYPE): Filesystem path for data persistence.
30
28
  """
31
29
 
32
30
  _columns: list[str] = BranchColumns.COLUMNS.value
@@ -36,6 +34,7 @@ class BaseBranch(BaseRelatableNode, ABC):
36
34
  messages: dataframe.ln_DataFrame | None = None,
37
35
  datalogger: DataLogger | None = None,
38
36
  persist_path: PATH_TYPE | None = None,
37
+ name=None,
39
38
  **kwargs,
40
39
  ) -> None:
41
40
  super().__init__(**kwargs)
@@ -47,9 +46,8 @@ class BaseBranch(BaseRelatableNode, ABC):
47
46
  else:
48
47
  self.messages = dataframe.ln_DataFrame(columns=self._columns)
49
48
 
50
- self.datalogger = (
51
- datalogger if datalogger else DataLogger(persist_path=persist_path)
52
- )
49
+ self.datalogger = datalogger or DataLogger(persist_path=persist_path)
50
+ self.name = name
53
51
 
54
52
  def add_message(
55
53
  self,
@@ -58,17 +56,18 @@ class BaseBranch(BaseRelatableNode, ABC):
58
56
  context: str | dict[str, Any] | None = None,
59
57
  response: dict | list | BaseMessage | None = None,
60
58
  output_fields=None,
59
+ recipient=None,
61
60
  **kwargs,
62
61
  ) -> None:
63
62
  """
64
63
  Adds a message to the branch.
65
64
 
66
65
  Args:
67
- system: Information for creating a System message.
68
- instruction: Information for creating an Instruction message.
69
- context: Context information for the message.
70
- response: Response data for creating a message.
71
- **kwargs: Additional keyword arguments for message creation.
66
+ system: Information for creating a System message.
67
+ instruction: Information for creating an Instruction message.
68
+ context: Context information for the message.
69
+ response: Response data for creating a message.
70
+ **kwargs: Additional keyword arguments for message creation.
72
71
  """
73
72
  _msg = MessageUtil.create_message(
74
73
  system=system,
@@ -76,9 +75,28 @@ class BaseBranch(BaseRelatableNode, ABC):
76
75
  context=context,
77
76
  response=response,
78
77
  output_fields=output_fields,
78
+ recipient=recipient,
79
79
  **kwargs,
80
80
  )
81
81
 
82
+ if isinstance(_msg, System):
83
+ self.system_node = _msg
84
+
85
+ # sourcery skip: merge-nested-ifs
86
+ if isinstance(_msg, Instruction):
87
+ if recipient is None and self.name is not None:
88
+ _msg.recipient = self.name
89
+
90
+ if isinstance(_msg, Response):
91
+ if "action_response" in _msg.content.keys():
92
+ if recipient is None and self.name is not None:
93
+ _msg.recipient = self.name
94
+ if recipient is not None and self.name is None:
95
+ _msg.recipient = recipient
96
+ if "response" in _msg.content.keys():
97
+ if self.name is not None:
98
+ _msg.sender = self.name
99
+
82
100
  _msg.content = _msg.msg_content
83
101
  self.messages.loc[len(self.messages)] = _msg.to_pd_series()
84
102
 
@@ -90,11 +108,11 @@ class BaseBranch(BaseRelatableNode, ABC):
90
108
  optionally including sender information.
91
109
 
92
110
  Args:
93
- with_sender: Flag to include sender information in the output.
111
+ with_sender: Flag to include sender information in the output.
94
112
 
95
113
  Returns:
96
- A list of message dictionaries, each with 'role' and 'content' keys,
97
- and optionally prefixed by 'Sender' if with_sender is True.
114
+ A list of message dictionaries, each with 'role' and 'content' keys,
115
+ and optionally prefixed by 'Sender' if with_sender is True.
98
116
  """
99
117
 
100
118
  message = []
@@ -125,7 +143,7 @@ class BaseBranch(BaseRelatableNode, ABC):
125
143
  Retrieves all chat messages without sender information.
126
144
 
127
145
  Returns:
128
- A list of dictionaries representing chat messages.
146
+ A list of dictionaries representing chat messages.
129
147
  """
130
148
 
131
149
  return self._to_chatcompletion_message()
@@ -136,7 +154,7 @@ class BaseBranch(BaseRelatableNode, ABC):
136
154
  Retrieves all chat messages, including sender information.
137
155
 
138
156
  Returns:
139
- A list of dictionaries representing chat messages, each prefixed with its sender.
157
+ A list of dictionaries representing chat messages, each prefixed with its sender.
140
158
  """
141
159
 
142
160
  return self._to_chatcompletion_message(with_sender=True)
@@ -147,7 +165,7 @@ class BaseBranch(BaseRelatableNode, ABC):
147
165
  Retrieves the last message from the branch as a pandas Series.
148
166
 
149
167
  Returns:
150
- A pandas Series representing the last message in the branch.
168
+ A pandas Series representing the last message in the branch.
151
169
  """
152
170
 
153
171
  return MessageUtil.get_message_rows(self.messages, n=1, from_="last")
@@ -158,7 +176,7 @@ class BaseBranch(BaseRelatableNode, ABC):
158
176
  Extracts the content of the last message in the branch.
159
177
 
160
178
  Returns:
161
- A dictionary representing the content of the last message.
179
+ A dictionary representing the content of the last message.
162
180
  """
163
181
 
164
182
  return convert.to_dict(self.messages.content.iloc[-1])
@@ -169,7 +187,7 @@ class BaseBranch(BaseRelatableNode, ABC):
169
187
  Retrieves the first message marked with the 'system' role.
170
188
 
171
189
  Returns:
172
- A pandas Series representing the first 'system' message in the branch.
190
+ A pandas Series representing the first 'system' message in the branch.
173
191
  """
174
192
 
175
193
  return MessageUtil.get_message_rows(
@@ -182,7 +200,7 @@ class BaseBranch(BaseRelatableNode, ABC):
182
200
  Retrieves the last message marked with the 'assistant' role.
183
201
 
184
202
  Returns:
185
- A pandas Series representing the last 'assistant' (response) message in the branch.
203
+ A pandas Series representing the last 'assistant' (response) message in the branch.
186
204
  """
187
205
 
188
206
  return MessageUtil.get_message_rows(
@@ -195,7 +213,7 @@ class BaseBranch(BaseRelatableNode, ABC):
195
213
  Extracts the content of the last 'assistant' (response) message.
196
214
 
197
215
  Returns:
198
- A dictionary representing the content of the last 'assistant' message.
216
+ A dictionary representing the content of the last 'assistant' message.
199
217
  """
200
218
 
201
219
  return convert.to_dict(self.last_response.content.iloc[-1])
@@ -206,7 +224,7 @@ class BaseBranch(BaseRelatableNode, ABC):
206
224
  Filters and retrieves all messages sent by 'action_request'.
207
225
 
208
226
  Returns:
209
- A pandas DataFrame containing all 'action_request' messages.
227
+ A pandas DataFrame containing all 'action_request' messages.
210
228
  """
211
229
 
212
230
  return convert.to_df(self.messages[self.messages.sender == "action_request"])
@@ -217,7 +235,7 @@ class BaseBranch(BaseRelatableNode, ABC):
217
235
  Filters and retrieves all messages sent by 'action_response'.
218
236
 
219
237
  Returns:
220
- A pandas DataFrame containing all 'action_response' messages.
238
+ A pandas DataFrame containing all 'action_response' messages.
221
239
  """
222
240
 
223
241
  return convert.to_df(self.messages[self.messages.sender == "action_response"])
@@ -228,7 +246,7 @@ class BaseBranch(BaseRelatableNode, ABC):
228
246
  Retrieves all messages marked with the 'assistant' role.
229
247
 
230
248
  Returns:
231
- A pandas DataFrame containing all messages with an 'assistant' role.
249
+ A pandas DataFrame containing all messages with an 'assistant' role.
232
250
  """
233
251
 
234
252
  return convert.to_df(self.messages[self.messages.role == "assistant"])
@@ -239,20 +257,24 @@ class BaseBranch(BaseRelatableNode, ABC):
239
257
  Filters 'assistant' role messages excluding 'action_request' and 'action_response'.
240
258
 
241
259
  Returns:
242
- A pandas DataFrame of 'assistant' messages excluding action requests/responses.
260
+ A pandas DataFrame of 'assistant' messages excluding action requests/responses.
243
261
  """
244
262
 
245
263
  a_responses = self.responses[self.responses.sender != "action_response"]
246
264
  a_responses = a_responses[a_responses.sender != "action_request"]
247
265
  return convert.to_df(a_responses)
248
266
 
267
+ @property
268
+ def last_assistant_response(self):
269
+ return self.assistant_responses.iloc[-1]
270
+
249
271
  @property
250
272
  def info(self) -> dict[str, Any]:
251
273
  """
252
274
  Summarizes branch information, including message counts by role.
253
275
 
254
276
  Returns:
255
- A dictionary containing counts of messages categorized by their role.
277
+ A dictionary containing counts of messages categorized by their role.
256
278
  """
257
279
 
258
280
  return self._info()
@@ -263,7 +285,7 @@ class BaseBranch(BaseRelatableNode, ABC):
263
285
  Provides a summary of message counts categorized by sender.
264
286
 
265
287
  Returns:
266
- A dictionary with senders as keys and counts of their messages as values.
288
+ A dictionary with senders as keys and counts of their messages as values.
267
289
  """
268
290
 
269
291
  return self._info(use_sender=True)
@@ -274,8 +296,8 @@ class BaseBranch(BaseRelatableNode, ABC):
274
296
  Provides a detailed description of the branch, including a summary of messages.
275
297
 
276
298
  Returns:
277
- A dictionary with a summary of total messages, a breakdown by role, and
278
- a preview of the first five messages.
299
+ A dictionary with a summary of total messages, a breakdown by role, and
300
+ a preview of the first five messages.
279
301
  """
280
302
 
281
303
  return {
@@ -322,13 +344,13 @@ class BaseBranch(BaseRelatableNode, ABC):
322
344
  Exports the branch messages to a CSV file.
323
345
 
324
346
  Args:
325
- filepath: Destination path for the CSV file. Defaults to 'messages.csv'.
326
- dir_exist_ok: If False, an error is raised if the directory exists. Defaults to True.
327
- timestamp: If True, appends a timestamp to the filename. Defaults to True.
328
- time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
329
- verbose: If True, prints a message upon successful export. Defaults to True.
330
- clear: If True, clears the messages after exporting. Defaults to True.
331
- **kwargs: Additional keyword arguments for pandas.DataFrame.to_csv().
347
+ filepath: Destination path for the CSV file. Defaults to 'messages.csv'.
348
+ dir_exist_ok: If False, an error is raised if the directory exists. Defaults to True.
349
+ timestamp: If True, appends a timestamp to the filename. Defaults to True.
350
+ time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
351
+ verbose: If True, prints a message upon successful export. Defaults to True.
352
+ clear: If True, clears the messages after exporting. Defaults to True.
353
+ **kwargs: Additional keyword arguments for pandas.DataFrame.to_csv().
332
354
  """
333
355
 
334
356
  if not filename.endswith(".csv"):
@@ -349,7 +371,7 @@ class BaseBranch(BaseRelatableNode, ABC):
349
371
  if clear:
350
372
  self.clear_messages()
351
373
  except Exception as e:
352
- raise ValueError(f"Error in saving to csv: {e}")
374
+ raise ValueError(f"Error in saving to csv: {e}") from e
353
375
 
354
376
  def to_json_file(
355
377
  self,
@@ -365,13 +387,13 @@ class BaseBranch(BaseRelatableNode, ABC):
365
387
  Exports the branch messages to a JSON file.
366
388
 
367
389
  Args:
368
- filename: Destination path for the JSON file. Defaults to 'messages.json'.
369
- dir_exist_ok: If False, an error is raised if the dirctory exists. Defaults to True.
370
- timestamp: If True, appends a timestamp to the filename. Defaults to True.
371
- time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
372
- verbose: If True, prints a message upon successful export. Defaults to True.
373
- clear: If True, clears the messages after exporting. Defaults to True.
374
- **kwargs: Additional keyword arguments for pandas.DataFrame.to_json().
390
+ filename: Destination path for the JSON file. Defaults to 'messages.json'.
391
+ dir_exist_ok: If False, an error is raised if the dirctory exists. Defaults to True.
392
+ timestamp: If True, appends a timestamp to the filename. Defaults to True.
393
+ time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
394
+ verbose: If True, prints a message upon successful export. Defaults to True.
395
+ clear: If True, clears the messages after exporting. Defaults to True.
396
+ **kwargs: Additional keyword arguments for pandas.DataFrame.to_json().
375
397
  """
376
398
 
377
399
  if not filename.endswith(".json"):
@@ -394,7 +416,7 @@ class BaseBranch(BaseRelatableNode, ABC):
394
416
  if clear:
395
417
  self.clear_messages()
396
418
  except Exception as e:
397
- raise ValueError(f"Error in saving to json: {e}")
419
+ raise ValueError(f"Error in saving to json: {e}") from e
398
420
 
399
421
  def log_to_csv(
400
422
  self,
@@ -412,13 +434,13 @@ class BaseBranch(BaseRelatableNode, ABC):
412
434
  Exports the data logger contents to a CSV file.
413
435
 
414
436
  Args:
415
- filename: Destination path for the CSV file. Defaults to 'log.csv'.
416
- dir_exist_ok: If False, an error is raised if the directory exists. Defaults to True.
417
- timestamp: If True, appends a timestamp to the filename. Defaults to True.
418
- time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
419
- verbose: If True, prints a message upon successful export. Defaults to True.
420
- clear: If True, clears the logger after exporting. Defaults to True.
421
- **kwargs: Additional keyword arguments for pandas.DataFrame.to_csv().
437
+ filename: Destination path for the CSV file. Defaults to 'log.csv'.
438
+ dir_exist_ok: If False, an error is raised if the directory exists. Defaults to True.
439
+ timestamp: If True, appends a timestamp to the filename. Defaults to True.
440
+ time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
441
+ verbose: If True, prints a message upon successful export. Defaults to True.
442
+ clear: If True, clears the logger after exporting. Defaults to True.
443
+ **kwargs: Additional keyword arguments for pandas.DataFrame.to_csv().
422
444
  """
423
445
  self.datalogger.to_csv_file(
424
446
  filename=filename,
@@ -448,13 +470,13 @@ class BaseBranch(BaseRelatableNode, ABC):
448
470
  Exports the data logger contents to a JSON file.
449
471
 
450
472
  Args:
451
- filename: Destination path for the JSON file. Defaults to 'log.json'.
452
- dir_exist_ok: If False, an error is raised if the directory exists. Defaults to True.
453
- timestamp: If True, appends a timestamp to the filename. Defaults to True.
454
- time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
455
- verbose: If True, prints a message upon successful export. Defaults to True.
456
- clear: If True, clears the logger after exporting. Defaults to True.
457
- **kwargs: Additional keyword arguments for pandas.DataFrame.to_json().
473
+ filename: Destination path for the JSON file. Defaults to 'log.json'.
474
+ dir_exist_ok: If False, an error is raised if the directory exists. Defaults to True.
475
+ timestamp: If True, appends a timestamp to the filename. Defaults to True.
476
+ time_prefix: If True, prefixes the filename with a timestamp. Defaults to False.
477
+ verbose: If True, prints a message upon successful export. Defaults to True.
478
+ clear: If True, clears the logger after exporting. Defaults to True.
479
+ **kwargs: Additional keyword arguments for pandas.DataFrame.to_json().
458
480
  """
459
481
 
460
482
  self.datalogger.to_json_file(
@@ -491,14 +513,14 @@ class BaseBranch(BaseRelatableNode, ABC):
491
513
  if verbose:
492
514
  print(f"Loaded {len(df)} logs from {filename}")
493
515
  except Exception as e:
494
- raise ValueError(f"Error in loading log: {e}")
516
+ raise ValueError(f"Error in loading log: {e}") from e
495
517
 
496
518
  def remove_message(self, node_id: str) -> None:
497
519
  """
498
520
  Removes a message from the branch based on its node ID.
499
521
 
500
522
  Args:
501
- node_id: The unique identifier of the message to be removed.
523
+ node_id: The unique identifier of the message to be removed.
502
524
  """
503
525
  MessageUtil.remove_message(self.messages, node_id)
504
526
 
@@ -507,9 +529,9 @@ class BaseBranch(BaseRelatableNode, ABC):
507
529
  Updates a specific column of a message identified by node_id with a new value.
508
530
 
509
531
  Args:
510
- value: The new value to update the message with.
511
- node_id: The unique identifier of the message to update.
512
- column: The column of the message to update.
532
+ value: The new value to update the message with.
533
+ node_id: The unique identifier of the message to update.
534
+ column: The column of the message to update.
513
535
  """
514
536
 
515
537
  index = self.messages[self.messages["node_id"] == node_id].index[0]
@@ -525,8 +547,8 @@ class BaseBranch(BaseRelatableNode, ABC):
525
547
  Updates the first system message with new content and/or sender.
526
548
 
527
549
  Args:
528
- system: The new system message content or a System object.
529
- sender: The identifier of the sender for the system message.
550
+ system: The new system message content or a System object.
551
+ sender: The identifier of the sender for the system message.
530
552
  """
531
553
 
532
554
  if len(self.messages[self.messages["role"] == "system"]) == 0:
@@ -548,7 +570,7 @@ class BaseBranch(BaseRelatableNode, ABC):
548
570
  Removes the last 'n' messages from the branch.
549
571
 
550
572
  Args:
551
- steps: The number of messages to remove from the end.
573
+ steps: The number of messages to remove from the end.
552
574
  """
553
575
 
554
576
  self.messages = dataframe.remove_last_n_rows(self.messages, steps)
@@ -620,10 +642,10 @@ class BaseBranch(BaseRelatableNode, ABC):
620
642
  Helper method to generate summaries of messages either by role or sender.
621
643
 
622
644
  Args:
623
- use_sender: If True, summary is categorized by sender. Otherwise, by role.
645
+ use_sender: If True, summary is categorized by sender. Otherwise, by role.
624
646
 
625
647
  Returns:
626
- A dictionary summarizing the count of messages either by role or sender.
648
+ A dictionary summarizing the count of messages either by role or sender.
627
649
  """
628
650
 
629
651
  messages = self.messages["sender"] if use_sender else self.messages["role"]
@@ -2,27 +2,22 @@ from collections import deque
2
2
  from typing import Any, Union, TypeVar, Callable
3
3
 
4
4
  from lionagi.libs.sys_util import PATH_TYPE
5
- from lionagi.libs.ln_api import StatusTracker, BaseService
6
- from lionagi.libs import ln_convert as convert
7
- from lionagi.libs import ln_dataframe as dataframe
5
+ from lionagi.libs import StatusTracker, BaseService, convert, dataframe
8
6
 
9
- from lionagi.core.schema.base_node import TOOL_TYPE, Tool
10
- from lionagi.core.schema.data_logger import DataLogger
11
- from lionagi.core.tool.tool_manager import ToolManager, func_to_tool
7
+ from ..schema import TOOL_TYPE, Tool, DataLogger
8
+ from ..tool import ToolManager, func_to_tool
12
9
 
13
- from lionagi.core.branch.base_branch import BaseBranch
14
- from lionagi.core.messages.schema import System
15
- from lionagi.core.mail.schema import BaseMail
16
-
17
- from lionagi.core.branch.util import MessageUtil
10
+ from ..messages import System
11
+ from ..mail import BaseMail
18
12
 
13
+ from .util import MessageUtil
14
+ from .base_branch import BaseBranch
19
15
  from .branch_flow_mixin import BranchFlowMixin
20
16
 
21
17
  from dotenv import load_dotenv
22
18
 
23
19
  load_dotenv()
24
20
 
25
-
26
21
  T = TypeVar("T", bound=Tool)
27
22
 
28
23
 
@@ -30,7 +25,7 @@ class Branch(BaseBranch, BranchFlowMixin):
30
25
 
31
26
  def __init__(
32
27
  self,
33
- branch_name: str | None = None,
28
+ name: str | None = None,
34
29
  system: dict | list | System | None = None,
35
30
  messages: dataframe.ln_DataFrame | None = None,
36
31
  service: BaseService | None = None,
@@ -38,8 +33,7 @@ class Branch(BaseBranch, BranchFlowMixin):
38
33
  llmconfig: dict[str, str | int | dict] | None = None,
39
34
  tools: list[Callable | Tool] | None = None,
40
35
  datalogger: None | DataLogger = None,
41
- persist_path: PATH_TYPE | None = None,
42
- # instruction_sets=None,
36
+ persist_path: PATH_TYPE | None = None, # instruction_sets=None,
43
37
  tool_manager: ToolManager | None = None,
44
38
  **kwargs,
45
39
  ):
@@ -49,15 +43,15 @@ class Branch(BaseBranch, BranchFlowMixin):
49
43
  messages=messages,
50
44
  datalogger=datalogger,
51
45
  persist_path=persist_path,
46
+ name=name,
52
47
  **kwargs,
53
48
  )
54
49
 
55
50
  # add branch name
56
- self.branch_name = branch_name
57
51
  self.sender = sender or "system"
58
52
 
59
53
  # add tool manager and register tools
60
- self.tool_manager = tool_manager if tool_manager else ToolManager()
54
+ self.tool_manager = tool_manager or ToolManager()
61
55
  if tools:
62
56
  try:
63
57
  tools_ = []
@@ -70,7 +64,7 @@ class Branch(BaseBranch, BranchFlowMixin):
70
64
 
71
65
  self.register_tools(tools_)
72
66
  except Exception as e:
73
- raise TypeError(f"Error in registering tools: {e}")
67
+ raise TypeError(f"Error in registering tools: {e}") from e
74
68
 
75
69
  # add service and llmconfig
76
70
  self.service, self.llmconfig = self._add_service(service, llmconfig)
@@ -91,22 +85,21 @@ class Branch(BaseBranch, BranchFlowMixin):
91
85
  def from_csv(
92
86
  cls,
93
87
  filepath,
94
- branch_name: str | None = None,
88
+ name: str | None = None,
95
89
  service: BaseService | None = None,
96
90
  llmconfig: dict[str, str | int | dict] | None = None,
97
91
  tools: TOOL_TYPE | None = None,
98
92
  datalogger: None | DataLogger = None,
99
- persist_path: PATH_TYPE | None = None,
100
- # instruction_sets=None,
93
+ persist_path: PATH_TYPE | None = None, # instruction_sets=None,
101
94
  tool_manager: ToolManager | None = None,
102
95
  read_kwargs=None,
103
96
  **kwargs,
104
97
  ):
105
98
 
106
- self = cls._from_csv(
99
+ return cls._from_csv(
107
100
  filepath=filepath,
108
101
  read_kwargs=read_kwargs,
109
- branch_name=branch_name,
102
+ name=name,
110
103
  service=service,
111
104
  llmconfig=llmconfig,
112
105
  tools=tools,
@@ -117,28 +110,25 @@ class Branch(BaseBranch, BranchFlowMixin):
117
110
  **kwargs,
118
111
  )
119
112
 
120
- return self
121
-
122
113
  @classmethod
123
114
  def from_json_string(
124
115
  cls,
125
116
  filepath,
126
- branch_name: str | None = None,
117
+ name: str | None = None,
127
118
  service: BaseService | None = None,
128
119
  llmconfig: dict[str, str | int | dict] | None = None,
129
120
  tools: TOOL_TYPE | None = None,
130
121
  datalogger: None | DataLogger = None,
131
- persist_path: PATH_TYPE | None = None,
132
- # instruction_sets=None,
122
+ persist_path: PATH_TYPE | None = None, # instruction_sets=None,
133
123
  tool_manager: ToolManager | None = None,
134
124
  read_kwargs=None,
135
125
  **kwargs,
136
126
  ):
137
127
 
138
- self = cls._from_json(
128
+ return cls._from_json(
139
129
  filepath=filepath,
140
130
  read_kwargs=read_kwargs,
141
- branch_name=branch_name,
131
+ name=name,
142
132
  service=service,
143
133
  llmconfig=llmconfig,
144
134
  tools=tools,
@@ -149,8 +139,6 @@ class Branch(BaseBranch, BranchFlowMixin):
149
139
  **kwargs,
150
140
  )
151
141
 
152
- return self
153
-
154
142
  def messages_describe(self) -> dict[str, Any]:
155
143
 
156
144
  return dict(
@@ -301,7 +289,7 @@ class Branch(BaseBranch, BranchFlowMixin):
301
289
  Check if the conversation has been invoked with an action response.
302
290
 
303
291
  Returns:
304
- bool: True if the conversation has been invoked, False otherwise.
292
+ bool: True if the conversation has been invoked, False otherwise.
305
293
 
306
294
  """
307
295
  content = self.messages.iloc[-1]["content"]
@@ -312,5 +300,5 @@ class Branch(BaseBranch, BranchFlowMixin):
312
300
  "output",
313
301
  }:
314
302
  return True
315
- except:
303
+ except Exception:
316
304
  return False