lionagi 0.0.201__py3-none-any.whl → 0.0.204__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|