lionagi 0.1.2__py3-none-any.whl → 0.2.0__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 +60 -5
- lionagi/core/__init__.py +0 -25
- lionagi/core/_setting/_setting.py +59 -0
- lionagi/core/action/__init__.py +14 -0
- lionagi/core/action/function_calling.py +136 -0
- lionagi/core/action/manual.py +1 -0
- lionagi/core/action/node.py +109 -0
- lionagi/core/action/tool.py +114 -0
- lionagi/core/action/tool_manager.py +356 -0
- lionagi/core/agent/base_agent.py +27 -13
- lionagi/core/agent/eval/evaluator.py +1 -0
- lionagi/core/agent/eval/vote.py +40 -0
- lionagi/core/agent/learn/learner.py +59 -0
- lionagi/core/agent/plan/unit_template.py +1 -0
- lionagi/core/collections/__init__.py +17 -0
- lionagi/core/{generic/data_logger.py → collections/_logger.py} +69 -55
- lionagi/core/collections/abc/__init__.py +53 -0
- lionagi/core/collections/abc/component.py +615 -0
- lionagi/core/collections/abc/concepts.py +297 -0
- lionagi/core/collections/abc/exceptions.py +150 -0
- lionagi/core/collections/abc/util.py +45 -0
- lionagi/core/collections/exchange.py +161 -0
- lionagi/core/collections/flow.py +426 -0
- lionagi/core/collections/model.py +419 -0
- lionagi/core/collections/pile.py +913 -0
- lionagi/core/collections/progression.py +236 -0
- lionagi/core/collections/util.py +64 -0
- lionagi/core/director/direct.py +314 -0
- lionagi/core/director/director.py +2 -0
- lionagi/core/{execute/branch_executor.py → engine/branch_engine.py} +134 -97
- lionagi/core/{execute/instruction_map_executor.py → engine/instruction_map_engine.py} +80 -55
- lionagi/{experimental/directive/evaluator → core/engine}/script_engine.py +17 -1
- lionagi/core/executor/base_executor.py +90 -0
- lionagi/core/{execute/structure_executor.py → executor/graph_executor.py} +62 -66
- lionagi/core/{execute → executor}/neo4j_executor.py +70 -67
- lionagi/core/generic/__init__.py +3 -33
- lionagi/core/generic/edge.py +29 -79
- lionagi/core/generic/edge_condition.py +16 -0
- lionagi/core/generic/graph.py +236 -0
- lionagi/core/generic/hyperedge.py +1 -0
- lionagi/core/generic/node.py +156 -221
- lionagi/core/generic/tree.py +48 -0
- lionagi/core/generic/tree_node.py +79 -0
- lionagi/core/mail/__init__.py +12 -0
- lionagi/core/mail/mail.py +25 -0
- lionagi/core/mail/mail_manager.py +139 -58
- lionagi/core/mail/package.py +45 -0
- lionagi/core/mail/start_mail.py +36 -0
- lionagi/core/message/__init__.py +19 -0
- lionagi/core/message/action_request.py +133 -0
- lionagi/core/message/action_response.py +135 -0
- lionagi/core/message/assistant_response.py +95 -0
- lionagi/core/message/instruction.py +234 -0
- lionagi/core/message/message.py +101 -0
- lionagi/core/message/system.py +86 -0
- lionagi/core/message/util.py +283 -0
- lionagi/core/report/__init__.py +4 -0
- lionagi/core/report/base.py +217 -0
- lionagi/core/report/form.py +231 -0
- lionagi/core/report/report.py +166 -0
- lionagi/core/report/util.py +28 -0
- lionagi/core/rule/_default.py +16 -0
- lionagi/core/rule/action.py +99 -0
- lionagi/core/rule/base.py +238 -0
- lionagi/core/rule/boolean.py +56 -0
- lionagi/core/rule/choice.py +47 -0
- lionagi/core/rule/mapping.py +96 -0
- lionagi/core/rule/number.py +71 -0
- lionagi/core/rule/rulebook.py +109 -0
- lionagi/core/rule/string.py +52 -0
- lionagi/core/rule/util.py +35 -0
- lionagi/core/session/branch.py +431 -0
- lionagi/core/session/directive_mixin.py +287 -0
- lionagi/core/session/session.py +229 -903
- lionagi/core/structure/__init__.py +1 -0
- lionagi/core/structure/chain.py +1 -0
- lionagi/core/structure/forest.py +1 -0
- lionagi/core/structure/graph.py +1 -0
- lionagi/core/structure/tree.py +1 -0
- lionagi/core/unit/__init__.py +5 -0
- lionagi/core/unit/parallel_unit.py +245 -0
- lionagi/core/unit/template/action.py +81 -0
- lionagi/core/unit/template/base.py +51 -0
- lionagi/core/unit/template/plan.py +84 -0
- lionagi/core/unit/template/predict.py +109 -0
- lionagi/core/unit/template/score.py +124 -0
- lionagi/core/unit/template/select.py +104 -0
- lionagi/core/unit/unit.py +362 -0
- lionagi/core/unit/unit_form.py +305 -0
- lionagi/core/unit/unit_mixin.py +1168 -0
- lionagi/core/unit/util.py +71 -0
- lionagi/core/validator/validator.py +364 -0
- lionagi/core/work/work.py +74 -0
- lionagi/core/work/work_function.py +92 -0
- lionagi/core/work/work_queue.py +81 -0
- lionagi/core/work/worker.py +195 -0
- lionagi/core/work/worklog.py +124 -0
- lionagi/experimental/compressor/base.py +46 -0
- lionagi/experimental/compressor/llm_compressor.py +247 -0
- lionagi/experimental/compressor/llm_summarizer.py +61 -0
- lionagi/experimental/compressor/util.py +70 -0
- lionagi/experimental/directive/__init__.py +19 -0
- lionagi/experimental/directive/parser/base_parser.py +69 -2
- lionagi/experimental/directive/{template_ → template}/base_template.py +17 -1
- lionagi/{libs/ln_tokenizer.py → experimental/directive/tokenizer.py} +16 -0
- lionagi/experimental/{directive/evaluator → evaluator}/ast_evaluator.py +16 -0
- lionagi/experimental/{directive/evaluator → evaluator}/base_evaluator.py +16 -0
- lionagi/experimental/knowledge/base.py +10 -0
- lionagi/experimental/memory/__init__.py +0 -0
- lionagi/experimental/strategies/__init__.py +0 -0
- lionagi/experimental/strategies/base.py +1 -0
- lionagi/integrations/bridge/langchain_/documents.py +4 -0
- lionagi/integrations/bridge/llamaindex_/index.py +30 -0
- lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +6 -0
- lionagi/integrations/chunker/chunk.py +161 -24
- lionagi/integrations/config/oai_configs.py +34 -3
- lionagi/integrations/config/openrouter_configs.py +14 -2
- lionagi/integrations/loader/load.py +122 -21
- lionagi/integrations/loader/load_util.py +6 -77
- lionagi/integrations/provider/_mapping.py +46 -0
- lionagi/integrations/provider/litellm.py +2 -1
- lionagi/integrations/provider/mlx_service.py +16 -9
- lionagi/integrations/provider/oai.py +91 -4
- lionagi/integrations/provider/ollama.py +6 -5
- lionagi/integrations/provider/openrouter.py +115 -8
- lionagi/integrations/provider/services.py +2 -2
- lionagi/integrations/provider/transformers.py +18 -22
- lionagi/integrations/storage/__init__.py +3 -3
- lionagi/integrations/storage/neo4j.py +52 -60
- lionagi/integrations/storage/storage_util.py +44 -46
- lionagi/integrations/storage/structure_excel.py +43 -26
- lionagi/integrations/storage/to_excel.py +11 -4
- lionagi/libs/__init__.py +22 -1
- lionagi/libs/ln_api.py +75 -20
- lionagi/libs/ln_context.py +37 -0
- lionagi/libs/ln_convert.py +21 -9
- lionagi/libs/ln_func_call.py +69 -28
- lionagi/libs/ln_image.py +107 -0
- lionagi/libs/ln_nested.py +26 -11
- lionagi/libs/ln_parse.py +82 -23
- lionagi/libs/ln_queue.py +16 -0
- lionagi/libs/ln_tokenize.py +164 -0
- lionagi/libs/ln_validate.py +16 -0
- lionagi/libs/special_tokens.py +172 -0
- lionagi/libs/sys_util.py +95 -24
- lionagi/lions/coder/code_form.py +13 -0
- lionagi/lions/coder/coder.py +50 -3
- lionagi/lions/coder/util.py +30 -25
- lionagi/tests/libs/test_func_call.py +23 -21
- lionagi/tests/libs/test_nested.py +36 -21
- lionagi/tests/libs/test_parse.py +1 -1
- lionagi/tests/test_core/collections/__init__.py +0 -0
- lionagi/tests/test_core/collections/test_component.py +206 -0
- lionagi/tests/test_core/collections/test_exchange.py +138 -0
- lionagi/tests/test_core/collections/test_flow.py +145 -0
- lionagi/tests/test_core/collections/test_pile.py +171 -0
- lionagi/tests/test_core/collections/test_progression.py +129 -0
- lionagi/tests/test_core/generic/test_edge.py +67 -0
- lionagi/tests/test_core/generic/test_graph.py +96 -0
- lionagi/tests/test_core/generic/test_node.py +106 -0
- lionagi/tests/test_core/generic/test_tree_node.py +73 -0
- lionagi/tests/test_core/test_branch.py +115 -294
- lionagi/tests/test_core/test_form.py +46 -0
- lionagi/tests/test_core/test_report.py +105 -0
- lionagi/tests/test_core/test_validator.py +111 -0
- lionagi/version.py +1 -1
- lionagi-0.2.0.dist-info/LICENSE +202 -0
- lionagi-0.2.0.dist-info/METADATA +272 -0
- lionagi-0.2.0.dist-info/RECORD +240 -0
- lionagi/core/branch/base.py +0 -653
- lionagi/core/branch/branch.py +0 -474
- lionagi/core/branch/flow_mixin.py +0 -96
- lionagi/core/branch/util.py +0 -323
- lionagi/core/direct/__init__.py +0 -19
- lionagi/core/direct/cot.py +0 -123
- lionagi/core/direct/plan.py +0 -164
- lionagi/core/direct/predict.py +0 -166
- lionagi/core/direct/react.py +0 -171
- lionagi/core/direct/score.py +0 -279
- lionagi/core/direct/select.py +0 -170
- lionagi/core/direct/sentiment.py +0 -1
- lionagi/core/direct/utils.py +0 -110
- lionagi/core/direct/vote.py +0 -64
- lionagi/core/execute/base_executor.py +0 -47
- lionagi/core/flow/baseflow.py +0 -23
- lionagi/core/flow/monoflow/ReAct.py +0 -240
- lionagi/core/flow/monoflow/__init__.py +0 -9
- lionagi/core/flow/monoflow/chat.py +0 -95
- lionagi/core/flow/monoflow/chat_mixin.py +0 -253
- lionagi/core/flow/monoflow/followup.py +0 -215
- lionagi/core/flow/polyflow/__init__.py +0 -1
- lionagi/core/flow/polyflow/chat.py +0 -251
- lionagi/core/form/action_form.py +0 -26
- lionagi/core/form/field_validator.py +0 -287
- lionagi/core/form/form.py +0 -302
- lionagi/core/form/mixin.py +0 -214
- lionagi/core/form/scored_form.py +0 -13
- lionagi/core/generic/action.py +0 -26
- lionagi/core/generic/component.py +0 -532
- lionagi/core/generic/condition.py +0 -46
- lionagi/core/generic/mail.py +0 -90
- lionagi/core/generic/mailbox.py +0 -36
- lionagi/core/generic/relation.py +0 -70
- lionagi/core/generic/signal.py +0 -22
- lionagi/core/generic/structure.py +0 -362
- lionagi/core/generic/transfer.py +0 -20
- lionagi/core/generic/work.py +0 -40
- lionagi/core/graph/graph.py +0 -126
- lionagi/core/graph/tree.py +0 -190
- lionagi/core/mail/schema.py +0 -63
- lionagi/core/messages/schema.py +0 -325
- lionagi/core/tool/__init__.py +0 -5
- lionagi/core/tool/tool.py +0 -28
- lionagi/core/tool/tool_manager.py +0 -283
- lionagi/experimental/report/form.py +0 -64
- lionagi/experimental/report/report.py +0 -138
- lionagi/experimental/report/util.py +0 -47
- lionagi/experimental/tool/function_calling.py +0 -43
- lionagi/experimental/tool/manual.py +0 -66
- lionagi/experimental/tool/schema.py +0 -59
- lionagi/experimental/tool/tool_manager.py +0 -138
- lionagi/experimental/tool/util.py +0 -16
- lionagi/experimental/validator/rule.py +0 -139
- lionagi/experimental/validator/validator.py +0 -56
- lionagi/experimental/work/__init__.py +0 -10
- lionagi/experimental/work/async_queue.py +0 -54
- lionagi/experimental/work/schema.py +0 -73
- lionagi/experimental/work/work_function.py +0 -67
- lionagi/experimental/work/worker.py +0 -56
- lionagi/experimental/work2/form.py +0 -371
- lionagi/experimental/work2/report.py +0 -289
- lionagi/experimental/work2/schema.py +0 -30
- lionagi/experimental/work2/tests.py +0 -72
- lionagi/experimental/work2/work_function.py +0 -89
- lionagi/experimental/work2/worker.py +0 -12
- lionagi/integrations/bridge/llamaindex_/get_index.py +0 -294
- lionagi/tests/test_core/generic/test_component.py +0 -89
- lionagi/tests/test_core/test_base_branch.py +0 -426
- lionagi/tests/test_core/test_chat_flow.py +0 -63
- lionagi/tests/test_core/test_mail_manager.py +0 -75
- lionagi/tests/test_core/test_prompts.py +0 -51
- lionagi/tests/test_core/test_session.py +0 -254
- lionagi/tests/test_core/test_session_base_util.py +0 -313
- lionagi/tests/test_core/test_tool_manager.py +0 -95
- lionagi-0.1.2.dist-info/LICENSE +0 -9
- lionagi-0.1.2.dist-info/METADATA +0 -174
- lionagi-0.1.2.dist-info/RECORD +0 -206
- /lionagi/core/{branch → _setting}/__init__.py +0 -0
- /lionagi/core/{execute → agent/eval}/__init__.py +0 -0
- /lionagi/core/{flow → agent/learn}/__init__.py +0 -0
- /lionagi/core/{form → agent/plan}/__init__.py +0 -0
- /lionagi/core/{branch/executable_branch.py → agent/plan/plan.py} +0 -0
- /lionagi/core/{graph → director}/__init__.py +0 -0
- /lionagi/core/{messages → engine}/__init__.py +0 -0
- /lionagi/{experimental/directive/evaluator → core/engine}/sandbox_.py +0 -0
- /lionagi/{experimental/directive/evaluator → core/executor}/__init__.py +0 -0
- /lionagi/{experimental/directive/template_ → core/rule}/__init__.py +0 -0
- /lionagi/{experimental/report → core/unit/template}/__init__.py +0 -0
- /lionagi/{experimental/tool → core/validator}/__init__.py +0 -0
- /lionagi/{experimental/validator → core/work}/__init__.py +0 -0
- /lionagi/experimental/{work2 → compressor}/__init__.py +0 -0
- /lionagi/{core/flow/mono_chat_mixin.py → experimental/directive/template/__init__.py} +0 -0
- /lionagi/experimental/directive/{schema.py → template/schema.py} +0 -0
- /lionagi/experimental/{work2/util.py → evaluator/__init__.py} +0 -0
- /lionagi/experimental/{work2/work.py → knowledge/__init__.py} +0 -0
- /lionagi/{tests/libs/test_async.py → experimental/knowledge/graph.py} +0 -0
- {lionagi-0.1.2.dist-info → lionagi-0.2.0.dist-info}/WHEEL +0 -0
- {lionagi-0.1.2.dist-info → lionagi-0.2.0.dist-info}/top_level.txt +0 -0
lionagi/core/branch/util.py
DELETED
@@ -1,323 +0,0 @@
|
|
1
|
-
import contextlib
|
2
|
-
from datetime import datetime
|
3
|
-
from typing import Any
|
4
|
-
|
5
|
-
from lionagi.libs import convert, nested, func_call, dataframe
|
6
|
-
|
7
|
-
from lionagi.core.messages.schema import (
|
8
|
-
System,
|
9
|
-
Instruction,
|
10
|
-
Response,
|
11
|
-
BaseMessage,
|
12
|
-
BranchColumns,
|
13
|
-
)
|
14
|
-
|
15
|
-
CUSTOM_TYPE = dict[str, Any] | str | list[Any] | None
|
16
|
-
|
17
|
-
|
18
|
-
class MessageUtil:
|
19
|
-
|
20
|
-
@staticmethod
|
21
|
-
def create_message(
|
22
|
-
system: System | CUSTOM_TYPE = None,
|
23
|
-
instruction: Instruction | CUSTOM_TYPE = None,
|
24
|
-
context: str | dict[str, Any] | None = None,
|
25
|
-
response: Response | CUSTOM_TYPE = None,
|
26
|
-
output_fields=None,
|
27
|
-
**kwargs,
|
28
|
-
) -> BaseMessage:
|
29
|
-
"""
|
30
|
-
Creates a message object based on the input parameters, ensuring only one message role is present.
|
31
|
-
|
32
|
-
Args:
|
33
|
-
system: Information for creating a System message.
|
34
|
-
instruction: Information for creating an Instruction message.
|
35
|
-
context: Context information for the message.
|
36
|
-
response: Response data for creating a message.
|
37
|
-
**kwargs: Additional keyword arguments for message creation.
|
38
|
-
|
39
|
-
Returns:
|
40
|
-
A message object of the appropriate type based on provided inputs.
|
41
|
-
|
42
|
-
Raises:
|
43
|
-
ValueError: If more than one of the role-specific parameters are provided.
|
44
|
-
"""
|
45
|
-
if sum(func_call.lcall([system, instruction, response], bool)) != 1:
|
46
|
-
raise ValueError("Error: Message must have one and only one role.")
|
47
|
-
|
48
|
-
if isinstance(system, System):
|
49
|
-
return system
|
50
|
-
elif isinstance(instruction, Instruction):
|
51
|
-
return instruction
|
52
|
-
elif isinstance(response, Response):
|
53
|
-
return response
|
54
|
-
|
55
|
-
msg = 0
|
56
|
-
if response:
|
57
|
-
msg = Response(response=response, **kwargs)
|
58
|
-
elif instruction:
|
59
|
-
msg = Instruction(
|
60
|
-
instruction=instruction,
|
61
|
-
context=context,
|
62
|
-
output_fields=output_fields,
|
63
|
-
**kwargs,
|
64
|
-
)
|
65
|
-
elif system:
|
66
|
-
msg = System(system=system, **kwargs)
|
67
|
-
return msg
|
68
|
-
|
69
|
-
@staticmethod
|
70
|
-
def validate_messages(messages: dataframe.ln_DataFrame) -> bool:
|
71
|
-
"""
|
72
|
-
Validates the format and content of a DataFrame containing messages.
|
73
|
-
|
74
|
-
Args:
|
75
|
-
messages: A DataFrame with message information.
|
76
|
-
|
77
|
-
Returns:
|
78
|
-
True if the messages DataFrame is correctly formatted, False otherwise.
|
79
|
-
|
80
|
-
Raises:
|
81
|
-
ValueError: If the DataFrame does not match expected schema or content requirements.
|
82
|
-
"""
|
83
|
-
|
84
|
-
if list(messages.columns) != BranchColumns.COLUMNS.value:
|
85
|
-
raise ValueError("Invalid messages dataframe. Unmatched columns.")
|
86
|
-
if messages.isnull().values.any():
|
87
|
-
raise ValueError("Invalid messages dataframe. Cannot have null.")
|
88
|
-
if any(
|
89
|
-
role not in ["system", "user", "assistant"]
|
90
|
-
for role in messages["role"].unique()
|
91
|
-
):
|
92
|
-
raise ValueError(
|
93
|
-
'Invalid messages dataframe. Cannot have role other than ["system", "user", "assistant"].'
|
94
|
-
)
|
95
|
-
for cont in messages["content"]:
|
96
|
-
if cont.startswith("Sender"):
|
97
|
-
cont = cont.split(":", 1)[1]
|
98
|
-
try:
|
99
|
-
convert.to_dict(cont)
|
100
|
-
except:
|
101
|
-
raise ValueError(
|
102
|
-
"Invalid messages dataframe. Content expect json string."
|
103
|
-
)
|
104
|
-
return True
|
105
|
-
|
106
|
-
@staticmethod
|
107
|
-
def sign_message(
|
108
|
-
messages: dataframe.ln_DataFrame, sender: str
|
109
|
-
) -> dataframe.ln_DataFrame:
|
110
|
-
"""
|
111
|
-
Appends a sender prefix to the 'content' field of each message in a DataFrame.
|
112
|
-
|
113
|
-
Args:
|
114
|
-
messages: A DataFrame containing message data.
|
115
|
-
sender: The identifier of the sender to prefix to message contents.
|
116
|
-
|
117
|
-
Returns:
|
118
|
-
A DataFrame with sender-prefixed message contents.
|
119
|
-
|
120
|
-
Raises:
|
121
|
-
ValueError: If the sender is None or the value is 'none'.
|
122
|
-
"""
|
123
|
-
|
124
|
-
if sender is None or convert.strip_lower(sender) == "none":
|
125
|
-
raise ValueError("sender cannot be None")
|
126
|
-
df = convert.to_df(messages)
|
127
|
-
|
128
|
-
for i in df.index:
|
129
|
-
if not df.loc[i, "content"].startswith("Sender"):
|
130
|
-
df.loc[i, "content"] = f"Sender {sender}: {df.loc[i, 'content']}"
|
131
|
-
else:
|
132
|
-
content = df.loc[i, "content"].split(":", 1)[1]
|
133
|
-
df.loc[i, "content"] = f"Sender {sender}: {content}"
|
134
|
-
|
135
|
-
return convert.to_df(df)
|
136
|
-
|
137
|
-
@staticmethod
|
138
|
-
def filter_messages_by(
|
139
|
-
messages: dataframe.ln_DataFrame,
|
140
|
-
role: str | None = None,
|
141
|
-
sender: str | None = None,
|
142
|
-
start_time: datetime | None = None,
|
143
|
-
end_time: datetime | None = None,
|
144
|
-
content_keywords: str | list[str] | None = None,
|
145
|
-
case_sensitive: bool = False,
|
146
|
-
) -> dataframe.ln_DataFrame:
|
147
|
-
"""
|
148
|
-
Filters messages in a DataFrame based on specified criteria.
|
149
|
-
|
150
|
-
Args:
|
151
|
-
messages: The DataFrame to filter.
|
152
|
-
role: The role to filter by.
|
153
|
-
sender: The sender to filter by.
|
154
|
-
start_time: The minimum timestamp for messages.
|
155
|
-
end_time: The maximum timestamp for messages.
|
156
|
-
content_keywords: Keywords to look for in message content.
|
157
|
-
case_sensitive: Whether the keyword search should be case-sensitive.
|
158
|
-
|
159
|
-
Returns:
|
160
|
-
A filtered DataFrame based on the specified criteria.
|
161
|
-
"""
|
162
|
-
|
163
|
-
try:
|
164
|
-
outs = messages.copy()
|
165
|
-
|
166
|
-
if content_keywords:
|
167
|
-
outs = MessageUtil.search_keywords(
|
168
|
-
outs, keywords=content_keywords, case_sensitive=case_sensitive
|
169
|
-
)
|
170
|
-
|
171
|
-
outs = outs[outs["role"] == role] if role else outs
|
172
|
-
outs = outs[outs["sender"] == sender] if sender else outs
|
173
|
-
outs = outs[outs["timestamp"] > start_time] if start_time else outs
|
174
|
-
outs = outs[outs["timestamp"] < end_time] if end_time else outs
|
175
|
-
|
176
|
-
return convert.to_df(outs)
|
177
|
-
|
178
|
-
except Exception as e:
|
179
|
-
raise ValueError(f"Error in filtering messages: {e}") from e
|
180
|
-
|
181
|
-
@staticmethod
|
182
|
-
def remove_message(messages: dataframe.ln_DataFrame, node_id: str) -> bool:
|
183
|
-
"""
|
184
|
-
Removes a message from the DataFrame based on its node ID.
|
185
|
-
|
186
|
-
Args:
|
187
|
-
messages: The DataFrame containing messages.
|
188
|
-
node_id: The unique identifier of the message to be removed.
|
189
|
-
|
190
|
-
Returns:
|
191
|
-
If any messages are removed.
|
192
|
-
|
193
|
-
Examples:
|
194
|
-
>>> messages = dataframe.ln_DataFrame([...])
|
195
|
-
>>> updated_messages = MessageUtil.remove_message(messages, "node_id_123")
|
196
|
-
"""
|
197
|
-
|
198
|
-
initial_length = len(messages)
|
199
|
-
messages.drop(messages[messages["node_id"] == node_id].index, inplace=True)
|
200
|
-
messages.reset_index(drop=True, inplace=True)
|
201
|
-
|
202
|
-
return len(messages) < initial_length
|
203
|
-
|
204
|
-
@staticmethod
|
205
|
-
def get_message_rows(
|
206
|
-
messages: dataframe.ln_DataFrame,
|
207
|
-
sender: str | None = None,
|
208
|
-
role: str | None = None,
|
209
|
-
n: int = 1,
|
210
|
-
sign_: bool = False,
|
211
|
-
from_: str = "front",
|
212
|
-
) -> dataframe.ln_DataFrame:
|
213
|
-
"""
|
214
|
-
Retrieves a specified number of message rows based on sender and role.
|
215
|
-
|
216
|
-
Args:
|
217
|
-
messages: The DataFrame containing messages.
|
218
|
-
sender: Filter messages by the sender.
|
219
|
-
role: Filter messages by the role.
|
220
|
-
n: The number of messages to retrieve.
|
221
|
-
sign_: If True, sign the message with the sender.
|
222
|
-
from_: Specify retrieval from the 'front' or 'last' of the DataFrame.
|
223
|
-
|
224
|
-
Returns:
|
225
|
-
A DataFrame containing the filtered messages.
|
226
|
-
"""
|
227
|
-
|
228
|
-
outs = ""
|
229
|
-
|
230
|
-
if from_ == "last":
|
231
|
-
if sender is None and role is None:
|
232
|
-
outs = messages.iloc[-n:]
|
233
|
-
elif sender and role:
|
234
|
-
outs = messages[
|
235
|
-
(messages["sender"] == sender) & (messages["role"] == role)
|
236
|
-
].iloc[-n:]
|
237
|
-
|
238
|
-
elif sender:
|
239
|
-
outs = messages[messages["sender"] == sender].iloc[-n:]
|
240
|
-
else:
|
241
|
-
outs = messages[messages["role"] == role].iloc[-n:]
|
242
|
-
|
243
|
-
elif from_ == "front":
|
244
|
-
if sender is None and role is None:
|
245
|
-
outs = messages.iloc[:n]
|
246
|
-
elif sender and role:
|
247
|
-
outs = messages[
|
248
|
-
(messages["sender"] == sender) & (messages["role"] == role)
|
249
|
-
].iloc[:n]
|
250
|
-
elif sender:
|
251
|
-
outs = messages[messages["sender"] == sender].iloc[:n]
|
252
|
-
else:
|
253
|
-
outs = messages[messages["role"] == role].iloc[:n]
|
254
|
-
|
255
|
-
return MessageUtil.sign_message(outs, sender) if sign_ else outs
|
256
|
-
|
257
|
-
@staticmethod
|
258
|
-
def extend(
|
259
|
-
df1: dataframe.ln_DataFrame, df2: dataframe.ln_DataFrame, **kwargs
|
260
|
-
) -> dataframe.ln_DataFrame:
|
261
|
-
"""
|
262
|
-
Extends a DataFrame with another DataFrame's rows, ensuring no duplicate 'node_id'.
|
263
|
-
|
264
|
-
Args:
|
265
|
-
df1: The primary DataFrame.
|
266
|
-
df2: The DataFrame to merge with the primary DataFrame.
|
267
|
-
**kwargs: Additional keyword arguments for `drop_duplicates`.
|
268
|
-
|
269
|
-
Returns:
|
270
|
-
A DataFrame combined from df1 and df2 with duplicates removed based on 'node_id'.
|
271
|
-
|
272
|
-
Examples:
|
273
|
-
>>> df_main = dataframe.ln_DataFrame([...])
|
274
|
-
>>> df_additional = dataframe.ln_DataFrame([...])
|
275
|
-
>>> combined_df = MessageUtil.extend(df_main, df_additional, keep='first')
|
276
|
-
"""
|
277
|
-
|
278
|
-
MessageUtil.validate_messages(df2)
|
279
|
-
try:
|
280
|
-
if len(df2.dropna(how="all")) > 0 and len(df1.dropna(how="all")) > 0:
|
281
|
-
df = convert.to_df([df1, df2])
|
282
|
-
df.drop_duplicates(
|
283
|
-
inplace=True, subset=["node_id"], keep="first", **kwargs
|
284
|
-
)
|
285
|
-
return convert.to_df(df)
|
286
|
-
except Exception as e:
|
287
|
-
raise ValueError(f"Error in extending messages: {e}") from e
|
288
|
-
|
289
|
-
@staticmethod
|
290
|
-
def to_markdown_string(messages: dataframe.ln_DataFrame) -> str:
|
291
|
-
"""
|
292
|
-
Converts messages in a DataFrame to a Markdown-formatted string for easy reading.
|
293
|
-
|
294
|
-
Args:
|
295
|
-
messages: A DataFrame containing messages with columns for 'role' and 'content'.
|
296
|
-
|
297
|
-
Returns:
|
298
|
-
A string formatted in Markdown, where each message's content is presented
|
299
|
-
according to its role in a readable format.
|
300
|
-
"""
|
301
|
-
|
302
|
-
answers = []
|
303
|
-
for _, i in messages.iterrows():
|
304
|
-
content = convert.to_dict(i.content)
|
305
|
-
|
306
|
-
if i.role == "assistant":
|
307
|
-
with contextlib.suppress(Exception):
|
308
|
-
a = nested.nget(content, ["action_response", "func"])
|
309
|
-
b = nested.nget(content, ["action_response", "arguments"])
|
310
|
-
c = nested.nget(content, ["action_response", "output"])
|
311
|
-
if a is not None:
|
312
|
-
answers.extend(
|
313
|
-
(f"Function: {a}", f"Arguments: {b}", f"Output: {c}")
|
314
|
-
)
|
315
|
-
else:
|
316
|
-
answers.append(nested.nget(content, ["assistant_response"]))
|
317
|
-
elif i.role == "user":
|
318
|
-
with contextlib.suppress(Exception):
|
319
|
-
answers.append(nested.nget(content, ["instruction"]))
|
320
|
-
else:
|
321
|
-
with contextlib.suppress(Exception):
|
322
|
-
answers.append(nested.nget(content, ["system_info"]))
|
323
|
-
return "\n".join(answers)
|
lionagi/core/direct/__init__.py
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
from .predict import predict
|
2
|
-
from .select import select
|
3
|
-
from .score import score
|
4
|
-
from .react import react
|
5
|
-
from .vote import vote
|
6
|
-
from .plan import plan
|
7
|
-
from .cot import chain_of_thoughts, chain_of_react
|
8
|
-
|
9
|
-
|
10
|
-
__all__ = [
|
11
|
-
"predict",
|
12
|
-
"select",
|
13
|
-
"score",
|
14
|
-
"vote",
|
15
|
-
"react",
|
16
|
-
"plan",
|
17
|
-
"chain_of_thoughts",
|
18
|
-
"chain_of_react",
|
19
|
-
]
|
lionagi/core/direct/cot.py
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
from lionagi.libs import convert
|
2
|
-
|
3
|
-
from lionagi.core.direct.predict import predict
|
4
|
-
from lionagi.core.direct.plan import plan
|
5
|
-
from lionagi.core.direct.react import react
|
6
|
-
|
7
|
-
from .utils import _process_tools
|
8
|
-
|
9
|
-
|
10
|
-
async def chain_of_thoughts(
|
11
|
-
sentence=None,
|
12
|
-
branch=None,
|
13
|
-
instruction=None,
|
14
|
-
reason=False,
|
15
|
-
confidence_score=False,
|
16
|
-
num_steps=3,
|
17
|
-
directive_kwargs={},
|
18
|
-
return_branch=False,
|
19
|
-
**kwargs,
|
20
|
-
):
|
21
|
-
|
22
|
-
out_, outs, answer, reasons, confidence_score = "", [], "", [], 0
|
23
|
-
if branch is not None:
|
24
|
-
out_ = await plan(
|
25
|
-
sentence,
|
26
|
-
branch=branch,
|
27
|
-
instruction=instruction,
|
28
|
-
num_steps=num_steps,
|
29
|
-
**kwargs,
|
30
|
-
)
|
31
|
-
else:
|
32
|
-
out_, branch = await plan(
|
33
|
-
sentence,
|
34
|
-
instruction=instruction,
|
35
|
-
branch=branch,
|
36
|
-
num_steps=num_steps,
|
37
|
-
return_branch=True,
|
38
|
-
**kwargs,
|
39
|
-
)
|
40
|
-
|
41
|
-
for i in range(len(out_.plan)):
|
42
|
-
_out = await predict(
|
43
|
-
branch=branch,
|
44
|
-
instruction=out_.plan[f"step_{i+1}"],
|
45
|
-
reason=reason,
|
46
|
-
confidence_score=confidence_score,
|
47
|
-
**directive_kwargs,
|
48
|
-
)
|
49
|
-
answer += _out.answer
|
50
|
-
if reason:
|
51
|
-
reasons.append(_out.reason)
|
52
|
-
if confidence_score:
|
53
|
-
confidence_score += _out.confidence_score
|
54
|
-
outs.append(_out)
|
55
|
-
|
56
|
-
setattr(out_, "chain_output", outs)
|
57
|
-
setattr(out_, "chain_answer", answer)
|
58
|
-
|
59
|
-
if reason:
|
60
|
-
setattr(out_, "chain_reasons", reasons)
|
61
|
-
if confidence_score:
|
62
|
-
setattr(out_, "chain_confidence_score", confidence_score / len(outs))
|
63
|
-
|
64
|
-
if return_branch:
|
65
|
-
return out_, branch
|
66
|
-
|
67
|
-
return out_
|
68
|
-
|
69
|
-
|
70
|
-
async def chain_of_react(
|
71
|
-
sentence=None,
|
72
|
-
branch=None,
|
73
|
-
instruction=None,
|
74
|
-
num_steps=3,
|
75
|
-
tools=None,
|
76
|
-
directive_system=None,
|
77
|
-
directive_kwargs={},
|
78
|
-
return_branch=False,
|
79
|
-
**kwargs,
|
80
|
-
):
|
81
|
-
out_, outs, reasons, actions, action_responses = "", [], [], [], []
|
82
|
-
if branch is not None:
|
83
|
-
out_ = await plan(
|
84
|
-
sentence,
|
85
|
-
branch=branch,
|
86
|
-
instruction=instruction,
|
87
|
-
num_steps=num_steps,
|
88
|
-
**kwargs,
|
89
|
-
)
|
90
|
-
else:
|
91
|
-
out_, branch = await plan(
|
92
|
-
sentence,
|
93
|
-
instruction=instruction,
|
94
|
-
branch=branch,
|
95
|
-
num_steps=num_steps,
|
96
|
-
return_branch=True,
|
97
|
-
**kwargs,
|
98
|
-
)
|
99
|
-
|
100
|
-
_process_tools(tools, branch)
|
101
|
-
|
102
|
-
for i in range(len(out_.plan)):
|
103
|
-
_out = await react(
|
104
|
-
branch=branch,
|
105
|
-
system=directive_system,
|
106
|
-
instruction=out_.plan[f"step_{i+1}"],
|
107
|
-
**directive_kwargs,
|
108
|
-
)
|
109
|
-
outs.append(_out)
|
110
|
-
reasons.append(_out.reason)
|
111
|
-
actions.append(_out.actions)
|
112
|
-
if _out.action_needed:
|
113
|
-
action_responses.append(_out.action_response)
|
114
|
-
|
115
|
-
setattr(out_, "chain_output", convert.to_list(outs))
|
116
|
-
setattr(out_, "chain_reason", convert.to_list(reasons))
|
117
|
-
setattr(out_, "chain_actions", convert.to_list(actions))
|
118
|
-
setattr(out_, "chain_action_response", convert.to_list(action_responses))
|
119
|
-
|
120
|
-
if return_branch:
|
121
|
-
return out_, branch
|
122
|
-
|
123
|
-
return out_
|
lionagi/core/direct/plan.py
DELETED
@@ -1,164 +0,0 @@
|
|
1
|
-
# plan.py
|
2
|
-
|
3
|
-
from lionagi.libs import func_call, ParseUtil
|
4
|
-
from lionagi.integrations.bridge.pydantic_.pydantic_bridge import Field
|
5
|
-
from lionagi.core.form.scored_form import ScoredForm
|
6
|
-
from lionagi.core.branch.branch import Branch
|
7
|
-
|
8
|
-
|
9
|
-
class PlanTemplate(ScoredForm):
|
10
|
-
template_name: str = "default_plan"
|
11
|
-
sentence: str | list | dict = Field(
|
12
|
-
default_factory=str,
|
13
|
-
description="the given sentence(s) or context to generate a plan for",
|
14
|
-
)
|
15
|
-
plan: dict | str = Field(
|
16
|
-
default_factory=dict,
|
17
|
-
description="the generated step by step plan, return as a dictionary following {step_n: {plan: ..., reason: ...}} format",
|
18
|
-
)
|
19
|
-
signature: str = "sentence -> plan"
|
20
|
-
|
21
|
-
def __init__(
|
22
|
-
self,
|
23
|
-
sentence=None,
|
24
|
-
instruction=None,
|
25
|
-
confidence_score=False,
|
26
|
-
reason=False,
|
27
|
-
num_step=3,
|
28
|
-
**kwargs,
|
29
|
-
):
|
30
|
-
super().__init__(**kwargs)
|
31
|
-
|
32
|
-
self.sentence = sentence
|
33
|
-
self.task = f"Generate a {num_step}_step plan based on the given context. Instruction: {instruction}."
|
34
|
-
|
35
|
-
if reason:
|
36
|
-
self.output_fields.append("reason")
|
37
|
-
|
38
|
-
if confidence_score:
|
39
|
-
self.output_fields.append("confidence_score")
|
40
|
-
|
41
|
-
|
42
|
-
async def _plan(
|
43
|
-
sentence,
|
44
|
-
*,
|
45
|
-
instruction=None,
|
46
|
-
branch=None,
|
47
|
-
confidence_score=False,
|
48
|
-
reason=False,
|
49
|
-
retries=2,
|
50
|
-
delay=0.5,
|
51
|
-
backoff_factor=2,
|
52
|
-
default_value=None,
|
53
|
-
timeout=None,
|
54
|
-
branch_name=None,
|
55
|
-
system=None,
|
56
|
-
messages=None,
|
57
|
-
service=None,
|
58
|
-
sender=None,
|
59
|
-
llmconfig=None,
|
60
|
-
tools=None,
|
61
|
-
datalogger=None,
|
62
|
-
persist_path=None,
|
63
|
-
tool_manager=None,
|
64
|
-
return_branch=False,
|
65
|
-
**kwargs,
|
66
|
-
):
|
67
|
-
if "temperature" not in kwargs:
|
68
|
-
kwargs["temperature"] = 0.1
|
69
|
-
|
70
|
-
instruction = instruction or ""
|
71
|
-
|
72
|
-
branch = branch or Branch(
|
73
|
-
name=branch_name,
|
74
|
-
system=system,
|
75
|
-
messages=messages,
|
76
|
-
service=service,
|
77
|
-
sender=sender,
|
78
|
-
llmconfig=llmconfig,
|
79
|
-
tools=tools,
|
80
|
-
datalogger=datalogger,
|
81
|
-
persist_path=persist_path,
|
82
|
-
tool_manager=tool_manager,
|
83
|
-
)
|
84
|
-
|
85
|
-
_template = PlanTemplate(
|
86
|
-
sentence=sentence,
|
87
|
-
instruction=instruction,
|
88
|
-
confidence_score=confidence_score,
|
89
|
-
reason=reason,
|
90
|
-
)
|
91
|
-
|
92
|
-
await func_call.rcall(
|
93
|
-
branch.chat,
|
94
|
-
form=_template,
|
95
|
-
retries=retries,
|
96
|
-
delay=delay,
|
97
|
-
backoff_factor=backoff_factor,
|
98
|
-
default=default_value,
|
99
|
-
timeout=timeout,
|
100
|
-
**kwargs,
|
101
|
-
)
|
102
|
-
|
103
|
-
_template.plan = ParseUtil.fuzzy_parse_json(_template.plan)
|
104
|
-
|
105
|
-
return (_template, branch) if return_branch else _template
|
106
|
-
|
107
|
-
|
108
|
-
async def plan(
|
109
|
-
sentence,
|
110
|
-
*,
|
111
|
-
instruction=None,
|
112
|
-
num_instances=1,
|
113
|
-
branch=None,
|
114
|
-
confidence_score=False,
|
115
|
-
reason=False,
|
116
|
-
retries=2,
|
117
|
-
delay=0.5,
|
118
|
-
backoff_factor=2,
|
119
|
-
default_value=None,
|
120
|
-
timeout=None,
|
121
|
-
branch_name=None,
|
122
|
-
system=None,
|
123
|
-
messages=None,
|
124
|
-
service=None,
|
125
|
-
sender=None,
|
126
|
-
llmconfig=None,
|
127
|
-
tools=None,
|
128
|
-
datalogger=None,
|
129
|
-
persist_path=None,
|
130
|
-
tool_manager=None,
|
131
|
-
return_branch=False,
|
132
|
-
**kwargs,
|
133
|
-
):
|
134
|
-
async def _inner(i=0):
|
135
|
-
return await _plan(
|
136
|
-
sentence=sentence,
|
137
|
-
instruction=instruction,
|
138
|
-
branch=branch,
|
139
|
-
confidence_score=confidence_score,
|
140
|
-
reason=reason,
|
141
|
-
retries=retries,
|
142
|
-
delay=delay,
|
143
|
-
backoff_factor=backoff_factor,
|
144
|
-
default_value=default_value,
|
145
|
-
timeout=timeout,
|
146
|
-
branch_name=branch_name,
|
147
|
-
system=system,
|
148
|
-
messages=messages,
|
149
|
-
service=service,
|
150
|
-
sender=sender,
|
151
|
-
llmconfig=llmconfig,
|
152
|
-
tools=tools,
|
153
|
-
datalogger=datalogger,
|
154
|
-
persist_path=persist_path,
|
155
|
-
tool_manager=tool_manager,
|
156
|
-
return_branch=return_branch,
|
157
|
-
**kwargs,
|
158
|
-
)
|
159
|
-
|
160
|
-
if num_instances == 1:
|
161
|
-
return await _inner()
|
162
|
-
|
163
|
-
elif num_instances > 1:
|
164
|
-
return await func_call.alcall(range(num_instances), _inner)
|