lionagi 0.1.2__py3-none-any.whl → 0.2.1__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 +76 -0
- lionagi/core/work/work_function.py +101 -0
- lionagi/core/work/work_queue.py +103 -0
- lionagi/core/work/worker.py +258 -0
- lionagi/core/work/worklog.py +120 -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.1.dist-info/LICENSE +202 -0
- lionagi-0.2.1.dist-info/METADATA +272 -0
- lionagi-0.2.1.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.1.dist-info}/WHEEL +0 -0
- {lionagi-0.1.2.dist-info → lionagi-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,23 +1,52 @@
|
|
1
1
|
import contextlib
|
2
2
|
from lionagi.libs import convert, AsyncUtil, ParseUtil
|
3
|
-
from lionagi.core.generic import
|
4
|
-
from lionagi.core.
|
5
|
-
from lionagi.core.
|
3
|
+
from lionagi.core.generic.edge import Edge
|
4
|
+
from lionagi.core.action import ActionNode
|
5
|
+
from lionagi.core.mail.mail import Mail
|
6
|
+
from lionagi.core.message import System, Instruction
|
7
|
+
from lionagi.core.collections import Pile, Progression
|
6
8
|
|
7
|
-
from lionagi.core.
|
8
|
-
from lionagi.core.
|
9
|
+
from lionagi.core.session.branch import Branch
|
10
|
+
from lionagi.core.executor.base_executor import BaseExecutor
|
9
11
|
|
10
12
|
|
11
13
|
class BranchExecutor(Branch, BaseExecutor):
|
12
14
|
|
15
|
+
def __init__(
|
16
|
+
self,
|
17
|
+
context=None,
|
18
|
+
verbose=True,
|
19
|
+
system=None,
|
20
|
+
user=None,
|
21
|
+
messages=None,
|
22
|
+
progress=None,
|
23
|
+
tool_manager=None,
|
24
|
+
tools=None,
|
25
|
+
imodel=None,
|
26
|
+
**kwargs,
|
27
|
+
):
|
28
|
+
super().__init__(
|
29
|
+
system=system,
|
30
|
+
user=user,
|
31
|
+
messages=messages,
|
32
|
+
progress=progress,
|
33
|
+
tool_manager=tool_manager,
|
34
|
+
tools=tools,
|
35
|
+
imodel=imodel,
|
36
|
+
**kwargs,
|
37
|
+
)
|
38
|
+
self.context = context
|
39
|
+
self.verbose = verbose
|
40
|
+
|
13
41
|
async def forward(self) -> None:
|
14
42
|
"""
|
15
43
|
Forwards the execution by processing all pending incoming mails in each branch. Depending on the category of the mail,
|
16
44
|
it processes starts, nodes, node lists, conditions, or ends, accordingly executing different functions.
|
17
45
|
"""
|
18
|
-
for key in list(self.pending_ins.keys()):
|
19
|
-
while self.pending_ins[key]:
|
20
|
-
|
46
|
+
for key in list(self.mailbox.pending_ins.keys()):
|
47
|
+
while self.mailbox.pending_ins[key].size() > 0:
|
48
|
+
mail_id = self.mailbox.pending_ins[key].popleft()
|
49
|
+
mail = self.mailbox.pile.pop(mail_id)
|
21
50
|
if mail.category == "start":
|
22
51
|
self._process_start(mail)
|
23
52
|
elif mail.category == "node":
|
@@ -25,9 +54,11 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
25
54
|
elif mail.category == "node_list":
|
26
55
|
self._process_node_list(mail)
|
27
56
|
elif mail.category == "condition":
|
28
|
-
self._process_condition(mail)
|
57
|
+
await self._process_condition(mail)
|
29
58
|
elif mail.category == "end":
|
30
59
|
self._process_end(mail)
|
60
|
+
if self.mailbox.pending_ins[key].size() == 0:
|
61
|
+
self.mailbox.pending_ins.pop(key)
|
31
62
|
|
32
63
|
async def execute(self, refresh_time=1) -> None:
|
33
64
|
"""
|
@@ -40,60 +71,57 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
40
71
|
await self.forward()
|
41
72
|
await AsyncUtil.sleep(refresh_time)
|
42
73
|
|
43
|
-
async def _process_node(self, mail:
|
74
|
+
async def _process_node(self, mail: Mail):
|
44
75
|
"""
|
45
76
|
Processes a single node based on the node type specified in the mail's package. It handles different types of nodes such as System,
|
46
77
|
Instruction, ActionNode, and generic nodes through separate processes.
|
47
78
|
|
48
79
|
Args:
|
49
|
-
mail (
|
80
|
+
mail (Mail): The mail containing the node to be processed along with associated details.
|
50
81
|
|
51
82
|
Raises:
|
52
83
|
ValueError: If an invalid mail is encountered or the process encounters errors.
|
53
84
|
"""
|
54
|
-
|
55
|
-
|
85
|
+
node = mail.package.package
|
86
|
+
if isinstance(node, System):
|
87
|
+
self._system_process(node, verbose=self.verbose)
|
56
88
|
self.send(
|
57
|
-
mail.
|
58
|
-
"node_id",
|
59
|
-
|
89
|
+
recipient=mail.sender,
|
90
|
+
category="node_id",
|
91
|
+
package=node.ln_id,
|
92
|
+
request_source=self.ln_id,
|
60
93
|
)
|
61
94
|
|
62
|
-
elif isinstance(
|
63
|
-
await self._instruction_process(
|
64
|
-
mail.package["package"], verbose=self.verbose
|
65
|
-
)
|
95
|
+
elif isinstance(node, Instruction):
|
96
|
+
await self._instruction_process(node, verbose=self.verbose)
|
66
97
|
self.send(
|
67
|
-
mail.
|
68
|
-
"node_id",
|
69
|
-
|
98
|
+
recipient=mail.sender,
|
99
|
+
category="node_id",
|
100
|
+
package=node.ln_id,
|
101
|
+
request_source=self.ln_id,
|
70
102
|
)
|
71
103
|
|
72
|
-
elif isinstance(
|
73
|
-
await self._action_process(
|
104
|
+
elif isinstance(node, ActionNode):
|
105
|
+
await self._action_process(node, verbose=self.verbose)
|
74
106
|
self.send(
|
75
|
-
mail.
|
76
|
-
"node_id",
|
77
|
-
|
78
|
-
|
79
|
-
"package": mail.package["package"].instruction.id_,
|
80
|
-
},
|
107
|
+
recipient=mail.sender,
|
108
|
+
category="node_id",
|
109
|
+
package=node.instruction.ln_id,
|
110
|
+
request_source=self.ln_id,
|
81
111
|
)
|
82
112
|
else:
|
83
113
|
try:
|
84
|
-
await self._agent_process(
|
114
|
+
await self._agent_process(node, verbose=self.verbose)
|
85
115
|
self.send(
|
86
|
-
mail.
|
87
|
-
"node_id",
|
88
|
-
|
89
|
-
|
90
|
-
"package": mail.package["package"].id_,
|
91
|
-
},
|
116
|
+
recipient=mail.sender,
|
117
|
+
category="node_id",
|
118
|
+
package=node.ln_id,
|
119
|
+
request_source=self.ln_id,
|
92
120
|
)
|
93
121
|
except:
|
94
122
|
raise ValueError(f"Invalid mail to process. Mail:{mail}")
|
95
123
|
|
96
|
-
def _process_node_list(self, mail:
|
124
|
+
def _process_node_list(self, mail: Mail):
|
97
125
|
"""
|
98
126
|
Processes a list of nodes provided in the mail, but currently only sends an end signal as multiple path selection is not supported.
|
99
127
|
|
@@ -103,28 +131,29 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
103
131
|
Raises:
|
104
132
|
ValueError: When trying to process multiple paths which is currently unsupported.
|
105
133
|
"""
|
106
|
-
self.send(mail.
|
134
|
+
self.send(mail.sender, category="end", package="end", request_source=self.ln_id)
|
107
135
|
self.execute_stop = True
|
108
|
-
raise ValueError("Multiple path selection is
|
136
|
+
raise ValueError("Multiple path selection is not supported in BranchExecutor")
|
109
137
|
|
110
|
-
def _process_condition(self, mail:
|
138
|
+
async def _process_condition(self, mail: Mail):
|
111
139
|
"""
|
112
140
|
Processes a condition associated with an edge based on the mail's package, setting up the result of the condition check.
|
113
141
|
|
114
142
|
Args:
|
115
143
|
mail (BaseMail): The mail containing the condition to be processed.
|
116
144
|
"""
|
117
|
-
|
118
|
-
check_result =
|
145
|
+
edge: Edge = mail.package.package
|
146
|
+
check_result = await edge.check_condition(self)
|
119
147
|
back_mail = {
|
120
|
-
"from": self.
|
121
|
-
"edge_id":
|
148
|
+
"from": self.ln_id,
|
149
|
+
"edge_id": edge.ln_id,
|
122
150
|
"check_result": check_result,
|
123
151
|
}
|
124
152
|
self.send(
|
125
|
-
mail.
|
126
|
-
"condition",
|
127
|
-
|
153
|
+
recipient=mail.sender,
|
154
|
+
category="condition",
|
155
|
+
package=back_mail,
|
156
|
+
request_source=self.ln_id,
|
128
157
|
)
|
129
158
|
|
130
159
|
def _system_process(self, system: System, verbose=True, context_verbose=False):
|
@@ -177,21 +206,22 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
177
206
|
)
|
178
207
|
|
179
208
|
if self.context:
|
180
|
-
|
181
|
-
|
209
|
+
result = await self.chat(
|
210
|
+
instruction=instruction.instruct, context=self.context, **kwargs
|
211
|
+
)
|
182
212
|
self.context = None
|
213
|
+
else:
|
214
|
+
result = await self.chat(instruction=instruction.instruct, **kwargs)
|
215
|
+
# instruction._add_context(context=self.context)
|
216
|
+
# self.context_log.append(self.context)
|
217
|
+
# self.context = None
|
183
218
|
|
184
|
-
result = await self.chat(instruction, **kwargs)
|
185
219
|
with contextlib.suppress(Exception):
|
186
220
|
result = ParseUtil.fuzzy_parse_json(result)
|
187
|
-
if "
|
188
|
-
result = result["
|
189
|
-
if verbose
|
190
|
-
display(
|
191
|
-
Markdown(
|
192
|
-
f"{self.last_assistant_response.sender}: {convert.to_str(result)}"
|
193
|
-
)
|
194
|
-
)
|
221
|
+
if "assistant_response" in result.keys():
|
222
|
+
result = result["assistant_response"]
|
223
|
+
if verbose:
|
224
|
+
display(Markdown(f"assistant {self.ln_id}: {convert.to_str(result)}"))
|
195
225
|
print("-----------------------------------------------------")
|
196
226
|
|
197
227
|
self.execution_responses.append(result)
|
@@ -209,10 +239,10 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
209
239
|
SysUtil.check_import("IPython")
|
210
240
|
from IPython.display import Markdown, display
|
211
241
|
|
212
|
-
try:
|
213
|
-
|
214
|
-
except:
|
215
|
-
|
242
|
+
# try:
|
243
|
+
# func = getattr(self, action.action)
|
244
|
+
# except:
|
245
|
+
# raise ValueError(f"{action.action} is not a valid action")
|
216
246
|
|
217
247
|
if verbose:
|
218
248
|
display(
|
@@ -221,27 +251,33 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
221
251
|
)
|
222
252
|
)
|
223
253
|
|
224
|
-
if action.tools:
|
225
|
-
|
226
|
-
if self.context:
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
254
|
+
# if action.tools:
|
255
|
+
# self.register_tools(action.tools)
|
256
|
+
# if self.context:
|
257
|
+
# result = await self.direct(
|
258
|
+
# action.directive,
|
259
|
+
# instruction=action.instruction.instruct,
|
260
|
+
# context=self.context,
|
261
|
+
# tools=action.tools,
|
262
|
+
# **action.directive_kwargs,
|
263
|
+
# )
|
264
|
+
result = await action.invoke(branch=self, context=self.context)
|
265
|
+
self.context = None
|
266
|
+
# else:
|
267
|
+
# result = await self.direct(
|
268
|
+
# action.directive,
|
269
|
+
# instruction=action.instruction.content,
|
270
|
+
# tools=action.tools,
|
271
|
+
# **action.directive_kwargs
|
272
|
+
# )
|
238
273
|
|
239
|
-
if verbose
|
240
|
-
|
241
|
-
Markdown(
|
242
|
-
|
243
|
-
)
|
244
|
-
|
274
|
+
if verbose:
|
275
|
+
if action.directive == "chat":
|
276
|
+
display(Markdown(f"assistant {self.ln_id}: {convert.to_str(result)}"))
|
277
|
+
else:
|
278
|
+
display(Markdown(f"assistant {self.ln_id}:\n"))
|
279
|
+
for k, v in result.work_fields.items():
|
280
|
+
display(Markdown(f"{k}: \n{v}\n"))
|
245
281
|
print("-----------------------------------------------------")
|
246
282
|
|
247
283
|
self.execution_responses.append(result)
|
@@ -254,7 +290,7 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
254
290
|
agent: The agent to process.
|
255
291
|
verbose (bool): A flag indicating whether to provide verbose output (default: True).
|
256
292
|
"""
|
257
|
-
context =
|
293
|
+
context = [msg["content"] for msg in self.to_chat_messages()]
|
258
294
|
if verbose:
|
259
295
|
print("*****************************************************")
|
260
296
|
result = await agent.execute(context)
|
@@ -262,12 +298,7 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
262
298
|
if verbose:
|
263
299
|
print("*****************************************************")
|
264
300
|
|
265
|
-
|
266
|
-
|
267
|
-
if isinstance(result, DataFrame):
|
268
|
-
self.context = list(result["content"])
|
269
|
-
else:
|
270
|
-
self.context = result
|
301
|
+
self.context = result
|
271
302
|
self.execution_responses.append(result)
|
272
303
|
|
273
304
|
def _process_start(self, mail):
|
@@ -277,15 +308,16 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
277
308
|
Args:
|
278
309
|
mail (BaseMail): The start mail to process.
|
279
310
|
"""
|
280
|
-
start_mail_content = mail.package
|
311
|
+
start_mail_content = mail.package.package
|
281
312
|
self.context = start_mail_content["context"]
|
282
313
|
self.send(
|
283
|
-
start_mail_content["structure_id"],
|
284
|
-
"start",
|
285
|
-
|
314
|
+
recipient=start_mail_content["structure_id"],
|
315
|
+
category="start",
|
316
|
+
package="start",
|
317
|
+
request_source=self.ln_id,
|
286
318
|
)
|
287
319
|
|
288
|
-
def _process_end(self, mail:
|
320
|
+
def _process_end(self, mail: Mail):
|
289
321
|
"""
|
290
322
|
Processes an end mail.
|
291
323
|
|
@@ -293,4 +325,9 @@ class BranchExecutor(Branch, BaseExecutor):
|
|
293
325
|
mail (BaseMail): The end mail to process.
|
294
326
|
"""
|
295
327
|
self.execute_stop = True
|
296
|
-
self.send(
|
328
|
+
self.send(
|
329
|
+
recipient=mail.sender,
|
330
|
+
category="end",
|
331
|
+
package="end",
|
332
|
+
request_source=self.ln_id,
|
333
|
+
)
|
@@ -1,33 +1,33 @@
|
|
1
1
|
import asyncio
|
2
2
|
from pydantic import Field
|
3
3
|
|
4
|
-
from lionagi.
|
5
|
-
|
6
|
-
from lionagi.core.mail.schema import BaseMail, MailTransfer
|
4
|
+
from lionagi.core.mail.mail import Mail, Package
|
5
|
+
from lionagi.core.collections import Exchange
|
7
6
|
from lionagi.core.mail.mail_manager import MailManager
|
8
|
-
from lionagi.core.
|
9
|
-
from lionagi.core.
|
7
|
+
from lionagi.core.executor.base_executor import BaseExecutor
|
8
|
+
from lionagi.core.engine.branch_engine import BranchExecutor
|
9
|
+
from lionagi.core.collections import progression, pile, Pile
|
10
10
|
|
11
11
|
|
12
|
-
class
|
12
|
+
class InstructionMapEngine(BaseExecutor):
|
13
13
|
"""
|
14
14
|
Manages the execution of a mapped set of instructions across multiple branches within an executable structure.
|
15
15
|
|
16
16
|
Attributes:
|
17
17
|
branches (dict[str, BranchExecutor]): A dictionary of branch executors managing individual instruction flows.
|
18
18
|
structure_id (str): The identifier for the structure within which these branches operate.
|
19
|
-
mail_transfer (
|
19
|
+
mail_transfer (Exchange): Handles the transfer of mail between branches and other components.
|
20
20
|
branch_kwargs (dict): Keyword arguments used for initializing branches.
|
21
21
|
num_end_branches (int): Tracks the number of branches that have completed execution.
|
22
22
|
mail_manager (MailManager): Manages the distribution and collection of mails across branches.
|
23
23
|
"""
|
24
24
|
|
25
|
-
branches:
|
25
|
+
branches: Pile[BranchExecutor] = Field(
|
26
26
|
default_factory=dict, description="The branches of the instruction mapping."
|
27
27
|
)
|
28
28
|
structure_id: str = Field("", description="The ID of the executable structure.")
|
29
|
-
mail_transfer:
|
30
|
-
default_factory=
|
29
|
+
mail_transfer: Exchange = Field(
|
30
|
+
default_factory=Exchange, description="The mail transfer."
|
31
31
|
)
|
32
32
|
branch_kwargs: dict = Field(
|
33
33
|
default_factory=dict,
|
@@ -53,9 +53,10 @@ class InstructionMapExecutor(BaseExecutor):
|
|
53
53
|
Processes incoming mails, directing them appropriately based on their categories, and handles the initial setup
|
54
54
|
of branches or the routing of node and condition mails.
|
55
55
|
"""
|
56
|
-
for key in list(self.pending_ins.keys()):
|
57
|
-
while self.pending_ins[key]:
|
58
|
-
|
56
|
+
for key in list(self.mailbox.pending_ins.keys()):
|
57
|
+
while self.mailbox.pending_ins[key].size() > 0:
|
58
|
+
mail_id = self.mailbox.pending_ins[key].popleft()
|
59
|
+
mail = self.mailbox.pile.pop(mail_id)
|
59
60
|
if mail.category == "start":
|
60
61
|
self._process_start(mail)
|
61
62
|
elif mail.category == "node_list":
|
@@ -65,9 +66,9 @@ class InstructionMapExecutor(BaseExecutor):
|
|
65
66
|
or (mail.category == "condition")
|
66
67
|
or (mail.category == "end")
|
67
68
|
):
|
68
|
-
mail.
|
69
|
-
mail.
|
70
|
-
self.mail_transfer.
|
69
|
+
mail.sender = self.mail_transfer.ln_id
|
70
|
+
mail.recipient = mail.package.request_source
|
71
|
+
self.mail_transfer.include(mail, "out")
|
71
72
|
|
72
73
|
def transfer_outs(self):
|
73
74
|
"""
|
@@ -75,23 +76,24 @@ class InstructionMapExecutor(BaseExecutor):
|
|
75
76
|
other mails to appropriate recipients.
|
76
77
|
"""
|
77
78
|
for key in list(self.mail_transfer.pending_ins.keys()):
|
78
|
-
while self.mail_transfer.pending_ins[key]:
|
79
|
-
|
79
|
+
while self.mail_transfer.pending_ins[key].size() > 0:
|
80
|
+
mail_id = self.mail_transfer.pending_ins[key].popleft()
|
81
|
+
mail = self.mail_transfer.pile.pop(mail_id)
|
80
82
|
if mail.category == "end":
|
81
83
|
self.num_end_branches += 1
|
82
84
|
if self.num_end_branches == len(
|
83
85
|
self.branches
|
84
86
|
): # tell when structure should stop
|
85
|
-
mail.
|
86
|
-
mail.
|
87
|
-
self.
|
87
|
+
mail.sender = self.ln_id
|
88
|
+
mail.recipient = self.structure_id
|
89
|
+
self.mailbox.include(mail, "out")
|
88
90
|
self.execute_stop = True
|
89
91
|
else:
|
90
|
-
mail.
|
91
|
-
mail.
|
92
|
-
self.
|
92
|
+
mail.sender = self.ln_id
|
93
|
+
mail.recipient = self.structure_id
|
94
|
+
self.mailbox.include(mail, "out")
|
93
95
|
|
94
|
-
def _process_start(self, start_mail:
|
96
|
+
def _process_start(self, start_mail: Mail):
|
95
97
|
"""
|
96
98
|
Processes a start mail to initialize a new branch executor and configures it based on the mail's package content.
|
97
99
|
|
@@ -99,19 +101,20 @@ class InstructionMapExecutor(BaseExecutor):
|
|
99
101
|
start_mail (BaseMail): The mail initiating the start of a new branch execution.
|
100
102
|
"""
|
101
103
|
branch = BranchExecutor(verbose=self.verbose, **self.branch_kwargs)
|
102
|
-
branch.context = start_mail.package["context"]
|
103
|
-
self.branches[branch.
|
104
|
+
branch.context = start_mail.package.package["context"]
|
105
|
+
self.branches[branch.ln_id] = branch
|
104
106
|
self.mail_manager.add_sources([branch])
|
105
|
-
self.structure_id = start_mail.package["structure_id"]
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
107
|
+
self.structure_id = start_mail.package.package["structure_id"]
|
108
|
+
|
109
|
+
pack = Package(category="start", package="start", request_source=branch.ln_id)
|
110
|
+
mail = Mail(
|
111
|
+
sender=self.ln_id,
|
112
|
+
recipient=self.structure_id,
|
113
|
+
package=pack,
|
111
114
|
)
|
112
|
-
self.
|
115
|
+
self.mailbox.include(mail, "out")
|
113
116
|
|
114
|
-
def _process_node_list(self, nl_mail:
|
117
|
+
def _process_node_list(self, nl_mail: Mail):
|
115
118
|
"""
|
116
119
|
Processes a node list mail, setting up new branches or propagating the execution context based on the node list
|
117
120
|
provided in the mail.
|
@@ -119,39 +122,59 @@ class InstructionMapExecutor(BaseExecutor):
|
|
119
122
|
Args:
|
120
123
|
nl_mail (BaseMail): The mail containing a list of nodes to be processed in subsequent branches.
|
121
124
|
"""
|
122
|
-
source_branch_id = nl_mail.package
|
123
|
-
node_list = nl_mail.package
|
125
|
+
source_branch_id = nl_mail.package.request_source
|
126
|
+
node_list = nl_mail.package.package
|
124
127
|
shared_context = self.branches[source_branch_id].context
|
125
128
|
shared_context_log = self.branches[source_branch_id].context_log
|
126
129
|
base_branch = self.branches[source_branch_id]
|
127
130
|
|
128
|
-
|
129
|
-
|
130
|
-
recipient_id=source_branch_id,
|
131
|
-
category="node",
|
132
|
-
package={"request_source": source_branch_id, "package": node_list[0]},
|
131
|
+
pack = Package(
|
132
|
+
category="node", package=node_list[0], request_source=source_branch_id
|
133
133
|
)
|
134
|
-
|
134
|
+
mail = Mail(
|
135
|
+
sender=self.mail_transfer.ln_id,
|
136
|
+
recipient=source_branch_id,
|
137
|
+
package=pack,
|
138
|
+
)
|
139
|
+
self.mail_transfer.include(mail, "out")
|
135
140
|
|
136
141
|
for i in range(1, len(node_list)):
|
142
|
+
system = base_branch.system.clone() if base_branch.system else None
|
143
|
+
if system:
|
144
|
+
system.sender = base_branch.ln_id
|
145
|
+
progress = progression()
|
146
|
+
messages = pile()
|
147
|
+
|
148
|
+
for id_ in base_branch.progress:
|
149
|
+
clone_message = base_branch.messages[id_].clone()
|
150
|
+
progress.append(clone_message.ln_id)
|
151
|
+
messages.append(clone_message)
|
152
|
+
|
137
153
|
branch = BranchExecutor(
|
138
154
|
verbose=self.verbose,
|
139
|
-
messages=
|
140
|
-
|
141
|
-
|
142
|
-
|
155
|
+
messages=messages,
|
156
|
+
user=base_branch.user,
|
157
|
+
system=base_branch.system.clone(),
|
158
|
+
progress=progress,
|
159
|
+
imodel=base_branch.imodel,
|
143
160
|
)
|
161
|
+
for message in branch.messages:
|
162
|
+
message.sender = base_branch.ln_id
|
163
|
+
message.recipient = branch.ln_id
|
164
|
+
|
144
165
|
branch.context = shared_context
|
145
166
|
branch.context_log = shared_context_log
|
146
|
-
self.branches[branch.
|
167
|
+
self.branches[branch.ln_id] = branch
|
147
168
|
self.mail_manager.add_sources([branch])
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
169
|
+
node_pacakge = Package(
|
170
|
+
category="node", package=node_list[i], request_source=source_branch_id
|
171
|
+
)
|
172
|
+
node_mail = Mail(
|
173
|
+
sender=self.mail_transfer.ln_id,
|
174
|
+
recipient=branch.ln_id,
|
175
|
+
package=node_pacakge,
|
153
176
|
)
|
154
|
-
self.mail_transfer.
|
177
|
+
self.mail_transfer.include(node_mail, "out")
|
155
178
|
|
156
179
|
async def forward(self):
|
157
180
|
"""
|
@@ -162,7 +185,9 @@ class InstructionMapExecutor(BaseExecutor):
|
|
162
185
|
self.mail_manager.collect_all()
|
163
186
|
self.mail_manager.send_all()
|
164
187
|
tasks = [
|
165
|
-
branch.forward()
|
188
|
+
branch.forward()
|
189
|
+
for branch in self.branches.values()
|
190
|
+
if branch.mailbox.pending_ins
|
166
191
|
]
|
167
192
|
await asyncio.gather(*tasks)
|
168
193
|
return
|
@@ -1,7 +1,23 @@
|
|
1
|
+
"""
|
2
|
+
Copyright 2024 HaiyangLi
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
"""
|
16
|
+
|
1
17
|
import ast
|
2
18
|
from functools import lru_cache
|
3
19
|
from lionagi.libs import AsyncUtil
|
4
|
-
from .base_evaluator import BaseEvaluator
|
20
|
+
from ..evaluator.base_evaluator import BaseEvaluator
|
5
21
|
from .sandbox_ import SandboxTransformer
|
6
22
|
|
7
23
|
|