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
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