lionagi 0.0.306__py3-none-any.whl → 0.0.308__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lionagi/__init__.py +2 -5
 - lionagi/core/__init__.py +7 -5
 - lionagi/core/agent/__init__.py +3 -0
 - lionagi/core/agent/base_agent.py +10 -12
 - lionagi/core/branch/__init__.py +4 -0
 - lionagi/core/branch/base_branch.py +81 -81
 - lionagi/core/branch/branch.py +16 -28
 - lionagi/core/branch/branch_flow_mixin.py +3 -7
 - lionagi/core/branch/executable_branch.py +86 -56
 - lionagi/core/branch/util.py +77 -162
 - lionagi/core/{flow/direct → direct}/__init__.py +1 -1
 - lionagi/core/{flow/direct/predict.py → direct/parallel_predict.py} +39 -17
 - lionagi/core/direct/parallel_react.py +0 -0
 - lionagi/core/direct/parallel_score.py +0 -0
 - lionagi/core/direct/parallel_select.py +0 -0
 - lionagi/core/direct/parallel_sentiment.py +0 -0
 - lionagi/core/direct/predict.py +174 -0
 - lionagi/core/{flow/direct → direct}/react.py +2 -2
 - lionagi/core/{flow/direct → direct}/score.py +28 -23
 - lionagi/core/{flow/direct → direct}/select.py +48 -45
 - lionagi/core/direct/utils.py +83 -0
 - lionagi/core/flow/monoflow/ReAct.py +6 -5
 - lionagi/core/flow/monoflow/__init__.py +9 -0
 - lionagi/core/flow/monoflow/chat.py +10 -10
 - lionagi/core/flow/monoflow/chat_mixin.py +11 -10
 - lionagi/core/flow/monoflow/followup.py +6 -5
 - lionagi/core/flow/polyflow/__init__.py +1 -0
 - lionagi/core/flow/polyflow/chat.py +15 -3
 - lionagi/core/mail/mail_manager.py +18 -19
 - lionagi/core/mail/schema.py +5 -4
 - lionagi/core/messages/schema.py +18 -20
 - lionagi/core/prompt/__init__.py +0 -0
 - lionagi/core/prompt/prompt_template.py +0 -0
 - lionagi/core/schema/__init__.py +2 -2
 - lionagi/core/schema/action_node.py +11 -3
 - lionagi/core/schema/base_mixin.py +56 -59
 - lionagi/core/schema/base_node.py +34 -37
 - lionagi/core/schema/condition.py +24 -0
 - lionagi/core/schema/data_logger.py +96 -99
 - lionagi/core/schema/data_node.py +19 -19
 - lionagi/core/schema/prompt_template.py +0 -0
 - lionagi/core/schema/structure.py +171 -169
 - lionagi/core/session/__init__.py +1 -3
 - lionagi/core/session/session.py +196 -214
 - lionagi/core/tool/tool_manager.py +95 -103
 - lionagi/integrations/__init__.py +1 -3
 - lionagi/integrations/bridge/langchain_/documents.py +17 -18
 - lionagi/integrations/bridge/langchain_/langchain_bridge.py +14 -14
 - lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +22 -22
 - lionagi/integrations/bridge/llamaindex_/node_parser.py +12 -12
 - lionagi/integrations/bridge/llamaindex_/reader.py +11 -11
 - lionagi/integrations/bridge/llamaindex_/textnode.py +7 -7
 - lionagi/integrations/config/openrouter_configs.py +0 -1
 - lionagi/integrations/provider/oai.py +26 -26
 - lionagi/integrations/provider/services.py +38 -38
 - lionagi/libs/__init__.py +34 -1
 - lionagi/libs/ln_api.py +211 -221
 - lionagi/libs/ln_async.py +53 -60
 - lionagi/libs/ln_convert.py +118 -120
 - lionagi/libs/ln_dataframe.py +32 -33
 - lionagi/libs/ln_func_call.py +334 -342
 - lionagi/libs/ln_nested.py +99 -107
 - lionagi/libs/ln_parse.py +161 -165
 - lionagi/libs/sys_util.py +52 -52
 - lionagi/tests/test_core/test_session.py +254 -266
 - lionagi/tests/test_core/test_session_base_util.py +299 -300
 - lionagi/tests/test_core/test_tool_manager.py +70 -74
 - lionagi/tests/test_libs/test_nested.py +2 -7
 - lionagi/tests/test_libs/test_parse.py +2 -2
 - lionagi/version.py +1 -1
 - {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/METADATA +4 -2
 - lionagi-0.0.308.dist-info/RECORD +115 -0
 - lionagi/core/flow/direct/utils.py +0 -43
 - lionagi-0.0.306.dist-info/RECORD +0 -106
 - /lionagi/core/{flow/direct → direct}/sentiment.py +0 -0
 - {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/LICENSE +0 -0
 - {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/WHEEL +0 -0
 - {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/top_level.txt +0 -0
 
| 
         @@ -1,27 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import contextlib
         
     | 
| 
       1 
2 
     | 
    
         
             
            from collections import deque
         
     | 
| 
       2 
3 
     | 
    
         
             
            from typing import Any
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            from  
     | 
| 
      
 5 
     | 
    
         
            +
            from lionagi.libs import convert, AsyncUtil, ParseUtil
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            import  
     | 
| 
       7 
     | 
    
         
            -
            from  
     | 
| 
       8 
     | 
    
         
            -
            from  
     | 
| 
      
 7 
     | 
    
         
            +
            from ..schema import BaseRelatableNode, ActionNode
         
     | 
| 
      
 8 
     | 
    
         
            +
            from ..mail import BaseMail
         
     | 
| 
      
 9 
     | 
    
         
            +
            from ..messages import System, Instruction
         
     | 
| 
      
 10 
     | 
    
         
            +
            from ..agent import BaseAgent
         
     | 
| 
       9 
11 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            from  
     | 
| 
       11 
     | 
    
         
            -
            from lionagi.core.schema.action_node import ActionNode
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            from lionagi.core.mail.schema import BaseMail
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            from lionagi.core.messages.schema import System, Instruction
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            from lionagi import Branch
         
     | 
| 
       19 
     | 
    
         
            -
            from lionagi.core.agent.base_agent import BaseAgent
         
     | 
| 
      
 12 
     | 
    
         
            +
            from .branch import Branch
         
     | 
| 
       20 
13 
     | 
    
         | 
| 
       21 
14 
     | 
    
         | 
| 
       22 
15 
     | 
    
         
             
            class ExecutableBranch(BaseRelatableNode):
         
     | 
| 
       23 
16 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                def __init__(self, **kwargs):
         
     | 
| 
      
 17 
     | 
    
         
            +
                def __init__(self, verbose=True, **kwargs):
         
     | 
| 
       25 
18 
     | 
    
         
             
                    super().__init__()
         
     | 
| 
       26 
19 
     | 
    
         
             
                    self.branch: Branch = Branch(**kwargs)
         
     | 
| 
       27 
20 
     | 
    
         
             
                    self.pending_ins = {}  # needed
         
     | 
| 
         @@ -29,6 +22,8 @@ class ExecutableBranch(BaseRelatableNode): 
     | 
|
| 
       29 
22 
     | 
    
         
             
                    self.responses = []
         
     | 
| 
       30 
23 
     | 
    
         
             
                    self.execute_stop = False  # needed
         
     | 
| 
       31 
24 
     | 
    
         
             
                    self.context = None  # needed
         
     | 
| 
      
 25 
     | 
    
         
            +
                    self.context_log = []
         
     | 
| 
      
 26 
     | 
    
         
            +
                    self.verbose = verbose
         
     | 
| 
       32 
27 
     | 
    
         | 
| 
       33 
28 
     | 
    
         
             
                def send(self, recipient_id: str, category: str, package: Any) -> None:
         
     | 
| 
       34 
29 
     | 
    
         
             
                    mail = BaseMail(
         
     | 
| 
         @@ -45,8 +40,12 @@ class ExecutableBranch(BaseRelatableNode): 
     | 
|
| 
       45 
40 
     | 
    
         
             
                            mail = self.pending_ins[key].popleft()
         
     | 
| 
       46 
41 
     | 
    
         
             
                            if mail.category == "start":  # needed
         
     | 
| 
       47 
42 
     | 
    
         
             
                                self._process_start(mail)
         
     | 
| 
       48 
     | 
    
         
            -
                             
     | 
| 
      
 43 
     | 
    
         
            +
                            elif mail.category == "node":
         
     | 
| 
       49 
44 
     | 
    
         
             
                                await self._process_node(mail)
         
     | 
| 
      
 45 
     | 
    
         
            +
                            elif mail.category == "node_list":
         
     | 
| 
      
 46 
     | 
    
         
            +
                                self._process_node_list(mail)
         
     | 
| 
      
 47 
     | 
    
         
            +
                            elif mail.category == "condition":
         
     | 
| 
      
 48 
     | 
    
         
            +
                                self._process_condition(mail)
         
     | 
| 
       50 
49 
     | 
    
         
             
                            elif mail.category == "end":  # needed
         
     | 
| 
       51 
50 
     | 
    
         
             
                                self._process_end(mail)
         
     | 
| 
       52 
51 
     | 
    
         | 
| 
         @@ -58,28 +57,40 @@ class ExecutableBranch(BaseRelatableNode): 
     | 
|
| 
       58 
57 
     | 
    
         
             
                async def _process_node(self, mail: BaseMail):
         
     | 
| 
       59 
58 
     | 
    
         | 
| 
       60 
59 
     | 
    
         
             
                    if isinstance(mail.package, System):
         
     | 
| 
       61 
     | 
    
         
            -
                        self._system_process(mail.package)
         
     | 
| 
      
 60 
     | 
    
         
            +
                        self._system_process(mail.package, verbose=self.verbose)
         
     | 
| 
       62 
61 
     | 
    
         
             
                        self.send(mail.sender_id, "node_id", mail.package.id_)
         
     | 
| 
       63 
     | 
    
         
            -
                        return
         
     | 
| 
       64 
62 
     | 
    
         | 
| 
       65 
63 
     | 
    
         
             
                    elif isinstance(mail.package, Instruction):
         
     | 
| 
       66 
     | 
    
         
            -
                        await self._instruction_process(mail.package)
         
     | 
| 
      
 64 
     | 
    
         
            +
                        await self._instruction_process(mail.package, verbose=self.verbose)
         
     | 
| 
       67 
65 
     | 
    
         
             
                        self.send(mail.sender_id, "node_id", mail.package.id_)
         
     | 
| 
       68 
     | 
    
         
            -
                        return
         
     | 
| 
       69 
66 
     | 
    
         | 
| 
       70 
67 
     | 
    
         
             
                    elif isinstance(mail.package, ActionNode):
         
     | 
| 
       71 
     | 
    
         
            -
                        await self._action_process(mail.package)
         
     | 
| 
      
 68 
     | 
    
         
            +
                        await self._action_process(mail.package, verbose=self.verbose)
         
     | 
| 
       72 
69 
     | 
    
         
             
                        self.send(mail.sender_id, "node_id", mail.package.instruction.id_)
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 71 
     | 
    
         
            +
                        try:
         
     | 
| 
      
 72 
     | 
    
         
            +
                            await self._agent_process(mail.package, verbose=self.verbose)
         
     | 
| 
      
 73 
     | 
    
         
            +
                            self.send(mail.sender_id, "node_id", mail.package.id_)
         
     | 
| 
      
 74 
     | 
    
         
            +
                        except:
         
     | 
| 
      
 75 
     | 
    
         
            +
                            raise ValueError(f"Invalid mail to process. Mail:{mail}")
         
     | 
| 
       74 
76 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
      
 77 
     | 
    
         
            +
                def _process_node_list(self, mail: BaseMail):
         
     | 
| 
      
 78 
     | 
    
         
            +
                    self.send(mail.sender_id, "end", "end")
         
     | 
| 
      
 79 
     | 
    
         
            +
                    self.execute_stop = True
         
     | 
| 
      
 80 
     | 
    
         
            +
                    raise ValueError("Multiple path selection is currently not supported")
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                def _process_condition(self, mail: BaseMail):
         
     | 
| 
      
 83 
     | 
    
         
            +
                    relationship = mail.package
         
     | 
| 
      
 84 
     | 
    
         
            +
                    check_result = relationship.condition(self)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    back_mail = {"relationship_id": mail.package.id_, "check_result": check_result}
         
     | 
| 
      
 86 
     | 
    
         
            +
                    self.send(mail.sender_id, "condition", back_mail)
         
     | 
| 
       79 
87 
     | 
    
         | 
| 
       80 
88 
     | 
    
         
             
                def _system_process(self, system: System, verbose=True, context_verbose=False):
         
     | 
| 
      
 89 
     | 
    
         
            +
                    from lionagi.libs import SysUtil
         
     | 
| 
      
 90 
     | 
    
         
            +
                    SysUtil.check_import('IPython')
         
     | 
| 
      
 91 
     | 
    
         
            +
                    from IPython.display import Markdown, display
         
     | 
| 
       81 
92 
     | 
    
         
             
                    if verbose:
         
     | 
| 
       82 
     | 
    
         
            -
                        print(f" 
     | 
| 
      
 93 
     | 
    
         
            +
                        print(f"------------------Welcome: {system.sender}--------------------")
         
     | 
| 
       83 
94 
     | 
    
         
             
                        display(Markdown(f"system: {convert.to_str(system.system_info)}"))
         
     | 
| 
       84 
95 
     | 
    
         
             
                        if self.context and context_verbose:
         
     | 
| 
       85 
96 
     | 
    
         
             
                            display(Markdown(f"context: {convert.to_str(self.context)}"))
         
     | 
| 
         @@ -89,6 +100,9 @@ class ExecutableBranch(BaseRelatableNode): 
     | 
|
| 
       89 
100 
     | 
    
         
             
                async def _instruction_process(
         
     | 
| 
       90 
101 
     | 
    
         
             
                    self, instruction: Instruction, verbose=True, **kwargs
         
     | 
| 
       91 
102 
     | 
    
         
             
                ):
         
     | 
| 
      
 103 
     | 
    
         
            +
                    from lionagi.libs import SysUtil
         
     | 
| 
      
 104 
     | 
    
         
            +
                    SysUtil.check_import('IPython')
         
     | 
| 
      
 105 
     | 
    
         
            +
                    from IPython.display import Markdown, display
         
     | 
| 
       92 
106 
     | 
    
         
             
                    if verbose:
         
     | 
| 
       93 
107 
     | 
    
         
             
                        display(
         
     | 
| 
       94 
108 
     | 
    
         
             
                            Markdown(
         
     | 
| 
         @@ -101,54 +115,41 @@ class ExecutableBranch(BaseRelatableNode): 
     | 
|
| 
       101 
115 
     | 
    
         
             
                        self.context = None
         
     | 
| 
       102 
116 
     | 
    
         | 
| 
       103 
117 
     | 
    
         
             
                    result = await self.branch.chat(instruction, **kwargs)
         
     | 
| 
       104 
     | 
    
         
            -
                     
     | 
| 
      
 118 
     | 
    
         
            +
                    with contextlib.suppress(Exception):
         
     | 
| 
       105 
119 
     | 
    
         
             
                        result = ParseUtil.fuzzy_parse_json(result)
         
     | 
| 
       106 
120 
     | 
    
         
             
                        if "response" in result.keys():
         
     | 
| 
       107 
121 
     | 
    
         
             
                            result = result["response"]
         
     | 
| 
       108 
     | 
    
         
            -
                     
     | 
| 
       109 
     | 
    
         
            -
                        pass
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
                    if verbose:
         
     | 
| 
      
 122 
     | 
    
         
            +
                    if verbose and len(self.branch.assistant_responses) != 0:
         
     | 
| 
       112 
123 
     | 
    
         
             
                        display(
         
     | 
| 
       113 
124 
     | 
    
         
             
                            Markdown(
         
     | 
| 
       114 
125 
     | 
    
         
             
                                f"{self.branch.last_assistant_response.sender}: {convert.to_str(result)}"
         
     | 
| 
       115 
126 
     | 
    
         
             
                            )
         
     | 
| 
       116 
127 
     | 
    
         
             
                        )
         
     | 
| 
      
 128 
     | 
    
         
            +
                        print("-----------------------------------------------------")
         
     | 
| 
       117 
129 
     | 
    
         | 
| 
       118 
130 
     | 
    
         
             
                    self.responses.append(result)
         
     | 
| 
       119 
131 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                async def  
     | 
| 
       121 
     | 
    
         
            -
                     
     | 
| 
       122 
     | 
    
         
            -
                     
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
                    self.context = result
         
     | 
| 
       125 
     | 
    
         
            -
                    self.responses.append(result)
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
                def _process_start(self, mail):
         
     | 
| 
       128 
     | 
    
         
            -
                    start_mail_content = mail.package
         
     | 
| 
       129 
     | 
    
         
            -
                    self.context = start_mail_content["context"]
         
     | 
| 
       130 
     | 
    
         
            -
                    self.send(start_mail_content["structure_id"], "start", "start")
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                def _process_end(self, mail):
         
     | 
| 
       133 
     | 
    
         
            -
                    self.execute_stop = True
         
     | 
| 
       134 
     | 
    
         
            -
                    self.send(mail.sender_id, "end", "end")
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
                async def _action_process(self, action: ActionNode):
         
     | 
| 
       137 
     | 
    
         
            -
                    # instruction = action.instruction
         
     | 
| 
       138 
     | 
    
         
            -
                    # if self.context:
         
     | 
| 
       139 
     | 
    
         
            -
                    #     instruction.content.update({"context": self.context})
         
     | 
| 
       140 
     | 
    
         
            -
                    #     self.context=None
         
     | 
| 
      
 132 
     | 
    
         
            +
                async def _action_process(self, action: ActionNode, verbose=True):
         
     | 
| 
      
 133 
     | 
    
         
            +
                    from lionagi.libs import SysUtil
         
     | 
| 
      
 134 
     | 
    
         
            +
                    SysUtil.check_import('IPython')
         
     | 
| 
      
 135 
     | 
    
         
            +
                    from IPython.display import Markdown, display
         
     | 
| 
       141 
136 
     | 
    
         
             
                    try:
         
     | 
| 
       142 
137 
     | 
    
         
             
                        func = getattr(self.branch, action.action)
         
     | 
| 
       143 
138 
     | 
    
         
             
                    except:
         
     | 
| 
       144 
139 
     | 
    
         
             
                        raise ValueError(f"{action.action} is not a valid action")
         
     | 
| 
       145 
140 
     | 
    
         | 
| 
      
 141 
     | 
    
         
            +
                    if verbose:
         
     | 
| 
      
 142 
     | 
    
         
            +
                        display(
         
     | 
| 
      
 143 
     | 
    
         
            +
                            Markdown(
         
     | 
| 
      
 144 
     | 
    
         
            +
                                f"{action.instruction.sender}: {convert.to_str(action.instruction.instruct)}"
         
     | 
| 
      
 145 
     | 
    
         
            +
                            )
         
     | 
| 
      
 146 
     | 
    
         
            +
                        )
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
       146 
148 
     | 
    
         
             
                    if action.tools:
         
     | 
| 
       147 
149 
     | 
    
         
             
                        self.branch.register_tools(action.tools)
         
     | 
| 
       148 
     | 
    
         
            -
                    # result = await func(instruction, tools=action.tools, **action.action_kwargs)
         
     | 
| 
       149 
150 
     | 
    
         
             
                    if self.context:
         
     | 
| 
       150 
151 
     | 
    
         
             
                        result = await func(
         
     | 
| 
       151 
     | 
    
         
            -
                            action.instruction.content,
         
     | 
| 
      
 152 
     | 
    
         
            +
                            action.instruction.content["instruction"],
         
     | 
| 
       152 
153 
     | 
    
         
             
                            context=self.context,
         
     | 
| 
       153 
154 
     | 
    
         
             
                            tools=action.tools,
         
     | 
| 
       154 
155 
     | 
    
         
             
                            **action.action_kwargs,
         
     | 
| 
         @@ -158,5 +159,34 @@ class ExecutableBranch(BaseRelatableNode): 
     | 
|
| 
       158 
159 
     | 
    
         
             
                        result = await func(
         
     | 
| 
       159 
160 
     | 
    
         
             
                            action.instruction.content, tools=action.tools, **action.action_kwargs
         
     | 
| 
       160 
161 
     | 
    
         
             
                        )
         
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                    if verbose and len(self.branch.assistant_responses) != 0:
         
     | 
| 
      
 164 
     | 
    
         
            +
                        display(
         
     | 
| 
      
 165 
     | 
    
         
            +
                            Markdown(
         
     | 
| 
      
 166 
     | 
    
         
            +
                                f"{self.branch.last_assistant_response.sender}: {convert.to_str(result)}"
         
     | 
| 
      
 167 
     | 
    
         
            +
                            )
         
     | 
| 
      
 168 
     | 
    
         
            +
                        )
         
     | 
| 
      
 169 
     | 
    
         
            +
                        print("-----------------------------------------------------")
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
       162 
171 
     | 
    
         
             
                    self.responses.append(result)
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                async def _agent_process(self, agent, verbose=True):
         
     | 
| 
      
 174 
     | 
    
         
            +
                    context = self.responses
         
     | 
| 
      
 175 
     | 
    
         
            +
                    if verbose:
         
     | 
| 
      
 176 
     | 
    
         
            +
                        print("*****************************************************")
         
     | 
| 
      
 177 
     | 
    
         
            +
                    result = await agent.execute(context)
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                    if verbose:
         
     | 
| 
      
 180 
     | 
    
         
            +
                        print("*****************************************************")
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                    self.context = result
         
     | 
| 
      
 183 
     | 
    
         
            +
                    self.responses.append(result)
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                def _process_start(self, mail):
         
     | 
| 
      
 186 
     | 
    
         
            +
                    start_mail_content = mail.package
         
     | 
| 
      
 187 
     | 
    
         
            +
                    self.context = start_mail_content["context"]
         
     | 
| 
      
 188 
     | 
    
         
            +
                    self.send(start_mail_content["structure_id"], "start", "start")
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                def _process_end(self, mail):
         
     | 
| 
      
 191 
     | 
    
         
            +
                    self.execute_stop = True
         
     | 
| 
      
 192 
     | 
    
         
            +
                    self.send(mail.sender_id, "end", "end")
         
     | 
    
        lionagi/core/branch/util.py
    CHANGED
    
    | 
         @@ -1,10 +1,8 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import contextlib
         
     | 
| 
       1 
2 
     | 
    
         
             
            from datetime import datetime
         
     | 
| 
       2 
3 
     | 
    
         
             
            from typing import Any
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            from lionagi.libs import  
     | 
| 
       5 
     | 
    
         
            -
            from lionagi.libs import ln_nested as nested
         
     | 
| 
       6 
     | 
    
         
            -
            from lionagi.libs import ln_func_call as func_call
         
     | 
| 
       7 
     | 
    
         
            -
            from lionagi.libs import ln_dataframe as dataframe
         
     | 
| 
      
 5 
     | 
    
         
            +
            from lionagi.libs import convert, nested, func_call, dataframe
         
     | 
| 
       8 
6 
     | 
    
         | 
| 
       9 
7 
     | 
    
         
             
            from lionagi.core.messages.schema import (
         
     | 
| 
       10 
8 
     | 
    
         
             
                System,
         
     | 
| 
         @@ -14,7 +12,6 @@ from lionagi.core.messages.schema import ( 
     | 
|
| 
       14 
12 
     | 
    
         
             
                BranchColumns,
         
     | 
| 
       15 
13 
     | 
    
         
             
            )
         
     | 
| 
       16 
14 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
15 
     | 
    
         
             
            CUSTOM_TYPE = dict[str, Any] | str | list[Any] | None
         
     | 
| 
       19 
16 
     | 
    
         | 
| 
       20 
17 
     | 
    
         | 
| 
         @@ -33,42 +30,41 @@ class MessageUtil: 
     | 
|
| 
       33 
30 
     | 
    
         
             
                    Creates a message object based on the input parameters, ensuring only one message role is present.
         
     | 
| 
       34 
31 
     | 
    
         | 
| 
       35 
32 
     | 
    
         
             
                    Args:
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 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.
         
     | 
| 
       41 
38 
     | 
    
         | 
| 
       42 
39 
     | 
    
         
             
                    Returns:
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
                            A message object of the appropriate type based on provided inputs.
         
     | 
| 
       44 
41 
     | 
    
         | 
| 
       45 
42 
     | 
    
         
             
                    Raises:
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 43 
     | 
    
         
            +
                            ValueError: If more than one of the role-specific parameters are provided.
         
     | 
| 
       47 
44 
     | 
    
         
             
                    """
         
     | 
| 
       48 
45 
     | 
    
         
             
                    if sum(func_call.lcall([system, instruction, response], bool)) != 1:
         
     | 
| 
       49 
46 
     | 
    
         
             
                        raise ValueError("Error: Message must have one and only one role.")
         
     | 
| 
       50 
47 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                     
     | 
| 
       52 
     | 
    
         
            -
                         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                         
     | 
| 
       63 
     | 
    
         
            -
                             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                        return msg
         
     | 
| 
      
 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
         
     | 
| 
       72 
68 
     | 
    
         | 
| 
       73 
69 
     | 
    
         
             
                @staticmethod
         
     | 
| 
       74 
70 
     | 
    
         
             
                def validate_messages(messages: dataframe.ln_DataFrame) -> bool:
         
     | 
| 
         @@ -76,21 +72,21 @@ class MessageUtil: 
     | 
|
| 
       76 
72 
     | 
    
         
             
                    Validates the format and content of a DataFrame containing messages.
         
     | 
| 
       77 
73 
     | 
    
         | 
| 
       78 
74 
     | 
    
         
             
                    Args:
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
      
 75 
     | 
    
         
            +
                            messages: A DataFrame with message information.
         
     | 
| 
       80 
76 
     | 
    
         | 
| 
       81 
77 
     | 
    
         
             
                    Returns:
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
                            True if the messages DataFrame is correctly formatted, False otherwise.
         
     | 
| 
       83 
79 
     | 
    
         | 
| 
       84 
80 
     | 
    
         
             
                    Raises:
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
                            ValueError: If the DataFrame does not match expected schema or content requirements.
         
     | 
| 
       86 
82 
     | 
    
         
             
                    """
         
     | 
| 
       87 
83 
     | 
    
         | 
| 
       88 
84 
     | 
    
         
             
                    if list(messages.columns) != BranchColumns.COLUMNS.value:
         
     | 
| 
       89 
85 
     | 
    
         
             
                        raise ValueError("Invalid messages dataframe. Unmatched columns.")
         
     | 
| 
       90 
86 
     | 
    
         
             
                    if messages.isnull().values.any():
         
     | 
| 
       91 
87 
     | 
    
         
             
                        raise ValueError("Invalid messages dataframe. Cannot have null.")
         
     | 
| 
       92 
     | 
    
         
            -
                    if  
     | 
| 
       93 
     | 
    
         
            -
                        role in ["system", "user", "assistant"]
         
     | 
| 
      
 88 
     | 
    
         
            +
                    if any(
         
     | 
| 
      
 89 
     | 
    
         
            +
                        role not in ["system", "user", "assistant"]
         
     | 
| 
       94 
90 
     | 
    
         
             
                        for role in messages["role"].unique()
         
     | 
| 
       95 
91 
     | 
    
         
             
                    ):
         
     | 
| 
       96 
92 
     | 
    
         
             
                        raise ValueError(
         
     | 
| 
         @@ -115,14 +111,14 @@ class MessageUtil: 
     | 
|
| 
       115 
111 
     | 
    
         
             
                    Appends a sender prefix to the 'content' field of each message in a DataFrame.
         
     | 
| 
       116 
112 
     | 
    
         | 
| 
       117 
113 
     | 
    
         
             
                    Args:
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 114 
     | 
    
         
            +
                            messages: A DataFrame containing message data.
         
     | 
| 
      
 115 
     | 
    
         
            +
                            sender: The identifier of the sender to prefix to message contents.
         
     | 
| 
       120 
116 
     | 
    
         | 
| 
       121 
117 
     | 
    
         
             
                    Returns:
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
      
 118 
     | 
    
         
            +
                            A DataFrame with sender-prefixed message contents.
         
     | 
| 
       123 
119 
     | 
    
         | 
| 
       124 
120 
     | 
    
         
             
                    Raises:
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
      
 121 
     | 
    
         
            +
                            ValueError: If the sender is None or the value is 'none'.
         
     | 
| 
       126 
122 
     | 
    
         
             
                    """
         
     | 
| 
       127 
123 
     | 
    
         | 
| 
       128 
124 
     | 
    
         
             
                    if sender is None or convert.strip_lower(sender) == "none":
         
     | 
| 
         @@ -152,16 +148,16 @@ class MessageUtil: 
     | 
|
| 
       152 
148 
     | 
    
         
             
                    Filters messages in a DataFrame based on specified criteria.
         
     | 
| 
       153 
149 
     | 
    
         | 
| 
       154 
150 
     | 
    
         
             
                    Args:
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
      
 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.
         
     | 
| 
       162 
158 
     | 
    
         | 
| 
       163 
159 
     | 
    
         
             
                    Returns:
         
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
      
 160 
     | 
    
         
            +
                            A filtered DataFrame based on the specified criteria.
         
     | 
| 
       165 
161 
     | 
    
         
             
                    """
         
     | 
| 
       166 
162 
     | 
    
         | 
| 
       167 
163 
     | 
    
         
             
                    try:
         
     | 
| 
         @@ -180,7 +176,7 @@ class MessageUtil: 
     | 
|
| 
       180 
176 
     | 
    
         
             
                        return convert.to_df(outs)
         
     | 
| 
       181 
177 
     | 
    
         | 
| 
       182 
178 
     | 
    
         
             
                    except Exception as e:
         
     | 
| 
       183 
     | 
    
         
            -
                        raise ValueError(f"Error in filtering messages: {e}")
         
     | 
| 
      
 179 
     | 
    
         
            +
                        raise ValueError(f"Error in filtering messages: {e}") from e
         
     | 
| 
       184 
180 
     | 
    
         | 
| 
       185 
181 
     | 
    
         
             
                @staticmethod
         
     | 
| 
       186 
182 
     | 
    
         
             
                def remove_message(messages: dataframe.ln_DataFrame, node_id: str) -> bool:
         
     | 
| 
         @@ -188,15 +184,15 @@ class MessageUtil: 
     | 
|
| 
       188 
184 
     | 
    
         
             
                    Removes a message from the DataFrame based on its node ID.
         
     | 
| 
       189 
185 
     | 
    
         | 
| 
       190 
186 
     | 
    
         
             
                    Args:
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
      
 187 
     | 
    
         
            +
                            messages: The DataFrame containing messages.
         
     | 
| 
      
 188 
     | 
    
         
            +
                            node_id: The unique identifier of the message to be removed.
         
     | 
| 
       193 
189 
     | 
    
         | 
| 
       194 
190 
     | 
    
         
             
                    Returns:
         
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
      
 191 
     | 
    
         
            +
                            If any messages are removed.
         
     | 
| 
       196 
192 
     | 
    
         | 
| 
       197 
193 
     | 
    
         
             
                    Examples:
         
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
      
 194 
     | 
    
         
            +
                            >>> messages = dataframe.ln_DataFrame([...])
         
     | 
| 
      
 195 
     | 
    
         
            +
                            >>> updated_messages = MessageUtil.remove_message(messages, "node_id_123")
         
     | 
| 
       200 
196 
     | 
    
         
             
                    """
         
     | 
| 
       201 
197 
     | 
    
         | 
| 
       202 
198 
     | 
    
         
             
                    initial_length = len(messages)
         
     | 
| 
         @@ -218,15 +214,15 @@ class MessageUtil: 
     | 
|
| 
       218 
214 
     | 
    
         
             
                    Retrieves a specified number of message rows based on sender and role.
         
     | 
| 
       219 
215 
     | 
    
         | 
| 
       220 
216 
     | 
    
         
             
                    Args:
         
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
      
 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.
         
     | 
| 
       227 
223 
     | 
    
         | 
| 
       228 
224 
     | 
    
         
             
                    Returns:
         
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
      
 225 
     | 
    
         
            +
                            A DataFrame containing the filtered messages.
         
     | 
| 
       230 
226 
     | 
    
         
             
                    """
         
     | 
| 
       231 
227 
     | 
    
         | 
| 
       232 
228 
     | 
    
         
             
                    outs = ""
         
     | 
| 
         @@ -266,17 +262,17 @@ class MessageUtil: 
     | 
|
| 
       266 
262 
     | 
    
         
             
                    Extends a DataFrame with another DataFrame's rows, ensuring no duplicate 'node_id'.
         
     | 
| 
       267 
263 
     | 
    
         | 
| 
       268 
264 
     | 
    
         
             
                    Args:
         
     | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
       271 
     | 
    
         
            -
             
     | 
| 
      
 265 
     | 
    
         
            +
                            df1: The primary DataFrame.
         
     | 
| 
      
 266 
     | 
    
         
            +
                            df2: The DataFrame to merge with the primary DataFrame.
         
     | 
| 
      
 267 
     | 
    
         
            +
                            **kwargs: Additional keyword arguments for `drop_duplicates`.
         
     | 
| 
       272 
268 
     | 
    
         | 
| 
       273 
269 
     | 
    
         
             
                    Returns:
         
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
      
 270 
     | 
    
         
            +
                            A DataFrame combined from df1 and df2 with duplicates removed based on 'node_id'.
         
     | 
| 
       275 
271 
     | 
    
         | 
| 
       276 
272 
     | 
    
         
             
                    Examples:
         
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
      
 273 
     | 
    
         
            +
                            >>> df_main = dataframe.ln_DataFrame([...])
         
     | 
| 
      
 274 
     | 
    
         
            +
                            >>> df_additional = dataframe.ln_DataFrame([...])
         
     | 
| 
      
 275 
     | 
    
         
            +
                            >>> combined_df = MessageUtil.extend(df_main, df_additional, keep='first')
         
     | 
| 
       280 
276 
     | 
    
         
             
                    """
         
     | 
| 
       281 
277 
     | 
    
         | 
| 
       282 
278 
     | 
    
         
             
                    MessageUtil.validate_messages(df2)
         
     | 
| 
         @@ -288,7 +284,7 @@ class MessageUtil: 
     | 
|
| 
       288 
284 
     | 
    
         
             
                            )
         
     | 
| 
       289 
285 
     | 
    
         
             
                            return convert.to_df(df)
         
     | 
| 
       290 
286 
     | 
    
         
             
                    except Exception as e:
         
     | 
| 
       291 
     | 
    
         
            -
                        raise ValueError(f"Error in extending messages: {e}")
         
     | 
| 
      
 287 
     | 
    
         
            +
                        raise ValueError(f"Error in extending messages: {e}") from e
         
     | 
| 
       292 
288 
     | 
    
         | 
| 
       293 
289 
     | 
    
         
             
                @staticmethod
         
     | 
| 
       294 
290 
     | 
    
         
             
                def to_markdown_string(messages: dataframe.ln_DataFrame) -> str:
         
     | 
| 
         @@ -296,11 +292,11 @@ class MessageUtil: 
     | 
|
| 
       296 
292 
     | 
    
         
             
                    Converts messages in a DataFrame to a Markdown-formatted string for easy reading.
         
     | 
| 
       297 
293 
     | 
    
         | 
| 
       298 
294 
     | 
    
         
             
                    Args:
         
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
      
 295 
     | 
    
         
            +
                            messages: A DataFrame containing messages with columns for 'role' and 'content'.
         
     | 
| 
       300 
296 
     | 
    
         | 
| 
       301 
297 
     | 
    
         
             
                    Returns:
         
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
             
     | 
| 
      
 298 
     | 
    
         
            +
                            A string formatted in Markdown, where each message's content is presented
         
     | 
| 
      
 299 
     | 
    
         
            +
                            according to its role in a readable format.
         
     | 
| 
       304 
300 
     | 
    
         
             
                    """
         
     | 
| 
       305 
301 
     | 
    
         | 
| 
       306 
302 
     | 
    
         
             
                    answers = []
         
     | 
| 
         @@ -308,101 +304,20 @@ class MessageUtil: 
     | 
|
| 
       308 
304 
     | 
    
         
             
                        content = convert.to_dict(i.content)
         
     | 
| 
       309 
305 
     | 
    
         | 
| 
       310 
306 
     | 
    
         
             
                        if i.role == "assistant":
         
     | 
| 
       311 
     | 
    
         
            -
                             
     | 
| 
      
 307 
     | 
    
         
            +
                            with contextlib.suppress(Exception):
         
     | 
| 
       312 
308 
     | 
    
         
             
                                a = nested.nget(content, ["action_response", "func"])
         
     | 
| 
       313 
309 
     | 
    
         
             
                                b = nested.nget(content, ["action_response", "arguments"])
         
     | 
| 
       314 
310 
     | 
    
         
             
                                c = nested.nget(content, ["action_response", "output"])
         
     | 
| 
       315 
311 
     | 
    
         
             
                                if a is not None:
         
     | 
| 
       316 
     | 
    
         
            -
                                    answers. 
     | 
| 
       317 
     | 
    
         
            -
             
     | 
| 
       318 
     | 
    
         
            -
                                     
     | 
| 
      
 312 
     | 
    
         
            +
                                    answers.extend(
         
     | 
| 
      
 313 
     | 
    
         
            +
                                        (f"Function: {a}", f"Arguments: {b}", f"Output: {c}")
         
     | 
| 
      
 314 
     | 
    
         
            +
                                    )
         
     | 
| 
       319 
315 
     | 
    
         
             
                                else:
         
     | 
| 
       320 
316 
     | 
    
         
             
                                    answers.append(nested.nget(content, ["assistant_response"]))
         
     | 
| 
       321 
     | 
    
         
            -
                            except:
         
     | 
| 
       322 
     | 
    
         
            -
                                pass
         
     | 
| 
       323 
317 
     | 
    
         
             
                        elif i.role == "user":
         
     | 
| 
       324 
     | 
    
         
            -
                             
     | 
| 
      
 318 
     | 
    
         
            +
                            with contextlib.suppress(Exception):
         
     | 
| 
       325 
319 
     | 
    
         
             
                                answers.append(nested.nget(content, ["instruction"]))
         
     | 
| 
       326 
     | 
    
         
            -
                            except:
         
     | 
| 
       327 
     | 
    
         
            -
                                pass
         
     | 
| 
       328 
320 
     | 
    
         
             
                        else:
         
     | 
| 
       329 
     | 
    
         
            -
                             
     | 
| 
      
 321 
     | 
    
         
            +
                            with contextlib.suppress(Exception):
         
     | 
| 
       330 
322 
     | 
    
         
             
                                answers.append(nested.nget(content, ["system_info"]))
         
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
                                pass
         
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
     | 
    
         
            -
                    out_ = "\n".join(answers)
         
     | 
| 
       335 
     | 
    
         
            -
                    return out_
         
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
                # @staticmethod
         
     | 
| 
       338 
     | 
    
         
            -
                # def to_json_content(value):
         
     | 
| 
       339 
     | 
    
         
            -
                #     if isinstance(value, dict):
         
     | 
| 
       340 
     | 
    
         
            -
                #         for key, val in value.items():
         
     | 
| 
       341 
     | 
    
         
            -
                #             value[key] = MessageUtil.to_json_content(val)
         
     | 
| 
       342 
     | 
    
         
            -
                #         value = json.dumps(value)
         
     | 
| 
       343 
     | 
    
         
            -
                #     if isinstance(value, list):
         
     | 
| 
       344 
     | 
    
         
            -
                #         for i in range(len(value)):
         
     | 
| 
       345 
     | 
    
         
            -
                #             value[i] = MessageUtil.to_json_content(value[i])
         
     | 
| 
       346 
     | 
    
         
            -
                #     return value
         
     | 
| 
       347 
     | 
    
         
            -
             
     | 
| 
       348 
     | 
    
         
            -
                # @staticmethod
         
     | 
| 
       349 
     | 
    
         
            -
                # def to_dict_content(value):
         
     | 
| 
       350 
     | 
    
         
            -
                #     try:
         
     | 
| 
       351 
     | 
    
         
            -
                #         value = json.loads(value)
         
     | 
| 
       352 
     | 
    
         
            -
                #         if isinstance(value, dict):
         
     | 
| 
       353 
     | 
    
         
            -
                #             for key, val in value.items():
         
     | 
| 
       354 
     | 
    
         
            -
                #                 value[key] = MessageUtil.to_dict_content(val)
         
     | 
| 
       355 
     | 
    
         
            -
                #         if isinstance(value, list):
         
     | 
| 
       356 
     | 
    
         
            -
                #             for i in range(len(value)):
         
     | 
| 
       357 
     | 
    
         
            -
                #                 value[i] = MessageUtil.to_dict_content(value[i])
         
     | 
| 
       358 
     | 
    
         
            -
                #         return value
         
     | 
| 
       359 
     | 
    
         
            -
                #     except:
         
     | 
| 
       360 
     | 
    
         
            -
                #         return value
         
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
       362 
     | 
    
         
            -
                # @staticmethod
         
     | 
| 
       363 
     | 
    
         
            -
                # def response_to_message(response: dict[str, Any], **kwargs) -> Any:
         
     | 
| 
       364 
     | 
    
         
            -
                #     """
         
     | 
| 
       365 
     | 
    
         
            -
                #     Processes a message response dictionary to generate an appropriate message object.
         
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
       367 
     | 
    
         
            -
                #     Args:
         
     | 
| 
       368 
     | 
    
         
            -
                #         response: A dictionary potentially containing message information.
         
     | 
| 
       369 
     | 
    
         
            -
                #         **kwargs: Additional keyword arguments to pass to the message constructors.
         
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
                #     Returns:
         
     | 
| 
       372 
     | 
    
         
            -
                #         An instance of a message class, such as ActionRequest or AssistantResponse,
         
     | 
| 
       373 
     | 
    
         
            -
                #         depending on the content of the response.
         
     | 
| 
       374 
     | 
    
         
            -
                #     """
         
     | 
| 
       375 
     | 
    
         
            -
                #     try:
         
     | 
| 
       376 
     | 
    
         
            -
                #         response = response["message"]
         
     | 
| 
       377 
     | 
    
         
            -
                #         if .strip_lower(response['content']) == "none":
         
     | 
| 
       378 
     | 
    
         
            -
             
     | 
| 
       379 
     | 
    
         
            -
                #             content = ActionRequest._handle_action_request(response)
         
     | 
| 
       380 
     | 
    
         
            -
                #             return ActionRequest(action_request=content, **kwargs)
         
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
                #         else:
         
     | 
| 
       383 
     | 
    
         
            -
             
     | 
| 
       384 
     | 
    
         
            -
                #             try:
         
     | 
| 
       385 
     | 
    
         
            -
                #                 if 'tool_uses' in to_dict(response[MessageField.CONTENT.value]):
         
     | 
| 
       386 
     | 
    
         
            -
                #                     content_ = to_dict(response[MessageField.CONTENT.value])[
         
     | 
| 
       387 
     | 
    
         
            -
                #                         'tool_uses']
         
     | 
| 
       388 
     | 
    
         
            -
                #                     return ActionRequest(action_request=content_, **kwargs)
         
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
     | 
    
         
            -
                #                 elif MessageContentKey.RESPONSE.value in to_dict(
         
     | 
| 
       391 
     | 
    
         
            -
                #                         response[MessageField.CONTENT.value]):
         
     | 
| 
       392 
     | 
    
         
            -
                #                     content_ = to_dict(response[MessageField.CONTENT.value])[
         
     | 
| 
       393 
     | 
    
         
            -
                #                         MessageContentKey.RESPONSE.value]
         
     | 
| 
       394 
     | 
    
         
            -
                #                     return AssistantResponse(assistant_response=content_, **kwargs)
         
     | 
| 
       395 
     | 
    
         
            -
             
     | 
| 
       396 
     | 
    
         
            -
                #                 elif MessageContentKey.ACTION_REQUEST.value in to_dict(
         
     | 
| 
       397 
     | 
    
         
            -
                #                         response[MessageField.CONTENT.value]):
         
     | 
| 
       398 
     | 
    
         
            -
                #                     content_ = to_dict(response[MessageField.CONTENT.value])[
         
     | 
| 
       399 
     | 
    
         
            -
                #                         MessageContentKey.ACTION_REQUEST.value]
         
     | 
| 
       400 
     | 
    
         
            -
                #                     return ActionRequest(action_request=content_, **kwargs)
         
     | 
| 
       401 
     | 
    
         
            -
             
     | 
| 
       402 
     | 
    
         
            -
                #                 else:
         
     | 
| 
       403 
     | 
    
         
            -
                #                     return AssistantResponse(assistant_response=response, **kwargs)
         
     | 
| 
       404 
     | 
    
         
            -
             
     | 
| 
       405 
     | 
    
         
            -
                #             except:
         
     | 
| 
       406 
     | 
    
         
            -
                #                 return AssistantResponse(assistant_response=response, **kwargs)
         
     | 
| 
       407 
     | 
    
         
            -
                #     except:
         
     | 
| 
       408 
     | 
    
         
            -
                #         return ActionResponse(action_response=response, **kwargs)
         
     | 
| 
      
 323 
     | 
    
         
            +
                    return "\n".join(answers)
         
     |