lionagi 0.0.201__py3-none-any.whl → 0.0.204__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lionagi/_services/anthropic.py +79 -1
- lionagi/_services/base_service.py +1 -1
- lionagi/_services/services.py +61 -25
- lionagi/_services/transformers.py +46 -0
- lionagi/agents/__init__.py +0 -0
- lionagi/configs/oai_configs.py +1 -1
- lionagi/configs/openrouter_configs.py +1 -1
- lionagi/core/__init__.py +3 -7
- lionagi/core/branch/__init__.py +0 -0
- lionagi/core/branch/branch.py +589 -0
- lionagi/core/branch/branch_manager.py +139 -0
- lionagi/core/branch/cluster.py +1 -0
- lionagi/core/branch/conversation.py +484 -0
- lionagi/core/core_util.py +59 -0
- lionagi/core/flow/__init__.py +0 -0
- lionagi/core/flow/flow.py +19 -0
- lionagi/core/instruction_set/__init__.py +0 -0
- lionagi/core/instruction_set/instruction_set.py +343 -0
- lionagi/core/messages/__init__.py +0 -0
- lionagi/core/messages/messages.py +176 -0
- lionagi/core/sessions/__init__.py +0 -0
- lionagi/core/sessions/session.py +428 -0
- lionagi/models/__init__.py +0 -0
- lionagi/models/base_model.py +0 -0
- lionagi/models/imodel.py +53 -0
- lionagi/schema/data_logger.py +75 -155
- lionagi/tests/test_utils/test_call_util.py +658 -657
- lionagi/tools/tool_manager.py +121 -188
- lionagi/utils/__init__.py +5 -10
- lionagi/utils/call_util.py +667 -585
- lionagi/utils/io_util.py +3 -0
- lionagi/utils/nested_util.py +17 -211
- lionagi/utils/pd_util.py +57 -0
- lionagi/utils/sys_util.py +220 -184
- lionagi/utils/url_util.py +55 -0
- lionagi/version.py +1 -1
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/METADATA +12 -8
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/RECORD +47 -32
- lionagi/core/branch.py +0 -193
- lionagi/core/conversation.py +0 -341
- lionagi/core/flow.py +0 -8
- lionagi/core/instruction_set.py +0 -150
- lionagi/core/messages.py +0 -243
- lionagi/core/sessions.py +0 -474
- /lionagi/{tools → agents}/planner.py +0 -0
- /lionagi/{tools → agents}/prompter.py +0 -0
- /lionagi/{tools → agents}/scorer.py +0 -0
- /lionagi/{tools → agents}/summarizer.py +0 -0
- /lionagi/{tools → agents}/validator.py +0 -0
- /lionagi/core/{flow_util.py → flow/flow_util.py} +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/LICENSE +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/WHEEL +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/top_level.txt +0 -0
lionagi/core/instruction_set.py
DELETED
@@ -1,150 +0,0 @@
|
|
1
|
-
from typing import List, Union
|
2
|
-
from ..schema import Tool
|
3
|
-
from ..structures import Relationship, Structure
|
4
|
-
from .messages import Instruction
|
5
|
-
|
6
|
-
|
7
|
-
# dynamically structured preconfigured instructions
|
8
|
-
class InstructionSet(Structure):
|
9
|
-
"""
|
10
|
-
Represents a set of instructions and their relationships to tools.
|
11
|
-
|
12
|
-
Attributes:
|
13
|
-
last_instruct (Optional[str]): ID of the last instruction added.
|
14
|
-
first_instruct (Optional[str]): ID of the first instruction added.
|
15
|
-
instruct_len (int): The total number of instructions.
|
16
|
-
|
17
|
-
Example usage:
|
18
|
-
>>> instruction_set = InstructionSet()
|
19
|
-
>>> instruction = Instruction(...)
|
20
|
-
>>> tool = Tool(...)
|
21
|
-
>>> instruction_set.add_instruction(instruction)
|
22
|
-
>>> instruction_set.add_instruction(instruction, tools=tool)
|
23
|
-
>>> instruction_set.pop_instruction()
|
24
|
-
>>> instruction_node = instruction_set.get_instruction_by_id('node_id')
|
25
|
-
>>> next_instruction = instruction_set.get_next_instruction(instruction_node)
|
26
|
-
>>> tools = instruction_set.get_associated_tools(instruction_node)
|
27
|
-
"""
|
28
|
-
last_instruct: str = None
|
29
|
-
first_instruct: str = None
|
30
|
-
instruct_len: int = 0
|
31
|
-
|
32
|
-
def add_instruction(self, instruction: Instruction, tools: Union[Tool, List[Tool]] = None):
|
33
|
-
"""
|
34
|
-
Add an instruction to the instruction set.
|
35
|
-
|
36
|
-
Args:
|
37
|
-
instruction (Instruction): The instruction to add.
|
38
|
-
tools (Union[Tool, List[Tool]], optional): The tool or list of tools related to the instruction.
|
39
|
-
|
40
|
-
Example usage:
|
41
|
-
>>> instruction_set = InstructionSet()
|
42
|
-
>>> instruction = Instruction(...)
|
43
|
-
>>> tool = Tool(...)
|
44
|
-
>>> instruction_set.push_instruction(instruction)
|
45
|
-
>>> instruction_set.push_instruction(instruction, tools=tool)
|
46
|
-
"""
|
47
|
-
|
48
|
-
if self.graph.is_empty():
|
49
|
-
self.graph.add_node(instruction)
|
50
|
-
self.last_instruct = instruction.id_
|
51
|
-
self.first_instruct = instruction.id_
|
52
|
-
else:
|
53
|
-
relationship = Relationship(source_node_id=self.last_instruct, target_node_id=instruction.id_, label='instruction')
|
54
|
-
self.graph.add_node(instruction)
|
55
|
-
self.graph.add_relationship(relationship)
|
56
|
-
self.last_instruct = instruction.id_
|
57
|
-
self.instruct_len += 1
|
58
|
-
|
59
|
-
if tools:
|
60
|
-
if isinstance(tools, Tool):
|
61
|
-
tools = [tools]
|
62
|
-
for tool in tools:
|
63
|
-
relationship = Relationship(source_node_id=tool.id_, target_node_id=self.last_instruct, label='tool')
|
64
|
-
self.graph.add_node(tool)
|
65
|
-
self.graph.add_relationship(relationship)
|
66
|
-
|
67
|
-
def pop_instruction(self):
|
68
|
-
"""
|
69
|
-
Remove the last instruction from the instruction set.
|
70
|
-
|
71
|
-
Example usage:
|
72
|
-
>>> instruction_set = InstructionSet()
|
73
|
-
>>> instruction_set.pop_instruction()
|
74
|
-
"""
|
75
|
-
if self.graph.is_empty():
|
76
|
-
return
|
77
|
-
elif self.instruct_len == 1:
|
78
|
-
self.graph.clear()
|
79
|
-
self.last_instruct = None
|
80
|
-
self.first_instruct = None
|
81
|
-
self.instruct_len -= 1
|
82
|
-
else:
|
83
|
-
relationships = self.get_node_relationships(self.graph.nodes[self.last_instruct], out_edge=False)
|
84
|
-
prev_instruct = None
|
85
|
-
for r in relationships:
|
86
|
-
if r.label != 'instruction':
|
87
|
-
self.graph.remove_node(self.graph.nodes[r.source_node_id])
|
88
|
-
else:
|
89
|
-
prev_instruct = r.source_node_id
|
90
|
-
|
91
|
-
self.graph.remove_node(self.graph.nodes[self.last_instruct])
|
92
|
-
self.last_instruct = prev_instruct
|
93
|
-
self.instruct_len -= 1
|
94
|
-
|
95
|
-
def get_instruction_by_id(self, node_id):
|
96
|
-
"""
|
97
|
-
Retrieve an instruction by its ID.
|
98
|
-
|
99
|
-
Args:
|
100
|
-
node_id (str): The ID of the instruction node.
|
101
|
-
|
102
|
-
Returns:
|
103
|
-
Instruction: The instruction node associated with the given ID.
|
104
|
-
|
105
|
-
Example usage:
|
106
|
-
>>> instruction_set = InstructionSet()
|
107
|
-
>>> instruction_node = instruction_set.get_instruction_by_id('node_id')
|
108
|
-
"""
|
109
|
-
return self.graph.nodes[node_id]
|
110
|
-
|
111
|
-
def get_next_instruction(self, instruct_node: Instruction):
|
112
|
-
"""
|
113
|
-
Retrieve the next instruction following the given instruction node.
|
114
|
-
|
115
|
-
Args:
|
116
|
-
instruct_node (Instruction): The current instruction node.
|
117
|
-
|
118
|
-
Returns:
|
119
|
-
Optional[Instruction]: The next instruction node in the sequence, if it exists.
|
120
|
-
|
121
|
-
Example usage:
|
122
|
-
>>> instruction_set = InstructionSet()
|
123
|
-
>>> current_node = Instruction(...)
|
124
|
-
>>> next_node = instruction_set.get_next_instruction(current_node)
|
125
|
-
"""
|
126
|
-
relationship = self.get_node_relationships(instruct_node)
|
127
|
-
if relationship:
|
128
|
-
return self.graph.nodes[relationship[0].target_node_id]
|
129
|
-
|
130
|
-
def get_tools(self, instruct_node: Instruction):
|
131
|
-
"""
|
132
|
-
Retrieve the tools associated with a given instruction node.
|
133
|
-
|
134
|
-
Args:
|
135
|
-
instruct_node (Instruction): The instruction node to retrieve tools for.
|
136
|
-
|
137
|
-
Returns:
|
138
|
-
List[Tool]: The tools associated with the instruction node.
|
139
|
-
|
140
|
-
Example usage:
|
141
|
-
>>> instruction_set = InstructionSet()
|
142
|
-
>>> instruction_node = Instruction(...)
|
143
|
-
>>> tools = instruction_set.get_tools(instruction_node)
|
144
|
-
"""
|
145
|
-
relationships = self.get_node_relationships(instruct_node, out_edge=False, labels=['tool'])
|
146
|
-
tools = []
|
147
|
-
for r in relationships:
|
148
|
-
tool = self.graph.nodes[r.source_node_id]
|
149
|
-
tools.append(tool)
|
150
|
-
return tools
|
lionagi/core/messages.py
DELETED
@@ -1,243 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
from typing import Any, Optional, Dict
|
3
|
-
from ..utils.sys_util import strip_lower, as_dict
|
4
|
-
from ..utils.nested_util import nget, to_readable_dict
|
5
|
-
from ..schema import BaseNode
|
6
|
-
|
7
|
-
|
8
|
-
class Message(BaseNode):
|
9
|
-
"""
|
10
|
-
Represents a message with associated role, name, and content.
|
11
|
-
|
12
|
-
Attributes:
|
13
|
-
role (Optional[str]): The role of the entity sending the message.
|
14
|
-
name (Optional[str]): The name of the entity sending the message.
|
15
|
-
content (Any): The content of the message.
|
16
|
-
"""
|
17
|
-
|
18
|
-
role: Optional[str] = None
|
19
|
-
name: Optional[str] = None
|
20
|
-
|
21
|
-
@property
|
22
|
-
def msg(self) -> Dict[str, Any]:
|
23
|
-
"""The message as a dictionary.
|
24
|
-
|
25
|
-
Returns:
|
26
|
-
Dict[str, Any]: The message in dictionary form with 'role' or 'name' as a key.
|
27
|
-
"""
|
28
|
-
return self._to_message()
|
29
|
-
|
30
|
-
@property
|
31
|
-
def named_msg(self) -> Dict[str, Any]:
|
32
|
-
"""The message as a dictionary with the sender's name.
|
33
|
-
|
34
|
-
Returns:
|
35
|
-
Dict[str, Any]: The message in dictionary form with 'name' as a key.
|
36
|
-
"""
|
37
|
-
return self._to_message(use_name=True)
|
38
|
-
|
39
|
-
@property
|
40
|
-
def msg_content(self) -> Any:
|
41
|
-
"""The content of the message.
|
42
|
-
|
43
|
-
Returns:
|
44
|
-
Any: The content of the message.
|
45
|
-
"""
|
46
|
-
return self.msg['content']
|
47
|
-
|
48
|
-
@property
|
49
|
-
def sender(self) -> str:
|
50
|
-
"""The name of the sender of the message.
|
51
|
-
|
52
|
-
Returns:
|
53
|
-
Optional[str]: The name of the sender.
|
54
|
-
"""
|
55
|
-
return self.name
|
56
|
-
|
57
|
-
@property
|
58
|
-
def readable_content(self) -> str:
|
59
|
-
"""The content of the message in a human-readable format.
|
60
|
-
|
61
|
-
Returns:
|
62
|
-
str: The message content as a human-readable string.
|
63
|
-
"""
|
64
|
-
return to_readable_dict(self.content)
|
65
|
-
|
66
|
-
@staticmethod
|
67
|
-
def create_system(content: Any, name: Optional[str] = None):
|
68
|
-
"""Create a system message.
|
69
|
-
|
70
|
-
Args:
|
71
|
-
content (Any): The content of the system message.
|
72
|
-
name (Optional[str]): The name of the system.
|
73
|
-
|
74
|
-
Returns:
|
75
|
-
System: The created system message.
|
76
|
-
"""
|
77
|
-
return System(system=content, name=name)
|
78
|
-
|
79
|
-
@staticmethod
|
80
|
-
def create_instruction(
|
81
|
-
content: Any, context: Optional[Any] = None, name: Optional[str] = None
|
82
|
-
) -> "Instruction":
|
83
|
-
"""Create an instruction message.
|
84
|
-
|
85
|
-
Args:
|
86
|
-
content (Any): The content of the instruction.
|
87
|
-
context (Optional[Any]): Additional context for the instruction.
|
88
|
-
name (Optional[str]): The name of the sender.
|
89
|
-
|
90
|
-
Returns:
|
91
|
-
Instruction: The created instruction message.
|
92
|
-
"""
|
93
|
-
return Instruction(instruction=content, context=context, name=name)
|
94
|
-
|
95
|
-
@staticmethod
|
96
|
-
def create_response(content: Any, name: Optional[str] = None) -> "Response":
|
97
|
-
"""Create a response message.
|
98
|
-
|
99
|
-
Args:
|
100
|
-
content (Any): The content of the response.
|
101
|
-
name (Optional[str]): The name of the sender.
|
102
|
-
|
103
|
-
Returns:
|
104
|
-
Response: The created response message.
|
105
|
-
"""
|
106
|
-
return Response(response=content, name=name)
|
107
|
-
|
108
|
-
def _to_message(self, use_name: bool = False) -> Dict[str, Any]:
|
109
|
-
"""Convert the message to a dictionary.
|
110
|
-
|
111
|
-
Args:
|
112
|
-
use_name (bool): Whether to use the sender's name as a key.
|
113
|
-
|
114
|
-
Returns:
|
115
|
-
Dict[str, Any]: The message in dictionary form.
|
116
|
-
"""
|
117
|
-
out = {"name": self.name} if use_name else {"role": self.role}
|
118
|
-
out['content'] = json.dumps(self.content) if isinstance(self.content, dict) else self.content
|
119
|
-
return out
|
120
|
-
|
121
|
-
def to_plain_text(self) -> str:
|
122
|
-
"""Convert the message content to plain text.
|
123
|
-
|
124
|
-
Returns:
|
125
|
-
str: The plain text content of the message.
|
126
|
-
"""
|
127
|
-
if isinstance(self.content, str):
|
128
|
-
return self.content
|
129
|
-
elif isinstance(self.content, dict):
|
130
|
-
return json.dumps(self.content)
|
131
|
-
elif self.content is None:
|
132
|
-
return ""
|
133
|
-
else:
|
134
|
-
return str(self.content)
|
135
|
-
|
136
|
-
def __str__(self) -> str:
|
137
|
-
"""String representation of the Message object.
|
138
|
-
|
139
|
-
Returns:
|
140
|
-
str: The string representation of the message.
|
141
|
-
"""
|
142
|
-
content_preview = self.to_plain_text()[:75] + "..." if len(self.to_plain_text()) > 75 else self.to_plain_text()
|
143
|
-
return f"Message(role={self.role}, name={self.name}, content='{content_preview}')"
|
144
|
-
|
145
|
-
|
146
|
-
class System(Message):
|
147
|
-
"""Represents a system message."""
|
148
|
-
|
149
|
-
def __init__(self, system: Any, name: Optional[str] = None):
|
150
|
-
"""Initialize the System message.
|
151
|
-
|
152
|
-
Args:
|
153
|
-
system (Any): The content of the system message.
|
154
|
-
name (Optional[str]): The name of the system.
|
155
|
-
"""
|
156
|
-
super().__init__(role="system", name=name or 'system', content={"system_info": system})
|
157
|
-
|
158
|
-
|
159
|
-
class Instruction(Message):
|
160
|
-
"""Represents an instruction message."""
|
161
|
-
|
162
|
-
def __init__(self, instruction: Any, context=None, name: Optional[str] = None):
|
163
|
-
"""Initialize the Instruction message.
|
164
|
-
|
165
|
-
Args:
|
166
|
-
instruction (Any): The content of the instruction.
|
167
|
-
context (Optional[Any]): Additional context for the instruction.
|
168
|
-
name (Optional[str]): The name of the sender.
|
169
|
-
"""
|
170
|
-
|
171
|
-
super().__init__(role="user", name=name or 'user', content={"instruction": instruction})
|
172
|
-
if context:
|
173
|
-
self.content.update({"context": context})
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
class Response(Message):
|
179
|
-
|
180
|
-
def __init__(self, response: Any, name: Optional[str] = None, content_key=None) -> None:
|
181
|
-
try:
|
182
|
-
response = response["message"]
|
183
|
-
|
184
|
-
if strip_lower(response['content']) == "none":
|
185
|
-
content_ = self._handle_action_request(response)
|
186
|
-
name = name or "action_request"
|
187
|
-
content_key = content_key or "action_list"
|
188
|
-
|
189
|
-
else:
|
190
|
-
try:
|
191
|
-
if 'tool_uses' in json.loads(response['content']):
|
192
|
-
content_ = json.loads(response['content'])['tool_uses']
|
193
|
-
content_key = content_key or "action_list"
|
194
|
-
name = name or "action_request"
|
195
|
-
else:
|
196
|
-
content_ = response['content']
|
197
|
-
content_key = content_key or "response"
|
198
|
-
name = name or "assistant"
|
199
|
-
except:
|
200
|
-
content_ = response['content']
|
201
|
-
content_key = content_key or "response"
|
202
|
-
name = name or "assistant"
|
203
|
-
|
204
|
-
except:
|
205
|
-
name = name or "action_response"
|
206
|
-
content_ = response
|
207
|
-
content_key = content_key or "action_response"
|
208
|
-
|
209
|
-
super().__init__(role="assistant", name=name, content={content_key: content_})
|
210
|
-
|
211
|
-
@staticmethod
|
212
|
-
def _handle_action_request(response):
|
213
|
-
"""Handle an action request from the response.
|
214
|
-
|
215
|
-
Args:
|
216
|
-
response (Dict[str, Any]): The response dictionary containing the action request.
|
217
|
-
|
218
|
-
Returns:
|
219
|
-
List[Dict[str, Any]]: The list of actions parsed from the request.
|
220
|
-
|
221
|
-
Raises:
|
222
|
-
ValueError: If the response does not contain valid function calling information.
|
223
|
-
"""
|
224
|
-
try:
|
225
|
-
tool_count = 0
|
226
|
-
func_list = []
|
227
|
-
while tool_count < len(response['tool_calls']):
|
228
|
-
_path = ['tool_calls', tool_count, 'type']
|
229
|
-
|
230
|
-
if nget(response, _path) == 'function':
|
231
|
-
_path1 = ['tool_calls', tool_count, 'function', 'name']
|
232
|
-
_path2 = ['tool_calls', tool_count, 'function', 'arguments']
|
233
|
-
|
234
|
-
func_content = {
|
235
|
-
"action": ("action_" + nget(response, _path1)),
|
236
|
-
"arguments": nget(response, _path2)
|
237
|
-
}
|
238
|
-
func_list.append(func_content)
|
239
|
-
tool_count += 1
|
240
|
-
return func_list
|
241
|
-
except:
|
242
|
-
raise ValueError("Response message must be one of regular response or function calling")
|
243
|
-
|