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.
- lionagi/__init__.py +2 -5
- lionagi/core/__init__.py +7 -4
- lionagi/core/agent/__init__.py +3 -0
- lionagi/core/agent/base_agent.py +46 -0
- lionagi/core/branch/__init__.py +4 -0
- lionagi/core/branch/base/__init__.py +0 -0
- lionagi/core/branch/base_branch.py +100 -78
- lionagi/core/branch/branch.py +22 -34
- lionagi/core/branch/branch_flow_mixin.py +3 -7
- lionagi/core/branch/executable_branch.py +192 -0
- lionagi/core/branch/util.py +77 -162
- lionagi/core/direct/__init__.py +13 -0
- lionagi/core/direct/parallel_predict.py +127 -0
- lionagi/core/direct/parallel_react.py +0 -0
- lionagi/core/direct/parallel_score.py +0 -0
- lionagi/core/direct/parallel_select.py +0 -0
- lionagi/core/direct/parallel_sentiment.py +0 -0
- lionagi/core/direct/predict.py +174 -0
- lionagi/core/direct/react.py +33 -0
- lionagi/core/direct/score.py +163 -0
- lionagi/core/direct/select.py +144 -0
- lionagi/core/direct/sentiment.py +51 -0
- lionagi/core/direct/utils.py +83 -0
- lionagi/core/flow/__init__.py +0 -3
- lionagi/core/flow/monoflow/{mono_react.py → ReAct.py} +52 -9
- lionagi/core/flow/monoflow/__init__.py +9 -0
- lionagi/core/flow/monoflow/{mono_chat.py → chat.py} +11 -11
- lionagi/core/flow/monoflow/{mono_chat_mixin.py → chat_mixin.py} +33 -27
- lionagi/core/flow/monoflow/{mono_followup.py → followup.py} +7 -6
- lionagi/core/flow/polyflow/__init__.py +1 -0
- lionagi/core/flow/polyflow/{polychat.py → chat.py} +15 -3
- lionagi/core/mail/__init__.py +8 -0
- lionagi/core/mail/mail_manager.py +88 -40
- lionagi/core/mail/schema.py +32 -6
- lionagi/core/messages/__init__.py +3 -0
- lionagi/core/messages/schema.py +56 -25
- lionagi/core/prompt/__init__.py +0 -0
- lionagi/core/prompt/prompt_template.py +0 -0
- lionagi/core/schema/__init__.py +7 -5
- lionagi/core/schema/action_node.py +29 -0
- lionagi/core/schema/base_mixin.py +56 -59
- lionagi/core/schema/base_node.py +35 -38
- lionagi/core/schema/condition.py +24 -0
- lionagi/core/schema/data_logger.py +98 -98
- lionagi/core/schema/data_node.py +19 -19
- lionagi/core/schema/prompt_template.py +0 -0
- lionagi/core/schema/structure.py +293 -190
- lionagi/core/session/__init__.py +1 -3
- lionagi/core/session/session.py +196 -214
- lionagi/core/tool/tool_manager.py +95 -103
- lionagi/integrations/__init__.py +1 -3
- lionagi/integrations/bridge/langchain_/documents.py +17 -18
- lionagi/integrations/bridge/langchain_/langchain_bridge.py +14 -14
- lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +22 -22
- lionagi/integrations/bridge/llamaindex_/node_parser.py +12 -12
- lionagi/integrations/bridge/llamaindex_/reader.py +11 -11
- lionagi/integrations/bridge/llamaindex_/textnode.py +7 -7
- lionagi/integrations/config/openrouter_configs.py +0 -1
- lionagi/integrations/provider/oai.py +26 -26
- lionagi/integrations/provider/services.py +38 -38
- lionagi/libs/__init__.py +34 -1
- lionagi/libs/ln_api.py +211 -221
- lionagi/libs/ln_async.py +53 -60
- lionagi/libs/ln_convert.py +118 -120
- lionagi/libs/ln_dataframe.py +32 -33
- lionagi/libs/ln_func_call.py +334 -342
- lionagi/libs/ln_nested.py +99 -107
- lionagi/libs/ln_parse.py +175 -158
- lionagi/libs/sys_util.py +52 -52
- lionagi/tests/test_core/test_base_branch.py +427 -427
- lionagi/tests/test_core/test_branch.py +292 -292
- lionagi/tests/test_core/test_mail_manager.py +57 -57
- lionagi/tests/test_core/test_session.py +254 -266
- lionagi/tests/test_core/test_session_base_util.py +299 -300
- lionagi/tests/test_core/test_tool_manager.py +70 -74
- lionagi/tests/test_libs/test_nested.py +2 -7
- lionagi/tests/test_libs/test_parse.py +2 -2
- lionagi/version.py +1 -1
- {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/METADATA +4 -2
- lionagi-0.0.307.dist-info/RECORD +115 -0
- lionagi-0.0.305.dist-info/RECORD +0 -94
- {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/LICENSE +0 -0
- {lionagi-0.0.305.dist-info → lionagi-0.0.307.dist-info}/WHEEL +0 -0
- {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 .
|
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 .
|
2
|
-
from .session import Branch, Session
|
3
|
-
|
1
|
+
from . import *
|
4
2
|
|
5
|
-
|
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,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)
|
lionagi/core/branch/__init__.py
CHANGED
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
|
4
|
+
from lionagi.libs.sys_util import PATH_TYPE
|
5
|
+
from lionagi.libs import convert, dataframe, SysUtil
|
5
6
|
|
6
|
-
|
7
|
-
|
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
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
111
|
+
with_sender: Flag to include sender information in the output.
|
94
112
|
|
95
113
|
Returns:
|
96
|
-
|
97
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
278
|
-
|
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
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
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
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
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
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
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
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
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
|
-
|
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
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
529
|
-
|
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
|
-
|
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
|
-
|
645
|
+
use_sender: If True, summary is categorized by sender. Otherwise, by role.
|
624
646
|
|
625
647
|
Returns:
|
626
|
-
|
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"]
|
lionagi/core/branch/branch.py
CHANGED
@@ -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
|
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
|
10
|
-
from
|
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
|
14
|
-
from
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
99
|
+
return cls._from_csv(
|
107
100
|
filepath=filepath,
|
108
101
|
read_kwargs=read_kwargs,
|
109
|
-
|
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
|
-
|
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
|
-
|
128
|
+
return cls._from_json(
|
139
129
|
filepath=filepath,
|
140
130
|
read_kwargs=read_kwargs,
|
141
|
-
|
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
|
-
|
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
|