lionagi 0.0.201__py3-none-any.whl → 0.0.204__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. lionagi/_services/anthropic.py +79 -1
  2. lionagi/_services/base_service.py +1 -1
  3. lionagi/_services/services.py +61 -25
  4. lionagi/_services/transformers.py +46 -0
  5. lionagi/agents/__init__.py +0 -0
  6. lionagi/configs/oai_configs.py +1 -1
  7. lionagi/configs/openrouter_configs.py +1 -1
  8. lionagi/core/__init__.py +3 -7
  9. lionagi/core/branch/__init__.py +0 -0
  10. lionagi/core/branch/branch.py +589 -0
  11. lionagi/core/branch/branch_manager.py +139 -0
  12. lionagi/core/branch/cluster.py +1 -0
  13. lionagi/core/branch/conversation.py +484 -0
  14. lionagi/core/core_util.py +59 -0
  15. lionagi/core/flow/__init__.py +0 -0
  16. lionagi/core/flow/flow.py +19 -0
  17. lionagi/core/instruction_set/__init__.py +0 -0
  18. lionagi/core/instruction_set/instruction_set.py +343 -0
  19. lionagi/core/messages/__init__.py +0 -0
  20. lionagi/core/messages/messages.py +176 -0
  21. lionagi/core/sessions/__init__.py +0 -0
  22. lionagi/core/sessions/session.py +428 -0
  23. lionagi/models/__init__.py +0 -0
  24. lionagi/models/base_model.py +0 -0
  25. lionagi/models/imodel.py +53 -0
  26. lionagi/schema/data_logger.py +75 -155
  27. lionagi/tests/test_utils/test_call_util.py +658 -657
  28. lionagi/tools/tool_manager.py +121 -188
  29. lionagi/utils/__init__.py +5 -10
  30. lionagi/utils/call_util.py +667 -585
  31. lionagi/utils/io_util.py +3 -0
  32. lionagi/utils/nested_util.py +17 -211
  33. lionagi/utils/pd_util.py +57 -0
  34. lionagi/utils/sys_util.py +220 -184
  35. lionagi/utils/url_util.py +55 -0
  36. lionagi/version.py +1 -1
  37. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/METADATA +12 -8
  38. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/RECORD +47 -32
  39. lionagi/core/branch.py +0 -193
  40. lionagi/core/conversation.py +0 -341
  41. lionagi/core/flow.py +0 -8
  42. lionagi/core/instruction_set.py +0 -150
  43. lionagi/core/messages.py +0 -243
  44. lionagi/core/sessions.py +0 -474
  45. /lionagi/{tools → agents}/planner.py +0 -0
  46. /lionagi/{tools → agents}/prompter.py +0 -0
  47. /lionagi/{tools → agents}/scorer.py +0 -0
  48. /lionagi/{tools → agents}/summarizer.py +0 -0
  49. /lionagi/{tools → agents}/validator.py +0 -0
  50. /lionagi/core/{flow_util.py → flow/flow_util.py} +0 -0
  51. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/LICENSE +0 -0
  52. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/WHEEL +0 -0
  53. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/top_level.txt +0 -0
@@ -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
-