lionagi 0.0.105__tar.gz → 0.0.106__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. {lionagi-0.0.105 → lionagi-0.0.106}/PKG-INFO +1 -1
  2. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/session/conversation.py +4 -3
  3. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/session/message.py +24 -21
  4. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/session/session.py +29 -11
  5. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/utils/tool_util.py +9 -9
  6. lionagi-0.0.106/lionagi/version.py +1 -0
  7. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi.egg-info/PKG-INFO +1 -1
  8. lionagi-0.0.105/lionagi/version.py +0 -1
  9. {lionagi-0.0.105 → lionagi-0.0.106}/LICENSE +0 -0
  10. {lionagi-0.0.105 → lionagi-0.0.106}/README.md +0 -0
  11. {lionagi-0.0.105 → lionagi-0.0.106}/README.rst +0 -0
  12. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/__init__.py +0 -0
  13. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/api/__init__.py +0 -0
  14. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/api/oai_config.py +0 -0
  15. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/api/oai_service.py +0 -0
  16. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/session/__init__.py +0 -0
  17. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/tools/__init__.py +0 -0
  18. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/utils/__init__.py +0 -0
  19. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/utils/api_util.py +0 -0
  20. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/utils/doc_util.py +0 -0
  21. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/utils/log_util.py +0 -0
  22. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi/utils/sys_util.py +0 -0
  23. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi.egg-info/SOURCES.txt +0 -0
  24. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi.egg-info/dependency_links.txt +0 -0
  25. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi.egg-info/requires.txt +0 -0
  26. {lionagi-0.0.105 → lionagi-0.0.106}/lionagi.egg-info/top_level.txt +0 -0
  27. {lionagi-0.0.105 → lionagi-0.0.106}/pyproject.toml +0 -0
  28. {lionagi-0.0.105 → lionagi-0.0.106}/setup.cfg +0 -0
  29. {lionagi-0.0.105 → lionagi-0.0.106}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lionagi
3
- Version: 0.0.105
3
+ Version: 0.0.106
4
4
  Summary: Towards automated general intelligence.
5
5
  Author: HaiyangLi
6
6
  Author-email: Haiyang Li <ocean@lionagi.ai>
@@ -40,7 +40,7 @@ class Conversation:
40
40
  self.msg = Message()
41
41
  self.responses = []
42
42
 
43
- def initiate_conversation(self, system, instruction, context=None, name=None):
43
+ def initiate_conversation(self, system=None, instruction=None, context=None, name=None):
44
44
  """
45
45
  Initiate a conversation with a system setting and user instruction.
46
46
 
@@ -55,7 +55,7 @@ class Conversation:
55
55
  self.add_messages(instruction=instruction, context=context, name=name)
56
56
 
57
57
  # modify the message adding to accomodate tools
58
- def add_messages(self, system=None, instruction=None, context=None, response=None, tool=None, name=None):
58
+ def add_messages(self, system=None, instruction=None, context=None, response=None, name=None):
59
59
  """
60
60
  Add messages to the conversation, including system setting, user instruction, and assistant response.
61
61
 
@@ -67,7 +67,8 @@ class Conversation:
67
67
  tool (dict): The tool information for the message. Default is None.
68
68
  name (str): The name associated with the message. Default is None.
69
69
  """
70
- msg = self.msg(system=system, instruction=instruction, context=context, response=response, tool=tool, name=name)
70
+ msg = self.msg(system=system, instruction=instruction, context=context,
71
+ response=response, name=name)
71
72
  self.messages.append(msg)
72
73
 
73
74
  def change_system(self, system):
@@ -40,7 +40,8 @@ class Message:
40
40
  self.metadata = None
41
41
  self._logger = DataLogger()
42
42
 
43
- def create_message(self, system=None, instruction=None, context=None, response=None, tool=None, name=None):
43
+ def create_message(self, system=None, instruction=None, context=None, response=None, name=None):
44
+
44
45
  """
45
46
  Create a message based on the provided information.
46
47
 
@@ -52,25 +53,29 @@ class Message:
52
53
  tool (dict): The tool information for the message. Default is None.
53
54
  name (str): The name associated with the message. Default is None.
