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.
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
-