lionagi 0.0.201__py3-none-any.whl → 0.0.204__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/_services/anthropic.py +79 -1
- lionagi/_services/base_service.py +1 -1
- lionagi/_services/services.py +61 -25
- lionagi/_services/transformers.py +46 -0
- lionagi/agents/__init__.py +0 -0
- lionagi/configs/oai_configs.py +1 -1
- lionagi/configs/openrouter_configs.py +1 -1
- lionagi/core/__init__.py +3 -7
- lionagi/core/branch/__init__.py +0 -0
- lionagi/core/branch/branch.py +589 -0
- lionagi/core/branch/branch_manager.py +139 -0
- lionagi/core/branch/cluster.py +1 -0
- lionagi/core/branch/conversation.py +484 -0
- lionagi/core/core_util.py +59 -0
- lionagi/core/flow/__init__.py +0 -0
- lionagi/core/flow/flow.py +19 -0
- lionagi/core/instruction_set/__init__.py +0 -0
- lionagi/core/instruction_set/instruction_set.py +343 -0
- lionagi/core/messages/__init__.py +0 -0
- lionagi/core/messages/messages.py +176 -0
- lionagi/core/sessions/__init__.py +0 -0
- lionagi/core/sessions/session.py +428 -0
- lionagi/models/__init__.py +0 -0
- lionagi/models/base_model.py +0 -0
- lionagi/models/imodel.py +53 -0
- lionagi/schema/data_logger.py +75 -155
- lionagi/tests/test_utils/test_call_util.py +658 -657
- lionagi/tools/tool_manager.py +121 -188
- lionagi/utils/__init__.py +5 -10
- lionagi/utils/call_util.py +667 -585
- lionagi/utils/io_util.py +3 -0
- lionagi/utils/nested_util.py +17 -211
- lionagi/utils/pd_util.py +57 -0
- lionagi/utils/sys_util.py +220 -184
- lionagi/utils/url_util.py +55 -0
- lionagi/version.py +1 -1
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/METADATA +12 -8
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/RECORD +47 -32
- lionagi/core/branch.py +0 -193
- lionagi/core/conversation.py +0 -341
- lionagi/core/flow.py +0 -8
- lionagi/core/instruction_set.py +0 -150
- lionagi/core/messages.py +0 -243
- lionagi/core/sessions.py +0 -474
- /lionagi/{tools → agents}/planner.py +0 -0
- /lionagi/{tools → agents}/prompter.py +0 -0
- /lionagi/{tools → agents}/scorer.py +0 -0
- /lionagi/{tools → agents}/summarizer.py +0 -0
- /lionagi/{tools → agents}/validator.py +0 -0
- /lionagi/core/{flow_util.py → flow/flow_util.py} +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/LICENSE +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/WHEEL +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
lionagi/__init__.py,sha256=pRm9tnfYQnj_ZCan3xr3HQO7tbUeqwRhSBtwOvXJ-o8,886
|
2
|
-
lionagi/version.py,sha256=
|
2
|
+
lionagi/version.py,sha256=DFD_QxPb5C0pITp5fF5NUF2YLCrCu9FEfCgCY7YVy4I,24
|
3
3
|
lionagi/_services/__init__.py,sha256=zU5sxmSI9-Jtp_WsI-Zsb6hmT8y5zF9YtJ7XikAjnbs,60
|
4
|
-
lionagi/_services/anthropic.py,sha256=
|
4
|
+
lionagi/_services/anthropic.py,sha256=pLebbnr2H1A41bzXrJrU7yQbZY35swKrSi4mktXoIyk,3195
|
5
5
|
lionagi/_services/anyscale.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
lionagi/_services/azure.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
7
|
-
lionagi/_services/base_service.py,sha256=
|
7
|
+
lionagi/_services/base_service.py,sha256=bbPQ9xTaY5jxrHe6vW_PeyRkoxVaxWmpWlCqQxSfRI8,17314
|
8
8
|
lionagi/_services/bedrock.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
9
|
lionagi/_services/everlyai.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
lionagi/_services/gemini.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -20,23 +20,38 @@ lionagi/_services/openrouter.py,sha256=MuuwoT2ro9FmY7O1jzCenRrL2YfiYUMM8-0kKoGZH
|
|
20
20
|
lionagi/_services/perplexity.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
21
|
lionagi/_services/predibase.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
lionagi/_services/rungpt.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
|
-
lionagi/_services/services.py,sha256=
|
23
|
+
lionagi/_services/services.py,sha256=kY2TpT98pDS_qCrCO4H1YBlDYNDqekx5S9rWQdWm5Ck,4007
|
24
|
+
lionagi/_services/transformers.py,sha256=tHlo9QVV5ycB2xUEKNRf-b665o_21fPC6c4ycH3Hjk4,1444
|
24
25
|
lionagi/_services/vllm.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
26
|
lionagi/_services/xinference.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
+
lionagi/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
+
lionagi/agents/planner.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
29
|
+
lionagi/agents/prompter.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
30
|
+
lionagi/agents/scorer.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
31
|
+
lionagi/agents/summarizer.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
32
|
+
lionagi/agents/validator.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
26
33
|
lionagi/bridge/__init__.py,sha256=YDKi-pniFEknEXTSEvX6yEe4Y69f0kLvbjvEQ0TdrTU,575
|
27
34
|
lionagi/bridge/langchain.py,sha256=NuuUOJ5oV0l6ae4EeXxaeB82nJ6FDJHVC4AFBoIqiDs,5726
|
28
35
|
lionagi/bridge/llama_index.py,sha256=oggpASmfVA6IhfgBOJS8CWJrQb3zrGaDApUQ7MWT8OM,6652
|
29
36
|
lionagi/configs/__init__.py,sha256=QOd4Rs7vjIpNWvIocxWQeU-q-MPRC-AOxh-gM-eBJ2o,142
|
30
|
-
lionagi/configs/oai_configs.py,sha256=
|
31
|
-
lionagi/configs/openrouter_configs.py,sha256=
|
32
|
-
lionagi/core/__init__.py,sha256=
|
33
|
-
lionagi/core/
|
34
|
-
lionagi/core/
|
35
|
-
lionagi/core/
|
36
|
-
lionagi/core/
|
37
|
-
lionagi/core/
|
38
|
-
lionagi/core/
|
39
|
-
lionagi/core/
|
37
|
+
lionagi/configs/oai_configs.py,sha256=Q2ESc5QiMprnRc_w7SeMlaTYUWl_Y4SEzZSE4iOkz4Q,2646
|
38
|
+
lionagi/configs/openrouter_configs.py,sha256=IBQHqb8mo4Jb3kYAm_7NOHSKRPwSdGbPpDJoiwHxLYw,1269
|
39
|
+
lionagi/core/__init__.py,sha256=6uDjq1WCWBahNiCpzGaUCJe7GDg6lwUD_cGNT86GhwM,200
|
40
|
+
lionagi/core/core_util.py,sha256=80fmVywc0UC9FklXpQr5_dHdtdHdosv5Zxwy9tC-Ufg,2339
|
41
|
+
lionagi/core/branch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
42
|
+
lionagi/core/branch/branch.py,sha256=w3GZAws8_qgY17XOn6svmO4ECQqhNQ_rWMzXiwBQVO8,23403
|
43
|
+
lionagi/core/branch/branch_manager.py,sha256=kLVYUYVUmFQ2CPV34vfVRrkR6fhlizoAr3Dw2ilMX6M,4904
|
44
|
+
lionagi/core/branch/cluster.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
45
|
+
lionagi/core/branch/conversation.py,sha256=q05EwDouTAH5eMDCp2wwRHK0ipbm0MYFngk8R6vOTB0,18664
|
46
|
+
lionagi/core/flow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
+
lionagi/core/flow/flow.py,sha256=Fd6xVZKgjjpr-rcVAjvuMGP04OxNK4LVkbB9VnEP21k,813
|
48
|
+
lionagi/core/flow/flow_util.py,sha256=OoQ2-ktkpQs9f1m1VI1pucUeq75Mx1aKqz8KdINMt8M,2083
|
49
|
+
lionagi/core/instruction_set/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
|
+
lionagi/core/instruction_set/instruction_set.py,sha256=bxrxPxLJdaenvZ2CMaiucNB4fZ_5AWVz49MYs3mG2G8,13682
|
51
|
+
lionagi/core/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
|
+
lionagi/core/messages/messages.py,sha256=bokGS8hu4wQxa-4Gsf2Eg7Q99ANccjjixZpE-DC0P7g,6533
|
53
|
+
lionagi/core/sessions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
|
+
lionagi/core/sessions/session.py,sha256=-dSlIIzHmD2dGd3zu4m_U-UE0BKraKYyt1H_DAzpngk,17694
|
40
55
|
lionagi/datastores/__init__.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
41
56
|
lionagi/datastores/chroma.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
42
57
|
lionagi/datastores/deeplake.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
@@ -49,12 +64,15 @@ lionagi/loaders/__init__.py,sha256=vOOwHkdI0yIA_jV_pNyOrdkS5Ghs0k4od75S1U60jJE,4
|
|
49
64
|
lionagi/loaders/chunker.py,sha256=UY6GrC8qC0MLRaHiSfgG5HMnrtWSTuIvaRPhYfdm9ak,6438
|
50
65
|
lionagi/loaders/load_util.py,sha256=4fzhMk3H6OvcQcViUwlLPSTMpcY4alfdel16lJgXz8Y,8358
|
51
66
|
lionagi/loaders/reader.py,sha256=xI1uxw9qGJ_rWev_s3vtW8Ep9YaK-15q7ts-Jy61PGg,4625
|
67
|
+
lionagi/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
|
+
lionagi/models/base_model.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
69
|
+
lionagi/models/imodel.py,sha256=VultpAAZ5PBT6_Cps-LjgZqHEyuF-km6eVvT-sEPEgo,1491
|
52
70
|
lionagi/schema/__init__.py,sha256=XRWXK9sztycoIMCTzwLEVMxxc1wgWKNUDRbWTpn5Ie0,208
|
53
71
|
lionagi/schema/async_queue.py,sha256=e_wFyDvCeKTxW6MAIU6Q3jxw24uEQuahaZwNDzZMB4k,5674
|
54
72
|
lionagi/schema/base_condition.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
55
73
|
lionagi/schema/base_node.py,sha256=Ol4Y6gn81Dm8FJb3fdKVkJlq4R-OAGIf891exnVv45I,13211
|
56
74
|
lionagi/schema/base_tool.py,sha256=8LR-MYOGkv9zCHd8tWry296OZNYlbTpYeO1xd-oQcOM,1254
|
57
|
-
lionagi/schema/data_logger.py,sha256=
|
75
|
+
lionagi/schema/data_logger.py,sha256=2rNPBYF29_2xgv2m226BzKdTfFIVU1YlzQ0PK8zLAvY,4313
|
58
76
|
lionagi/schema/data_node.py,sha256=k80mv5DCqAHrGNlmaIHAkCA7JF4dkaRaRDh_oku4kUY,2272
|
59
77
|
lionagi/schema/status_tracker.py,sha256=6otnTSMrH5jM0PUDiDeK3zG0VOSKfNBDzNN6Bts2tmA,1236
|
60
78
|
lionagi/structures/__init__.py,sha256=wMPekT2vbWwUkJ5aW5o-lzJC9Fzhta6RHDiFPTNUm_0,120
|
@@ -64,28 +82,25 @@ lionagi/structures/structure.py,sha256=YyL3LxgeQWgkWDhACRxo8GoDn0IjE7idh7B0r5U3m
|
|
64
82
|
lionagi/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
65
83
|
lionagi/tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
84
|
lionagi/tests/test_utils/test_api_util.py,sha256=7Zyc0J1glZrIWI1HrTRSRhzw8jaUW1L2vVLFAlUhI4g,9721
|
67
|
-
lionagi/tests/test_utils/test_call_util.py,sha256=
|
85
|
+
lionagi/tests/test_utils/test_call_util.py,sha256=7xmfFaWvniMQfaOyfwasA2enJQVuSlcAwc8gUyAR_7k,26277
|
68
86
|
lionagi/tests/test_utils/test_encrypt_util.py,sha256=hlkbFjQs2jodr8fgtPli6f1MO3doQbTcsZfzGKVrG5k,12652
|
69
87
|
lionagi/tests/test_utils/test_io_util.py,sha256=cFZCT6EikVeuXB13w-UbtO3YceCHBO5RlNXxGICqg_U,11002
|
70
88
|
lionagi/tests/test_utils/test_nested_util.py,sha256=Z1boHufhjZryw51qW2lABOnnyJ1snAFp26KKzzzD8Bs,12612
|
71
89
|
lionagi/tests/test_utils/test_sys_util.py,sha256=TDCkzll-JLa6NuBbN_-ay5Rw9KTa_HcSHHAq62RVwGI,13545
|
72
90
|
lionagi/tools/__init__.py,sha256=ZEck-ReP5Co05nAA2gUXTpKoDN2QZqrL7DvU9Z09gqg,69
|
73
|
-
lionagi/tools/
|
74
|
-
lionagi/tools/prompter.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
75
|
-
lionagi/tools/scorer.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
76
|
-
lionagi/tools/summarizer.py,sha256=chG3GNX2BBDTWIuSVfZUJ_YF_ZVBSoel2d_AN0OChS0,6
|
77
|
-
lionagi/tools/tool_manager.py,sha256=znpDGeg7m71CCGFUkLCPmXIFj8jQG9t1n1Gcj4Aqgz0,9555
|
91
|
+
lionagi/tools/tool_manager.py,sha256=4yCjMVOrKo4PoEMv0xF6wMirpj20qhLx4J7op0v5h2w,6543
|
78
92
|
lionagi/tools/tool_util.py,sha256=5ln7lnqC_rjhKDDwef10xrBrjP1yLzsQvphllD5crec,9252
|
79
|
-
lionagi/
|
80
|
-
lionagi/utils/__init__.py,sha256=V3yj15tXS4ghXT0Du5l34RyIeIQzZCB1nBwWYydA32I,1081
|
93
|
+
lionagi/utils/__init__.py,sha256=FJAqYyb19Mp6kiietyjtp0WLlW2857-HAHl7OxqCc5Y,954
|
81
94
|
lionagi/utils/api_util.py,sha256=YV-DKPgR4lCKO_riroSKyq6mO-8vz-SilRo_gWtg4Zg,15282
|
82
|
-
lionagi/utils/call_util.py,sha256=
|
95
|
+
lionagi/utils/call_util.py,sha256=G3K8dkEZ9AehrBdbKHK6Xtr1pZZWxrtqhQEu5xkItuo,32919
|
83
96
|
lionagi/utils/encrypt_util.py,sha256=iZjZdXVvl0lw4Yw_YNzIWriM3F2qKtzai7PgSQ1TExc,9316
|
84
|
-
lionagi/utils/io_util.py,sha256=
|
85
|
-
lionagi/utils/nested_util.py,sha256=
|
86
|
-
lionagi/utils/
|
87
|
-
lionagi
|
88
|
-
lionagi
|
89
|
-
lionagi-0.0.
|
90
|
-
lionagi-0.0.
|
91
|
-
lionagi-0.0.
|
97
|
+
lionagi/utils/io_util.py,sha256=xoVsq8sP5JGsosuC80Kad3GkGjm8Qm0OLYyTw-U5ru8,6455
|
98
|
+
lionagi/utils/nested_util.py,sha256=67j-ySQtuMGxtjnC-Ty2mwQgqp2g1gZhXRy1MulUu1U,26656
|
99
|
+
lionagi/utils/pd_util.py,sha256=ShLdNRJI-U2nN9TmZEGPdRXHzFMfrmw-sTpUbxNWr1w,2274
|
100
|
+
lionagi/utils/sys_util.py,sha256=iZQu3HvYLl-12mmZ0kk4lX-3FnkRh-EAMAefPt_6P7k,10893
|
101
|
+
lionagi/utils/url_util.py,sha256=fu1uRFwSR9D3dO1nfSYVNRD1b1BZVClcbpgF7tA_U4s,1864
|
102
|
+
lionagi-0.0.204.dist-info/LICENSE,sha256=TBnSyG8fs_tMRtK805GzA1cIyExleKyzoN_kuVxT9IY,11358
|
103
|
+
lionagi-0.0.204.dist-info/METADATA,sha256=kxTcrwAWtkK8cRY0CAxJaOZ8lBIVQgFcy-8HT92mTuc,17894
|
104
|
+
lionagi-0.0.204.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
105
|
+
lionagi-0.0.204.dist-info/top_level.txt,sha256=szvch_d2jE1Lu9ZIKsl26Ll6BGfYfbOgt5lm-UpFSo4,8
|
106
|
+
lionagi-0.0.204.dist-info/RECORD,,
|
lionagi/core/branch.py
DELETED
@@ -1,193 +0,0 @@
|
|
1
|
-
from copy import deepcopy
|
2
|
-
from typing import Any, Dict, Union
|
3
|
-
from datetime import datetime
|
4
|
-
from pandas import DataFrame
|
5
|
-
|
6
|
-
from ..tools.tool_manager import ToolManager
|
7
|
-
from .messages import Message
|
8
|
-
from .conversation import Conversation
|
9
|
-
|
10
|
-
|
11
|
-
class Branch(Conversation):
|
12
|
-
"""
|
13
|
-
Branch of a conversation with message tracking and tool management.
|
14
|
-
|
15
|
-
This class extends the Conversation class, managing a branch of conversation
|
16
|
-
with the ability to track messages, maintain instruction sets, and manage tools
|
17
|
-
using a ToolManager.
|
18
|
-
|
19
|
-
Args:
|
20
|
-
init_message: The initial message or messages of the conversation branch.
|
21
|
-
instruction_sets: A set of instructions to be used in the conversation.
|
22
|
-
Defaults to None, which creates an empty dict.
|
23
|
-
tool_manager: A ToolManager instance to manage tools. Defaults to None,
|
24
|
-
which creates a new ToolManager instance.
|
25
|
-
|
26
|
-
Raises:
|
27
|
-
ValueError: If the input `init_message` is not a DataFrame or Message instance.
|
28
|
-
|
29
|
-
Attributes:
|
30
|
-
instruction_sets: Instruction sets associated with the conversation branch.
|
31
|
-
tool_manager: Tool manager for the branch.
|
32
|
-
messages: DataFrame containing the conversation messages.
|
33
|
-
system_message: The system message of the conversation branch.
|
34
|
-
|
35
|
-
Examples:
|
36
|
-
# Creating a Branch with an initial message
|
37
|
-
initial_message = Message(role="user", content="Hi there!")
|
38
|
-
branch = Branch(init_message=initial_message)
|
39
|
-
|
40
|
-
# Creating a Branch with initial messages as DataFrame
|
41
|
-
messages_df = DataFrame({
|
42
|
-
"role": ["user", "system"],
|
43
|
-
"content": ["Hi there!", "Hello!"]
|
44
|
-
})
|
45
|
-
branch = Branch(init_message=messages_df)
|
46
|
-
"""
|
47
|
-
|
48
|
-
def __init__(self, init_message: Union[Message, DataFrame],
|
49
|
-
instruction_sets: dict = None,
|
50
|
-
tool_manager: ToolManager = None) -> None:
|
51
|
-
super().__init__()
|
52
|
-
self.instruction_sets = instruction_sets if instruction_sets else {}
|
53
|
-
self.tool_manager = tool_manager if tool_manager else ToolManager()
|
54
|
-
|
55
|
-
if isinstance(init_message, DataFrame):
|
56
|
-
self.messages = init_message
|
57
|
-
elif isinstance(init_message, Message):
|
58
|
-
self.add_message(init_message)
|
59
|
-
else:
|
60
|
-
raise ValueError('Please input a valid init_message: DataFrame or Message')
|
61
|
-
self.system_message = self.messages.loc[0, 'content']
|
62
|
-
|
63
|
-
def change_system_message(self, system: Message):
|
64
|
-
"""
|
65
|
-
Change the system message to the provided message.
|
66
|
-
|
67
|
-
Args:
|
68
|
-
system: A Message object representing the new system message.
|
69
|
-
"""
|
70
|
-
message_dict = system.to_dict()
|
71
|
-
message_dict['timestamp'] = datetime.now()
|
72
|
-
self.messages.loc[0] = message_dict
|
73
|
-
self.system_message = self.messages.loc[0, 'content']
|
74
|
-
|
75
|
-
def add_instruction_set(self, name, instruction_set):
|
76
|
-
"""
|
77
|
-
Add an instruction set to the conversation branch.
|
78
|
-
|
79
|
-
Args:
|
80
|
-
name: The name of the instruction set.
|
81
|
-
instruction_set: The instruction set to be added.
|
82
|
-
"""
|
83
|
-
self.instruction_sets[name] = instruction_set
|
84
|
-
|
85
|
-
def remove_instruction_set(self, name):
|
86
|
-
"""
|
87
|
-
Remove an instruction set from the conversation branch by name.
|
88
|
-
|
89
|
-
Args:
|
90
|
-
name: The name of the instruction set to be removed.
|
91
|
-
|
92
|
-
Returns:
|
93
|
-
The removed instruction set if it exists, else None.
|
94
|
-
"""
|
95
|
-
return self.instruction_sets.pop(name)
|
96
|
-
|
97
|
-
def register_tools(self, tools):
|
98
|
-
"""
|
99
|
-
Register a list of tools to the ToolManager.
|
100
|
-
|
101
|
-
Args:
|
102
|
-
tools: A single tool or a list of tools to be registered.
|
103
|
-
"""
|
104
|
-
if not isinstance(tools, list):
|
105
|
-
tools = [tools]
|
106
|
-
self.tool_manager.register_tools(tools=tools)
|
107
|
-
|
108
|
-
def delete_tool(self, name):
|
109
|
-
"""
|
110
|
-
Delete a tool from the ToolManager by name.
|
111
|
-
|
112
|
-
Args:
|
113
|
-
name: The name of the tool to be deleted.
|
114
|
-
|
115
|
-
Returns:
|
116
|
-
True if the tool was successfully deleted, False otherwise.
|
117
|
-
"""
|
118
|
-
if name in self.tool_manager.registry:
|
119
|
-
self.tool_manager.registry.pop(name)
|
120
|
-
return True
|
121
|
-
return False
|
122
|
-
|
123
|
-
def clone(self):
|
124
|
-
"""
|
125
|
-
Create a deep copy of the current branch.
|
126
|
-
|
127
|
-
Returns:
|
128
|
-
A new Branch instance that is a deep copy of the current branch.
|
129
|
-
"""
|
130
|
-
cloned = Branch(self.messages.copy())
|
131
|
-
cloned.instruction_sets = deepcopy(self.instruction_sets)
|
132
|
-
cloned.tool_manager = ToolManager()
|
133
|
-
cloned.tool_manager.registry = deepcopy(self.tool_manager.registry)
|
134
|
-
return cloned
|
135
|
-
|
136
|
-
def merge(self, branch, update=True):
|
137
|
-
"""
|
138
|
-
Merge another Branch into the current one.
|
139
|
-
|
140
|
-
Args:
|
141
|
-
branch: The Branch to merge into the current one.
|
142
|
-
update: Whether to update the current Branch. If False, only adds
|
143
|
-
non-existing items from the other Branch.
|
144
|
-
"""
|
145
|
-
message_copy = branch.messages.copy()
|
146
|
-
branch_system = message_copy.loc[0]
|
147
|
-
message_copy.drop(0, inplace=True)
|
148
|
-
self.messages = self.messages.merge(message_copy, how='outer')
|
149
|
-
if update:
|
150
|
-
self.instruction_sets.update(branch.instruction_sets)
|
151
|
-
self.tool_manager.registry.update(branch.tool_manager.registry)
|
152
|
-
self.messages.loc[0] = branch_system
|
153
|
-
else:
|
154
|
-
for key, value in branch.instruction_sets.items():
|
155
|
-
if key not in self.instruction_sets:
|
156
|
-
self.instruction_sets[key] = value
|
157
|
-
|
158
|
-
for key, value in branch.tool_manager.registry.items():
|
159
|
-
if key not in self.tool_manager.registry:
|
160
|
-
self.tool_manager.registry[key] = value
|
161
|
-
|
162
|
-
def report(self) -> Dict[str, Any]:
|
163
|
-
"""
|
164
|
-
Generate a report about the conversation branch.
|
165
|
-
|
166
|
-
Returns:
|
167
|
-
A dictionary containing information about total messages, a summary by role,
|
168
|
-
instruction sets, registered tools, and the messages themselves.
|
169
|
-
"""
|
170
|
-
|
171
|
-
return {
|
172
|
-
"total_messages": len(self.messages),
|
173
|
-
"summary_by_role": self.message_counts(),
|
174
|
-
"instruction_sets": self.instruction_sets,
|
175
|
-
"registered_tools": self.tool_manager.registry,
|
176
|
-
"messages": [
|
177
|
-
msg.to_dict() for _, msg in self.messages.iterrows()
|
178
|
-
],
|
179
|
-
}
|
180
|
-
|
181
|
-
def to_chatcompletion_message(self):
|
182
|
-
"""
|
183
|
-
Convert the conversation branch to a list of messages for chat completion.
|
184
|
-
|
185
|
-
Returns:
|
186
|
-
A list of dictionaries with 'name' or 'role' and 'content' from the conversation messages.
|
187
|
-
"""
|
188
|
-
message = []
|
189
|
-
for _, row in self.messages.iterrows():
|
190
|
-
out = {"role": row['role'], "content": row['content']}
|
191
|
-
message.append(out)
|
192
|
-
return message
|
193
|
-
|
lionagi/core/conversation.py
DELETED
@@ -1,341 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
from datetime import datetime
|
3
|
-
from typing import Optional, Dict, Any
|
4
|
-
import pandas as pd
|
5
|
-
|
6
|
-
from .messages import Message
|
7
|
-
|
8
|
-
class Conversation:
|
9
|
-
"""
|
10
|
-
Manages the flow and archival of a conversation using Pandas DataFrame.
|
11
|
-
|
12
|
-
Attributes:
|
13
|
-
messages (pd.DataFrame): A DataFrame to store messages.
|
14
|
-
dir (Optional[str]): The directory path for saving files, if provided.
|
15
|
-
|
16
|
-
Examples:
|
17
|
-
>>> conv = Conversation()
|
18
|
-
>>> msg = Message(node_id="1", role="user", name="Alice", content="Hi there!")
|
19
|
-
>>> conv.add_message(msg)
|
20
|
-
>>> conv.get_message_by_role("user")
|
21
|
-
>>> conv.last_message()
|
22
|
-
>>> conv.search_message("Hi")
|
23
|
-
>>> conv.message_counts()
|
24
|
-
"""
|
25
|
-
|
26
|
-
def __init__(self, dir: Optional[str] = None) -> None:
|
27
|
-
self.messages = pd.DataFrame(
|
28
|
-
columns=["node_id", "role", "name", "timestamp", "content"]
|
29
|
-
)
|
30
|
-
self.dir = dir
|
31
|
-
|
32
|
-
def add_message(self, message: Message) -> None:
|
33
|
-
"""
|
34
|
-
Adds a new message to the DataFrame.
|
35
|
-
|
36
|
-
Args:
|
37
|
-
message (Message): The message object to be added.
|
38
|
-
|
39
|
-
Examples:
|
40
|
-
>>> conv = Conversation()
|
41
|
-
>>> msg = Message(node_id="1", role="user", name="Alice", content="Hi there!")
|
42
|
-
>>> conv.add_message(msg)
|
43
|
-
"""
|
44
|
-
message_dict = message.to_dict()
|
45
|
-
if isinstance(message_dict['content'], dict):
|
46
|
-
message_dict['content'] = json.dumps(message_dict['content'])
|
47
|
-
message_dict['timestamp'] = datetime.now()
|
48
|
-
self.messages.loc[len(self.messages)] = message_dict
|
49
|
-
|
50
|
-
def get_message_by_role(self, role: str) -> pd.DataFrame:
|
51
|
-
"""
|
52
|
-
Retrieves messages sent by a specific role.
|
53
|
-
|
54
|
-
Args:
|
55
|
-
role (str): The role to filter messages by.
|
56
|
-
|
57
|
-
Returns:
|
58
|
-
pd.DataFrame: DataFrame of messages matching the role.
|
59
|
-
|
60
|
-
Examples:
|
61
|
-
>>> conv = Conversation()
|
62
|
-
>>> conv.get_message_by_role("user")
|
63
|
-
"""
|
64
|
-
return self.messages[self.messages["role"] == role]
|
65
|
-
|
66
|
-
def last_message(self):
|
67
|
-
"""
|
68
|
-
Retrieves the last message from the conversation.
|
69
|
-
|
70
|
-
Returns:
|
71
|
-
Message: The last message object, if the DataFrame is not empty.
|
72
|
-
|
73
|
-
Examples:
|
74
|
-
>>> conv = Conversation()
|
75
|
-
>>> conv.last_message()
|
76
|
-
"""
|
77
|
-
if not self.messages.empty:
|
78
|
-
return Message(**self.messages.iloc[-1].to_dict())
|
79
|
-
|
80
|
-
def last_message_by_role(self, role: str) -> Optional[Message]:
|
81
|
-
"""
|
82
|
-
Retrieves the last message of a specific role.
|
83
|
-
|
84
|
-
Args:
|
85
|
-
role (str): The role to get messages by.
|
86
|
-
|
87
|
-
Returns:
|
88
|
-
Optional[Message]: The last message of the given role, if exists.
|
89
|
-
|
90
|
-
Examples:
|
91
|
-
>>> conv = Conversation()
|
92
|
-
>>> conv.last_message_by_role("user")
|
93
|
-
"""
|
94
|
-
filtered_messages = self.messages[
|
95
|
-
self.messages["role"] == role
|
96
|
-
]
|
97
|
-
if not filtered_messages.empty:
|
98
|
-
return Message(**filtered_messages.iloc[-1].to_dict())
|
99
|
-
return None
|
100
|
-
|
101
|
-
def search_message(self, keyword: str, case_sensitive: bool = False) -> pd.DataFrame:
|
102
|
-
"""
|
103
|
-
Searches for messages containing a specific keyword.
|
104
|
-
|
105
|
-
Args:
|
106
|
-
keyword (str): The keyword to search for.
|
107
|
-
case_sensitive (bool, optional): Whether the search should be case-sensitive. Defaults to False.
|
108
|
-
|
109
|
-
Returns:
|
110
|
-
pd.DataFrame: DataFrame of messages containing the keyword.
|
111
|
-
|
112
|
-
Examples:
|
113
|
-
>>> conv = Conversation()
|
114
|
-
>>> conv.search_message("Hi")
|
115
|
-
>>> conv.search_message("Hi", case_sensitive=True)
|
116
|
-
"""
|
117
|
-
if not case_sensitive:
|
118
|
-
keyword = keyword.lower()
|
119
|
-
return self.messages[
|
120
|
-
self.messages["content"].str.lower().str.contains(keyword)
|
121
|
-
]
|
122
|
-
return self.messages[self.messages["content"].str.contains(keyword)]
|
123
|
-
|
124
|
-
def delete_message(self, message_id: str) -> bool:
|
125
|
-
"""
|
126
|
-
Deletes a message by its unique identifier.
|
127
|
-
|
128
|
-
Args:
|
129
|
-
message_id (str): The unique identifier of the message.
|
130
|
-
|
131
|
-
Returns:
|
132
|
-
bool: True if a message was deleted, False otherwise.
|
133
|
-
|
134
|
-
Examples:
|
135
|
-
>>> conv = Conversation()
|
136
|
-
>>> conv.delete_message("1")
|
137
|
-
"""
|
138
|
-
initial_length = len(self.messages)
|
139
|
-
self.messages = self.messages[self.messages["node_id"] != message_id]
|
140
|
-
return len(self.messages) < initial_length
|
141
|
-
|
142
|
-
def update_message_content(self, message_id: str, new_content: str) -> bool:
|
143
|
-
"""
|
144
|
-
Updates the content of a specific message by its unique identifier.
|
145
|
-
|
146
|
-
Args:
|
147
|
-
message_id (str): The unique identifier of the message.
|
148
|
-
new_content (str): The new content for the message.
|
149
|
-
|
150
|
-
Returns:
|
151
|
-
bool: True if the content was updated, False otherwise.
|
152
|
-
|
153
|
-
Examples:
|
154
|
-
>>> conv = Conversation()
|
155
|
-
>>> conv.update_message_content("1", "New content")
|
156
|
-
"""
|
157
|
-
index = self.messages.index[self.messages["id_"] == message_id].tolist()
|
158
|
-
if index:
|
159
|
-
self.messages.at[index[0], "content"] = new_content
|
160
|
-
return True
|
161
|
-
return False
|
162
|
-
|
163
|
-
def get_message_by_id(self, message_id: str) -> Optional[Message]:
|
164
|
-
"""
|
165
|
-
Retrieves a message by its unique identifier.
|
166
|
-
|
167
|
-
Args:
|
168
|
-
message_id (str): The unique identifier of the message.
|
169
|
-
|
170
|
-
Returns:
|
171
|
-
Optional[Message]: The message if found, None otherwise.
|
172
|
-
|
173
|
-
Examples:
|
174
|
-
>>> conv = Conversation()
|
175
|
-
>>> conv.get_message_by_id("1")
|
176
|
-
"""
|
177
|
-
message_df = self.messages[self.messages["id_"] == message_id]
|
178
|
-
if not message_df.empty:
|
179
|
-
return Message.from_json(message_df.iloc[0].to_dict())
|
180
|
-
return None
|
181
|
-
|
182
|
-
def message_counts(self, use_name=False) -> Dict[str, int]:
|
183
|
-
"""
|
184
|
-
Provides a summary of message counts in the conversation, optionally grouped by sender's name.
|
185
|
-
|
186
|
-
Args:
|
187
|
-
use_name (bool, optional): If True, groups by sender's name instead of role. Defaults to False.
|
188
|
-
|
189
|
-
Returns:
|
190
|
-
Dict[str, int]: A dictionary with roles or names as keys and their associated message counts as values.
|
191
|
-
|
192
|
-
Examples:
|
193
|
-
>>> conv = Conversation()
|
194
|
-
>>> conv.message_counts() # Group by role
|
195
|
-
>>> conv.message_counts(use_name=True) # Group by sender's name
|
196
|
-
"""
|
197
|
-
messages = self.messages['name'] if use_name else self.messages['role']
|
198
|
-
result = messages.value_counts().to_dict()
|
199
|
-
result['total'] = len(self.messages)
|
200
|
-
return result
|
201
|
-
|
202
|
-
def report(self) -> Dict[str, Any]:
|
203
|
-
"""
|
204
|
-
Generates a detailed report of the conversation.
|
205
|
-
|
206
|
-
Returns:
|
207
|
-
Dict[str, Any]: A dictionary with various details about the conversation.
|
208
|
-
"""
|
209
|
-
return {
|
210
|
-
"total_messages": len(self.messages),
|
211
|
-
"summary_by_role": self.message_counts(),
|
212
|
-
"messages": [
|
213
|
-
msg.to_dict() for _, msg in self.messages.iterrows()
|
214
|
-
],
|
215
|
-
}
|
216
|
-
|
217
|
-
def history(
|
218
|
-
self, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None
|
219
|
-
) -> pd.DataFrame:
|
220
|
-
"""
|
221
|
-
Returns a history of the conversation, optionally filtered by date range.
|
222
|
-
|
223
|
-
Args:
|
224
|
-
start_date (Optional[datetime], optional): The start date of the date range filter. Defaults to None.
|
225
|
-
end_date (Optional[datetime], optional): The end date of the date range filter. Defaults to None.
|
226
|
-
|
227
|
-
Returns:
|
228
|
-
pd.DataFrame: A DataFrame containing the filtered conversation history.
|
229
|
-
"""
|
230
|
-
if isinstance(start_date, str):
|
231
|
-
start_date = datetime.strptime(start_date, '%Y-%m-%d')
|
232
|
-
if isinstance(end_date, str):
|
233
|
-
end_date = datetime.strptime(end_date, '%Y-%m-%d')
|
234
|
-
if start_date and end_date:
|
235
|
-
return self.messages[
|
236
|
-
(self.messages["timestamp"].dt.date >= start_date.date())
|
237
|
-
& (self.messages["timestamp"].dt.date <= end_date.date())
|
238
|
-
]
|
239
|
-
elif start_date:
|
240
|
-
return self.messages[(self.messages["timestamp"].dt.date >= start_date.date())]
|
241
|
-
elif end_date:
|
242
|
-
return self.messages[(self.messages["timestamp"].dt.date <= end_date.date())]
|
243
|
-
return self.messages
|
244
|
-
|
245
|
-
def replace_keyword(self, keyword: str, replacement: str, case_sensitive: bool = False) -> None:
|
246
|
-
"""
|
247
|
-
Replaces a keyword in all messages with a replacement.
|
248
|
-
|
249
|
-
Args:
|
250
|
-
keyword (str): The keyword to replace.
|
251
|
-
replacement (str): The text to replace the keyword with.
|
252
|
-
case_sensitive (bool, optional): Whether the replacement should be case-sensitive. Defaults to False.
|
253
|
-
"""
|
254
|
-
if not case_sensitive:
|
255
|
-
self.messages["content"] = self.messages["content"].str.replace(
|
256
|
-
keyword, replacement, case=False
|
257
|
-
)
|
258
|
-
else:
|
259
|
-
self.messages["content"] = self.messages["content"].str.replace(
|
260
|
-
keyword, replacement
|
261
|
-
)
|
262
|
-
|
263
|
-
def clone(self) -> 'Conversation':
|
264
|
-
"""
|
265
|
-
Creates a deep copy of the conversation.
|
266
|
-
|
267
|
-
Returns:
|
268
|
-
Conversation: A new Conversation instance with the same messages.
|
269
|
-
"""
|
270
|
-
cloned = Conversation(self.dir)
|
271
|
-
cloned.messages = self.messages.copy()
|
272
|
-
return cloned
|
273
|
-
|
274
|
-
def merge(self, other: 'Conversation') -> None:
|
275
|
-
"""
|
276
|
-
Merges another conversation into this one.
|
277
|
-
|
278
|
-
Args:
|
279
|
-
other (Conversation): Another Conversation instance to merge with this one.
|
280
|
-
"""
|
281
|
-
self.messages = self.messages.merge(other.messages, how='outer')
|
282
|
-
|
283
|
-
def rollback(self, steps: int) -> None:
|
284
|
-
"""
|
285
|
-
Rollbacks the conversation to a previous state by the given number of steps.
|
286
|
-
|
287
|
-
Args:
|
288
|
-
steps (int): The number of steps to rollback.
|
289
|
-
|
290
|
-
Raises:
|
291
|
-
ValueError: If steps are negative or exceed the current number of messages.
|
292
|
-
"""
|
293
|
-
if steps < 0 or steps > len(self.messages):
|
294
|
-
raise ValueError("Steps must be a non-negative integer less than or equal to the number of messages.")
|
295
|
-
self.messages = self.messages[:-steps].reset_index(drop=True)
|
296
|
-
|
297
|
-
def reset(self) -> None:
|
298
|
-
"""Clears all messages in the DataFrame."""
|
299
|
-
self.messages = pd.DataFrame(columns=self.messages.columns)
|
300
|
-
|
301
|
-
def to_csv(self, filepath: str, **kwargs) -> None:
|
302
|
-
"""
|
303
|
-
Saves the conversation to a CSV file.
|
304
|
-
|
305
|
-
Args:
|
306
|
-
filepath (str): The path to the file where the conversation should be saved.
|
307
|
-
"""
|
308
|
-
self.messages.to_csv(filepath, **kwargs)
|
309
|
-
|
310
|
-
def from_csv(self, filepath: str, **kwargs) -> None:
|
311
|
-
"""
|
312
|
-
Loads messages from a CSV file into the conversation.
|
313
|
-
|
314
|
-
Args:
|
315
|
-
filepath (str): The path to the file from which to load the conversation.
|
316
|
-
"""
|
317
|
-
self.messages = pd.read_csv(filepath, **kwargs)
|
318
|
-
|
319
|
-
def to_json(self, filepath: str) -> None:
|
320
|
-
"""
|
321
|
-
Saves the entire conversation as a JSON file.
|
322
|
-
|
323
|
-
Args:
|
324
|
-
filepath (str): The file path where the conversation will be saved.
|
325
|
-
"""
|
326
|
-
self.messages.to_json(
|
327
|
-
filepath, orient="records", lines=True, date_format="iso"
|
328
|
-
)
|
329
|
-
|
330
|
-
def from_json(self, filepath: str) -> None:
|
331
|
-
"""
|
332
|
-
Loads messages from a JSON file into the conversation.
|
333
|
-
|
334
|
-
Args:
|
335
|
-
filepath (str): The file path from which to load the conversation.
|
336
|
-
"""
|
337
|
-
self.reset()
|
338
|
-
self.messages = pd.read_json(filepath, orient="records", lines=True)
|
339
|
-
|
340
|
-
# def append(self, other: 'Conversation'):
|
341
|
-
# self.messages = pd.concat([self.messages, other.messages]).reset_index(drop=True)
|