54
55
  """
55
- if sum(l_call([system, instruction, response, tool], bool)) > 1:
56
+ if sum(l_call([system, instruction, response], bool)) > 1:
56
57
  raise ValueError("Error: Message cannot have more than one role.")
57
58
 
58
59
  else:
59
60
  if response:
60
61
  self.role = "assistant"
61
- response = response["message"]
62
- if str(response['content']) == "None":
63
- try:
64
- # currently can only support a single function response
65
- if response['tool_calls'][0]['type'] == 'function':
66
- self.name = name or ("func_" + response['tool_calls'][0]['function']['name'])
67
- content = response['tool_calls'][0]['function']['arguments']
68
- self.content = {"function":self.name, "arguments": content}
69
- except:
70
- raise ValueError("Response message must be one of regular response or function calling")
71
- else:
72
- self.content = response['content']
73
- self.name = name or "assistant"
62
+ try:
63
+ response = response["message"]
64
+ if str(response['content']) == "None":
65
+ try:
66
+ if response['tool_calls'][0]['type'] == 'function':
67
+ self.name = name or ("func_" + response['tool_calls'][0]['function']['name'])
68
+ content = response['tool_calls'][0]['function']['arguments']
69
+ self.content = {"function":self.name, "arguments": content}
70
+ except:
71
+ raise ValueError("Response message must be one of regular response or function calling")
72
+ else:
73
+ self.content = response['content']
74
+ self.name = name or "assistant"
75
+ except:
76
+ self.name = name or "func_call"
77
+ self.content = {"function call result": response}
78
+
74
79
  elif instruction:
75
80
  self.role = "user"
76
81
  self.content = {"instruction": instruction}
@@ -81,10 +86,6 @@ class Message:
81
86
  self.role = "system"
82
87
  self.content = system
83
88
  self.name = name or "system"
84
- elif tool:
85
- self.role = "tool"
86
- self.content = tool
87
- self.name = name or "tool"
88
89
 
89
90
  def to_json(self):
90
91
  """
@@ -106,7 +107,8 @@ class Message:
106
107
  self._logger({**self.metadata, **out})
107
108
  return out
108
109
 
109
- def __call__(self, system=None, instruction=None, context=None, response=None, name=None, tool=None):
110
+ def __call__(self, system=None, instruction=None, context=None,
111
+ response=None, name=None):
110
112
  """
111
113
  Create and return a message in JSON format.
112
114
 
@@ -121,7 +123,8 @@ class Message:
121
123
  Returns:
122
124
  dict: The message in JSON format.
123
125
  """
124
- self.create_message(system, instruction, context, response, tool, name)
126
+ self.create_message(system=system, instruction=instruction,
127
+ context=context, response=response, name=name)
125
128
  return self.to_json()
126
129
 
127
130
  def to_csv(self, dir=None, filename=None, verbose=True, timestamp=True, dir_exist_ok=True, file_exist_ok=False):
@@ -1,5 +1,6 @@
1
1
  import aiohttp
2
2
  import asyncio
3
+ import json
3
4
  from typing import Any
4
5
 
5
6
  from .conversation import Conversation
@@ -120,7 +121,7 @@ class Session():
120
121
  """
121
122
  self.api_service = api_service
122
123
 
123
- async def _output(self, output, invoke=True, out=True):
124
+ async def _output(self, invoke=True, out=True, tool_parser=None):
124
125
  """
125
126
  Process the output, invoke tools if needed, and optionally return the output.
126
127
 
@@ -134,13 +135,14 @@ class Session():
134
135
  """
135
136
  if invoke:
136
137
  try:
137
- func, args = self.toolmanager._get_function_call(output)
138
+ func, args = self.toolmanager._get_function_call(self.conversation.responses[-1]['content'])
138
139
  outs = await self.toolmanager.ainvoke(func, args)
139
- self.conversation.add_messages(tool=outs)
140
+ outs = tool_parser(outs) if tool_parser else outs
141
+ self.conversation.add_messages(response=outs)
140
142
  except:
141
143
  pass
142
144
  if out:
143
- return output
145
+ return self.conversation.responses[-1]['content']
144
146
 
145
147
  def register_tools(self, tools, funcs, update=False, new=False, prefix=None, postfix=None):
146
148
  """
@@ -157,7 +159,7 @@ class Session():
157
159
  funcs = to_list(funcs)
158
160
  self.toolmanager.register_tools(tools, funcs, update, new, prefix, postfix)
159
161
 
160
- async def initiate(self, instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
162
+ async def initiate(self, instruction, system=None, context=None, name=None, invoke=True, out=True, tool_parser=None, **kwargs) -> Any:
161
163
  """
162
164
  Start a new conversation session with the provided instruction.
163
165
 
@@ -177,11 +179,10 @@ class Session():
177
179
  system = system or self.system
178
180
  self.conversation.initiate_conversation(system=system, instruction=instruction, context=context, name=name)
179
181
  await self.call_chatcompletion(**config)
180
- output = self.conversation.responses[-1]['content']
181
182
 
182
- return await self._output(output, invoke, out)
183
+ return await self._output(invoke, out, tool_parser)
183
184
 
184
- async def followup(self, instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
185
+ async def followup(self, instruction, system=None, context=None, out=True, name=None, invoke=True, tool_parser=None, **kwargs) -> Any:
185
186
  """
186
187
  Continue the conversation with the provided instruction.
187
188
 
@@ -202,9 +203,9 @@ class Session():
202
203
  self.conversation.add_messages(instruction=instruction, context=context, name=name)
203
204
  config = {**self.llmconfig, **kwargs}
204
205
  await self.call_chatcompletion(**config)
205
- output = self.conversation.responses[-1]['content']
206
+
206
207
 
207
- return await self._output(output, invoke, out)
208
+ return await self._output(invoke, out, tool_parser)
208
209
 
209
210
  def create_payload_chatcompletion(self, **kwargs):
210
211
  """
@@ -288,4 +289,21 @@ class Session():
288
289
  dir = dir or self._logger.dir
289
290
  if dir is None:
290
291
  raise ValueError("No directory specified.")
291
- self._logger.to_csv(dir=dir, filename=filename, **kwags)
292
+ self._logger.to_csv(dir=dir, filename=filename, **kwags)
293
+
294
+ def is_invoked(self):
295
+ msg = self.conversation.messages[-1]
296
+ try:
297
+ if "function call result" in json.loads(msg['content']).keys():
298
+ return True
299
+ except:
300
+ return False
301
+
302
+ async def auto_followup(self, instruct, num=3, tool_parser=None, **kwags):
303
+ cont_ = True
304
+ while num > 0 and cont_ is True:
305
+ await self.followup(instruct,tool_parser=tool_parser, tool_choice="auto", **kwags)
306
+ num -= 1
307
+ cont_ = True if self.is_invoked() else False
308
+ if num == 0:
309
+ await self.followup(instruct, **kwags)
@@ -92,32 +92,32 @@ class ToolManager:
92
92
  name = f"{prefix or ''}{name}{postfix or '1'}" if new else name
93
93
  self.registry.update(self._to_dict(name, function, content))
94
94
 
95
- def invoke(self, name, args):
95
+ def invoke(self, name, kwargs):
96
96
  """
97
97
  Invoke a registered function with the provided arguments.
98
98
 
99
99
  Parameters:
100
100
  name (str): The name of the function to invoke.
101
- args (dict): The arguments to pass to the function.
101
+ kwargs (dict): The arguments to pass to the function.
102
102
 
103
103
  Returns:
104
104
  Any: The result of invoking the function.
105
105
  """
106
106
  if self._name_existed(name):
107
107
  try:
108
- return self.registry[name](**args)
108
+ return self.registry[name](**kwargs)
109
109
  except Exception as e:
110
- raise ValueError(f"Error when invoking function {name} with arguments {args} with error message {e}")
110
+ raise ValueError(f"Error when invoking function {name} with arguments {kwargs} with error message {e}")
111
111
  else:
112
112
  raise ValueError(f"Function {name} is not registered.")
113
113
 
114
- async def ainvoke(self, name, args):
114
+ async def ainvoke(self, name, kwargs):
115
115
  """
116
116
  Asynchronously invoke a registered function with the provided arguments.
117
117
 
118
118
  Parameters:
119
119
  name (str): The name of the function to invoke.
120
- args (dict): The arguments to pass to the function.
120
+ kwargs (dict): The arguments to pass to the function.
121
121
 
122
122
  Returns:
123
123
  Any: The result of invoking the function asynchronously.
@@ -127,11 +127,11 @@ class ToolManager:
127
127
  function = self.registry[name]["function"]
128
128
  try:
129
129
  if asyncio.iscoroutinefunction(function):
130
- return await function(**args)
130
+ return await function(**kwargs)
131
131
  else:
132
- return function(**args)
132
+ return function(**kwargs)
133
133
  except Exception as e:
134
- raise ValueError(f"Error when invoking function {name} with arguments {args} with error message {e}")
134
+ raise ValueError(f"Error when invoking function {name} with arguments {kwargs} with error message {e}")
135
135
  else:
136
136
  raise ValueError(f"Function {name} is not registered.")
137
137
 
@@ -0,0 +1 @@
1
+ __version__ = "0.0.106"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lionagi
3
- Version: 0.0.105
3
+ Version: 0.0.106
4
4
  Summary: Towards automated general intelligence.
5
5
  Author: HaiyangLi
6
6
  Author-email: Haiyang Li <ocean@lionagi.ai>
@@ -1 +0,0 @@
1
- __version__ = "0.0.105"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes