lionagi 0.0.104__py3-none-any.whl → 0.0.105__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.
@@ -2,87 +2,91 @@ from .message import Message
2
2
 
3
3
  class Conversation:
4
4
  """
5
- A class modeling conversations and managing messages within the conversation.
5
+ A class representing a conversation between users and the assistant.
6
6
 
7
- This class facilitates the organization and manipulation of messages in a conversation.
8
- It includes methods for initiating a conversation, adding messages, changing the system message,
9
- appending the last response, and keeping the last N exchanges.
7
+ This class manages the exchange of messages within a conversation, including system settings,
8
+ user instructions, and assistant responses.
10
9
 
11
10
  Attributes:
12
- response_counts: A class-level attribute to track the number of responses.
13
- messages: A list containing messages in the conversation.
14
- msg: An instance of the Message class for creating and processing messages.
15
- responses: A list containing response messages.
11
+ response_counts (int): The count of assistant responses in the conversation.
12
+ messages (list): A list to store messages in the conversation.
13
+ msg (Message): An instance of the Message class for creating messages.
14
+ responses (list): A list to store assistant responses in the conversation.
16
15
 
17
16
  Methods:
18
- initiate_conversation: Start a new conversation with system and user instructions.
19
- add_messages: Add messages to the conversation.
20
- change_system: Change the system message in the conversation.
21
- append_last_response: Append the last response to the conversation.
22
- keep_last_n_exchanges: Keep only the last N exchanges in the conversation.
17
+ initiate_conversation(system, instruction, context=None, name=None):
18
+ Initiate a conversation with a system setting and user instruction.
19
+
20
+ add_messages(system, instruction, context=None, response=None, tool=None, name=None):
21
+ Add messages to the conversation, including system setting, user instruction, and assistant response.
22
+
23
+ change_system(system):
24
+ Change the system setting in the conversation.
25
+
26
+ keep_last_n_exchanges(n: int):
27
+ Keep the last n exchanges in the conversation.
23
28
  """
24
-
25
29
  response_counts = 0
26
30
 
27
31
  def __init__(self, messages=None) -> None:
28
32
  """
29
33
  Initialize a Conversation object.
30
34
 
31
- Args:
32
- messages: A list of messages to initialize the conversation.
35
+ Parameters:
36
+ messages (list): A list of messages to initialize the conversation. Default is None.
37
+
33
38
  """
34
39
  self.messages = messages or []
35
40
  self.msg = Message()
36
41
  self.responses = []
37
42
 
38
- def initiate_conversation(self, system, instruction, context=None):
43
+ def initiate_conversation(self, system, instruction, context=None, name=None):
39
44
  """
40
- Start a new conversation with a system message and an instruction.
45
+ Initiate a conversation with a system setting and user instruction.
41
46
 
42
- Args:
43
- system: The content of the system message.
44
- instruction: The content of the user instruction.
45
- context: Additional context for the user instruction.
47
+ Parameters:
48
+ system (str): The system setting for the conversation.
49
+ instruction (str): The user instruction to initiate the conversation.
50
+ context (dict): Additional context for the conversation. Default is None.
51
+ name (str): The name associated with the user. Default is None.
46
52
  """
47
53
  self.messages, self.responses = [], []
48
54
  self.add_messages(system=system)
49
- self.add_messages(instruction=instruction, context=context)
55
+ self.add_messages(instruction=instruction, context=context, name=name)
50
56
 
51
- def add_messages(self, system=None, instruction=None, context=None, response=None):
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):
52
59
  """
53
- Add messages to the conversation.
60
+ Add messages to the conversation, including system setting, user instruction, and assistant response.
54
61
 
55
- Args:
56
- system: The content of the system message.
57
- instruction: The content of the user instruction.
58
- context: Additional context for the user instruction.
59
- response: The content of the assistant's response.
62
+ Parameters:
63
+ system (str): The system setting for the message. Default is None.
64
+ instruction (str): The instruction content for the message. Default is None.
65
+ context (dict): Additional context for the message. Default is None.
66
+ response (dict): The response content for the message. Default is None.
67
+ tool (dict): The tool information for the message. Default is None.
68
+ name (str): The name associated with the message. Default is None.
60
69
  """
61
- msg = self.msg(system=system, instruction=instruction, response=response, context=context)
70
+ msg = self.msg(system=system, instruction=instruction, context=context, response=response, tool=tool, name=name)
62
71
  self.messages.append(msg)
63
72
 
64
73
  def change_system(self, system):
65
74
  """
66
- Change the system message in the conversation.
75
+ Change the system setting in the conversation.
67
76
 
68
- Args:
69
- system: The new content for the system message.
77
+ Parameters:
78
+ system (str): The new system setting for the conversation.
70
79
  """
71
80
  self.messages[0] = self.msg(system=system)
72
81
 
73
- def append_last_response(self):
74
- """
75
- Append the last response to the conversation.
76
- """
77
- self.add_messages(response=self.responses[-1])
78
-
79
82
  def keep_last_n_exchanges(self, n: int):
80
83
  """
81
- Keep only the last N exchanges in the conversation.
84
+ Keep the last n exchanges in the conversation.
82
85
 
83
- Args:
84
- n: The number of exchanges to keep.
86
+ Parameters:
87
+ n (int): The number of exchanges to keep.
85
88
  """
89
+ # keep last n_exchanges, one exchange is marked by one assistant response
86
90
  response_indices = [
87
91
  index for index, message in enumerate(self.messages[1:]) if message["role"] == "assistant"
88
92
  ]
@@ -1,76 +1,139 @@
1
1
  from datetime import datetime
2
2
  import json
3
- from ..utils.sys_util import create_id
3
+ from ..utils.sys_util import create_id, l_call
4
4
  from ..utils.log_util import DataLogger
5
5
 
6
6
 
7
7
  class Message:
8
8
  """
9
- A class modeling messages in conversations.
9
+ A class representing a message in a conversation.
10
10
 
11
- This class is designed to encapsulate messages exchanged between different roles
12
- (user, assistant, or system) in a conversation. It includes functionality to process,
13
- log, and manage messages.
11
+ This class encapsulates messages from users, the assistant, systems, and external tools.
14
12
 
15
13
  Attributes:
16
- role: The role of the message (user, assistant, or system).
17
- content: The content of the message.
18
- sender: The sender of the message.
19
- logger: An instance of DataLogger for logging message information.
14
+ role (str): The role of the message, indicating if it's from the user, assistant, system, or tool.
15
+ content: The content of the message, which can be an instruction, response, system setting, or tool information.
16
+ name (str): The name associated with the message, specifying the source (user, assistant, system, or tool).
17
+ metadata (dict): Additional metadata including id, timestamp, and name.
18
+ _logger (DataLogger): An instance of the DataLogger class for logging message details.
20
19
 
21
20
  Methods:
22
- __call__: Process and log a message based on its role.
21
+ create_message(system, instruction, context, response, tool, name):
22
+ Create a message based on the provided information.
23
+
24
+ to_json() -> dict:
25
+ Convert the message to a JSON format.
26
+
27
+ __call__(system, instruction, context, response, name, tool) -> dict:
28
+ Create and return a message in JSON format.
29
+
30
+ to_csv(dir, filename, verbose, timestamp, dir_exist_ok, file_exist_ok):
31
+ Save the message to a CSV file.
23
32
  """
24
33
  def __init__(self) -> None:
25
34
  """
26
- Initialize a Message object with attributes for role, content, sender, and a DataLogger.
35
+ Initialize a Message object.
27
36
  """
28
37
  self.role = None
29
38
  self.content = None
30
- self.sender = None
31
- self.logger = DataLogger()
32
-
33
- def __call__(self, system=None, instruction=None, response=None, context=None, sender=None):
39
+ self.name = None
40
+ self.metadata = None
41
+ self._logger = DataLogger()
42
+
43
+ def create_message(self, system=None, instruction=None, context=None, response=None, tool=None, name=None):
34
44
  """
35
- Process and log a message based on the specified role (system, instruction, or response).
45
+ Create a message based on the provided information.
36
46
 
37
- Args:
38
- system: The content of the message in the system role.
39
- instruction: The content of the message in the user role.
40
- response: The content of the message in the assistant role.
41
- context: Additional context for the user instruction.
42
- sender: The sender of the message.
47
+ Parameters:
48
+ system (str): The system setting for the message. Default is None.
49
+ instruction (str): The instruction content for the message. Default is None.
50
+ context (dict): Additional context for the message. Default is None.
51
+ response (dict): The response content for the message. Default is None.
52
+ tool (dict): The tool information for the message. Default is None.
53
+ name (str): The name associated with the message. Default is None.
43
54
  """
55
+ if sum(l_call([system, instruction, response, tool], bool)) > 1:
56
+ raise ValueError("Error: Message cannot have more than one role.")
44
57
 
45
- if sum(map(bool, [system, instruction, response])) > 1:
46
- raise ValueError("Message cannot have more than one role.")
47
- else:
58
+ else:
48
59
  if response:
49
60
  self.role = "assistant"
50
- self.sender = sender or "assistant"
51
- self.content = response['content']
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"
52
74
  elif instruction:
53
75
  self.role = "user"
54
- self.sender = sender or "user"
55
76
  self.content = {"instruction": instruction}
77
+ self.name = name or "user"
56
78
  if context:
57
- self.content.update(context)
79
+ self.content.update({"context": context})
58
80
  elif system:
59
81
  self.role = "system"
60
- self.sender = sender or "system"
61
82
  self.content = system
83
+ self.name = name or "system"
84
+ elif tool:
85
+ self.role = "tool"
86
+ self.content = tool
87
+ self.name = name or "tool"
88
+
89
+ def to_json(self):
90
+ """
91
+ Convert the message to a JSON format.
92
+
93
+ Returns:
94
+ - dict: The message in JSON format.
95
+ """
62
96
  out = {
63
97
  "role": self.role,
64
98
  "content": json.dumps(self.content) if isinstance(self.content, dict) else self.content
65
99
  }
66
-
67
- a = {**{
100
+
101
+ self.metadata = {
68
102
  "id": create_id(),
69
103
  "timestamp": datetime.now().isoformat(),
70
- "sender": self.sender
71
- }, **out}
72
- self.logger(a)
104
+ "name": self.name}
105
+
106
+ self._logger({**self.metadata, **out})
73
107
  return out
108
+
109
+ def __call__(self, system=None, instruction=None, context=None, response=None, name=None, tool=None):
110
+ """
111
+ Create and return a message in JSON format.
112
+
113
+ Parameters:
114
+ system (str): The system setting for the message. Default is None.
115
+ instruction (str): The instruction content for the message. Default is None.
116
+ context (dict): Additional context for the message. Default is None.
117
+ response (dict): The response content for the message. Default is None.
118
+ name (str): The name associated with the message. Default is None.
119
+ tool (dict): The tool information for the message. Default is None.
120
+
121
+ Returns:
122
+ dict: The message in JSON format.
123
+ """
124
+ self.create_message(system, instruction, context, response, tool, name)
125
+ return self.to_json()
74
126
 
75
- def _to_csv(self, dir, filename, verbose=True, timestamp=True, dir_exist_ok=True, file_exist_ok=False):
76
- self.logger.to_csv(dir, filename, verbose, timestamp, dir_exist_ok, file_exist_ok)
127
+ def to_csv(self, dir=None, filename=None, verbose=True, timestamp=True, dir_exist_ok=True, file_exist_ok=False):
128
+ """
129
+ Save the message to a CSV file.
130
+
131
+ Parameters:
132
+ dir (str): The directory path for saving the CSV file. Default is None.
133
+ filename (str): The filename for the CSV file. Default is None.
134
+ verbose (bool): Whether to include verbose information in the CSV. Default is True.
135
+ timestamp (bool): Whether to include timestamps in the CSV. Default is True.
136
+ dir_exist_ok (bool): Whether to allow the directory to exist. Default is True.
137
+ file_exist_ok (bool): Whether to allow the file to exist. Default is False.
138
+ """
139
+ self._logger.to_csv(dir, filename, verbose, timestamp, dir_exist_ok, file_exist_ok)
@@ -3,108 +3,222 @@ import asyncio
3
3
  from typing import Any
4
4
 
5
5
  from .conversation import Conversation
6
- from ..api.oai_config import oai_llmconfig
6
+ from ..utils.sys_util import to_list
7
7
  from ..utils.log_util import DataLogger
8
8
  from ..utils.api_util import StatusTracker
9
+ from ..utils.tool_util import ToolManager
9
10
  from ..api.oai_service import OpenAIService
10
11
 
12
+ from ..api.oai_config import oai_llmconfig
13
+
11
14
 
12
15
  status_tracker = StatusTracker()
13
16
  OAIService = OpenAIService()
14
17
 
15
18
  class Session():
16
19
  """
17
- A class representing a conversation session with chat completion capabilities.
20
+ A class representing a conversation session with a conversational AI system.
18
21
 
19
- This class manages conversations, interacts with chat completion services (currently OpenAI),
20
- and logs the interactions using a DataLogger.
22
+ This class manages the flow of conversation, system settings, and interactions with external tools.
21
23
 
22
24
  Attributes:
23
- conversation: An instance of the Conversation class for managing messages.
24
- system: The system identifier for the conversation session.
25
- llmconfig: Configuration parameters for language models.
26
- logger: An instance of DataLogger for logging conversation interactions.
27
- api_service: An instance of the API service for making asynchronous API calls.
25
+ conversation (Conversation): An instance of the Conversation class to manage messages.
26
+ system (str): The current system setting for the conversation.
27
+ llmconfig (dict): Configuration settings for the language model.
28
+ _logger (DataLogger): An instance of the DataLogger class for logging conversation details.
29
+ api_service: An instance of the API service for making calls to the conversational AI model.
30
+ toolmanager (ToolManager): An instance of the ToolManager class for managing external tools.
28
31
 
29
32
  Methods:
30
- initiate: Initiate a conversation session with the given instruction.
31
- followup: Continue the conversation session with a follow-up instruction.
32
- create_payload_chatcompletion: Create a payload for chat completion API calls.
33
- call_chatcompletion: Make an asynchronous call to the chat completion API.
33
+ set_dir(dir):
34
+ Set the directory for logging.
35
+
36
+ set_system(system):
37
+ Set the system for the conversation.
38
+
39
+ set_llmconfig(llmconfig):
40
+ Set the language model configuration.
41
+
42
+ set_api_service(api_service):
43
+ Set the API service for making model calls.
44
+
45
+ _output(output, invoke=True, out=True) -> Any:
46
+ Process the output, invoke tools if needed, and optionally return the output.
47
+
48
+ register_tools(tools, funcs, update=False, new=False, prefix=None, postfix=None):
49
+ Register tools and their corresponding functions.
50
+
51
+ initiate(instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
52
+ Start a new conversation session with the provided instruction.
53
+
54
+ followup(instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
55
+ Continue the conversation with the provided instruction.
56
+
57
+ create_payload_chatcompletion(**kwargs) -> dict:
58
+ Create a payload for chat completion based on the conversation state and configuration.
59
+
60
+ call_chatcompletion(sleep=0.1, **kwargs) -> None:
61
+ Make a call to the chat completion API and process the response.
62
+
63
+ messages_to_csv(dir=None, filename="_messages.csv", **kwargs) -> None:
64
+ Save conversation messages to a CSV file.
65
+
66
+ log_to_csv(dir=None, filename="_llmlog.csv", **kwargs) -> None:
67
+ Save conversation logs to a CSV file.
34
68
  """
35
69
 
36
70
  def __init__(self, system, dir=None, llmconfig=oai_llmconfig, api_service=OAIService):
37
71
  """
38
- Initialize a Session object.
72
+ Initialize a Session object with default or provided settings.
39
73
 
40
- Args:
41
- system: The system identifier for the conversation session.
42
- dir: The directory for logging interactions.
43
- llmconfig: Configuration parameters for language models.
44
- api_service: An instance of the API service for making asynchronous API calls.
74
+ Parameters:
75
+ system (str): The initial system setting for the conversation.
76
+ dir (Optional[str]): The directory for logging. Default is None.
77
+ llmconfig (Optional[dict]): Configuration settings for the language model. Default is oai_llmconfig.
78
+ api_service: An instance of the API service for making calls to the conversational AI model.
45
79
  """
46
80
  self.conversation = Conversation()
47
81
  self.system = system
48
82
  self.llmconfig = llmconfig
49
- self.logger = DataLogger(dir=dir)
83
+ self._logger = DataLogger(dir=dir)
84
+ self.api_service = api_service
85
+ self.toolmanager = ToolManager()
86
+
87
+ def set_dir(self, dir):
88
+ """
89
+ Set the directory for logging.
90
+
91
+ Parameters:
92
+ dir (str): The directory path.
93
+ """
94
+ self._logger.dir = dir
95
+
96
+ def set_system(self, system):
97
+ """
98
+ Set the system for the conversation.
99
+
100
+ Parameters:
101
+ system (str): The system setting.
102
+ """
103
+ self.conversation.change_system(system)
104
+
105
+ def set_llmconfig(self, llmconfig):
106
+ """
107
+ Set the language model configuration.
108
+
109
+ Parameters:
110
+ llmconfig (dict): Configuration settings for the language model.
111
+ """
112
+ self.llmconfig = llmconfig
113
+
114
+ def set_api_service(self, api_service):
115
+ """
116
+ Set the API service for making model calls.
117
+
118
+ Parameters:
119
+ api_service: An instance of the API service.
120
+ """
50
121
  self.api_service = api_service
51
122
 
52
- async def initiate(self, instruction, system=None, context=None, out=True, **kwargs) -> Any:
123
+ async def _output(self, output, invoke=True, out=True):
53
124
  """
54
- Initiate a conversation session with the given instruction.
125
+ Process the output, invoke tools if needed, and optionally return the output.
55
126
 
56
- Args:
57
- instruction: The user's instruction to initiate the conversation.
58
- system: The content of the system message.
59
- context: Additional context for the user instruction.
60
- out: Whether to return the output content.
127
+ Parameters:
128
+ output: The output to process.
129
+ invoke (bool): Whether to invoke tools based on the output. Default is True.
130
+ out (bool): Whether to return the output. Default is True.
61
131
 
62
132
  Returns:
63
- Any: The output content if 'out' is True, otherwise None.
133
+ Any: The processed output.
134
+ """
135
+ if invoke:
136
+ try:
137
+ func, args = self.toolmanager._get_function_call(output)
138
+ outs = await self.toolmanager.ainvoke(func, args)
139
+ self.conversation.add_messages(tool=outs)
140
+ except:
141
+ pass
142
+ if out:
143
+ return output
144
+
145
+ def register_tools(self, tools, funcs, update=False, new=False, prefix=None, postfix=None):
146
+ """
147
+ Register tools and their corresponding functions.
148
+
149
+ Parameters:
150
+ tools (list): The list of tool information dictionaries.
151
+ funcs (list): The list of corresponding functions.
152
+ update (bool): Whether to update existing functions.
153
+ new (bool): Whether to create new registries for existing functions.
154
+ prefix (Optional[str]): A prefix to add to the function names.
155
+ postfix (Optional[str]): A postfix to add to the function names.
156
+ """
157
+ funcs = to_list(funcs)
158
+ self.toolmanager.register_tools(tools, funcs, update, new, prefix, postfix)
159
+
160
+ async def initiate(self, instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
161
+ """
162
+ Start a new conversation session with the provided instruction.
163
+
164
+ Parameters:
165
+ instruction (str): The instruction to initiate the conversation.
166
+ system (Optional[str]): The system setting for the conversation. Default is None.
167
+ context (Optional[dict]): Additional context for the instruction. Default is None.
168
+ out (bool): Whether to return the output. Default is True.
169
+ name (Optional[str]): The name associated with the instruction. Default is None.
170
+ invoke (bool): Whether to invoke tools based on the output. Default is True.
171
+ kwargs: Additional keyword arguments for configuration.
172
+
173
+ Returns:
174
+ Any: The processed output.
64
175
  """
65
176
  config = {**self.llmconfig, **kwargs}
66
177
  system = system or self.system
67
- self.conversation.initiate_conversation(system=system, instruction=instruction, context=context)
68
-
178
+ self.conversation.initiate_conversation(system=system, instruction=instruction, context=context, name=name)
69
179
  await self.call_chatcompletion(**config)
70
- if out:
71
- return self.conversation.responses[-1]['content']
180
+ output = self.conversation.responses[-1]['content']
181
+
182
+ return await self._output(output, invoke, out)
72
183
 
73
- async def followup(self, instruction, system=None, context=None, out=True, **kwargs) -> Any:
184
+ async def followup(self, instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
74
185
  """
75
- Continue the conversation session with a follow-up instruction.
186
+ Continue the conversation with the provided instruction.
76
187
 
77
- Args:
78
- instruction: The user's follow-up instruction.
79
- system: The content of the system message.
80
- context: Additional context for the user instruction.
81
- out: Whether to return the output content.
188
+ Parameters:
189
+ instruction (str): The instruction to continue the conversation.
190
+ system (Optional[str]): The system setting for the conversation. Default is None.
191
+ context (Optional[dict]): Additional context for the instruction. Default is None.
192
+ out (bool): Whether to return the output. Default is True.
193
+ name (Optional[str]): The name associated with the instruction. Default is None.
194
+ invoke (bool): Whether to invoke tools based on the output. Default is True.
195
+ kwargs: Additional keyword arguments for configuration.
82
196
 
83
197
  Returns:
84
- Any: The output content if 'out' is True, otherwise None.
198
+ Any: The processed output.
85
199
  """
86
- self.conversation.append_last_response()
87
200
  if system:
88
201
  self.conversation.change_system(system)
89
- self.conversation.add_messages(instruction=instruction, context=context)
90
-
202
+ self.conversation.add_messages(instruction=instruction, context=context, name=name)
91
203
  config = {**self.llmconfig, **kwargs}
92
204
  await self.call_chatcompletion(**config)
93
- if out:
94
- return self.conversation.responses[-1]['content']
205
+ output = self.conversation.responses[-1]['content']
206
+
207
+ return await self._output(output, invoke, out)
95
208
 
96
209
  def create_payload_chatcompletion(self, **kwargs):
97
210
  """
98
- Create a payload for chat completion API calls.
211
+ Create a payload for chat completion based on the conversation state and configuration.
212
+
213
+ Parameters:
214
+ kwargs: Additional keyword arguments for configuration.
99
215
 
100
- Args:
101
- kwargs: Additional keyword arguments for customization.
216
+ Returns:
217
+ dict: The payload for chat completion.
102
218
  """
103
219
  # currently only openai chat completions are supported
104
220
  messages = self.conversation.messages
105
-
106
221
  config = {**self.llmconfig, **kwargs}
107
-
108
222
  payload = {
109
223
  "messages": messages,
110
224
  "model": config.get('model'),
@@ -117,34 +231,30 @@ class Session():
117
231
  }
118
232
 
119
233
  for key in ["seed", "stop", "stream", "tools", "tool_choice", "user", "max_tokens"]:
120
- if config[key] is True:
234
+ if bool(config[key]) is True and str(config[key]) != "none":
121
235
  payload.update({key: config[key]})
122
-
123
236
  return payload
124
-
125
- async def call_chatcompletion(self, delay=1, **kwargs):
237
+
238
+ async def call_chatcompletion(self, sleep=0.1, **kwargs):
126
239
  """
127
- Make an asynchronous call to the chat completion API.
240
+ Make a call to the chat completion API and process the response.
128
241
 
129
- Args:
130
- delay: The delay (in seconds) between API calls.
131
- kwargs: Additional keyword arguments for customization.
242
+ Parameters:
243
+ sleep (float): The sleep duration after making the API call. Default is 0.1.
244
+ kwargs: Additional keyword arguments for configuration.
132
245
  """
133
- # currently only openai chat completions are supported
134
-
135
246
  endpoint = f"chat/completions"
136
247
  try:
137
248
  async with aiohttp.ClientSession() as session:
249
+ payload = self.create_payload_chatcompletion(**kwargs)
138
250
  completion = await self.api_service.call_api(
139
- session, endpoint,
140
- self.create_payload_chatcompletion(**kwargs))
251
+ session, endpoint, payload)
141
252
  if "choices" in completion:
142
- completion = completion['choices'][0] # currently can only call one completion at a time, n has to be 1
143
- self.logger({"input":self.conversation.messages, "output": completion})
144
- response = {"role": "assistant", "content": completion['message']["content"]}
145
- self.conversation.responses.append(response)
253
+ self._logger({"input":payload, "output": completion})
254
+ self.conversation.add_messages(response=completion['choices'][0])
255
+ self.conversation.responses.append(self.conversation.messages[-1])
146
256
  self.conversation.response_counts += 1
147
- await asyncio.sleep(delay=delay)
257
+ await asyncio.sleep(sleep)
148
258
  status_tracker.num_tasks_succeeded += 1
149
259
  else:
150
260
  status_tracker.num_tasks_failed += 1
@@ -153,13 +263,29 @@ class Session():
153
263
  raise e
154
264
 
155
265
  def messages_to_csv(self, dir=None, filename="_messages.csv", **kwags):
156
- dir = dir or self.logger.dir
266
+ """
267
+ Save conversation messages to a CSV file.
268
+
269
+ Parameters:
270
+ dir (Optional[str]): The directory path for saving the CSV file. Default is None.
271
+ filename (Optional[str]): The filename for the CSV file. Default is "_messages.csv".
272
+ kwargs: Additional keyword arguments for CSV file settings.
273
+ """
274
+ dir = dir or self._logger.dir
157
275
  if dir is None:
158
276
  raise ValueError("No directory specified.")
159
- self.conversation.msg._to_csv(dir=dir, filename=filename, **kwags)
277
+ self.conversation.msg.to_csv(dir=dir, filename=filename, **kwags)
160
278
 
161
279
  def log_to_csv(self, dir=None, filename="_llmlog.csv", **kwags):
162
- dir = dir or self.logger.dir
280
+ """
281
+ Save conversation logs to a CSV file.
282
+
283
+ Parameters:
284
+ dir (Optional[str]): The directory path for saving the CSV file. Default is None.
285
+ filename (Optional[str]): The filename for the CSV file. Default is "_llmlog.csv".
286
+ kwargs: Additional keyword arguments for CSV file settings.
287
+ """
288
+ dir = dir or self._logger.dir
163
289
  if dir is None:
164
290
  raise ValueError("No directory specified.")
165
- self.logger.to_csv(dir=dir, filename=filename, **kwags)
291
+ self._logger.to_csv(dir=dir, filename=filename, **kwags)
File without changes
lionagi/utils/__init__.py CHANGED
@@ -1,9 +1,10 @@
1
1
  from .sys_util import to_flat_dict, append_to_jsonl, to_list, str_to_num, make_copy, to_temp, to_csv, hold_call, ahold_call, l_call, al_call, m_call, am_call, e_call, ae_call, get_timestamp, create_path
2
2
  from .doc_util import dir_to_path, read_text, dir_to_files, chunk_text, file_to_chunks, file_to_chunks, get_bins
3
3
  from .log_util import DataLogger
4
+ from .tool_util import ToolManager
4
5
 
5
6
  __all__ = [
6
7
  "to_list", "str_to_num", "make_copy", "to_temp", "to_csv", "hold_call", "ahold_call", "l_call", "al_call", "m_call", "am_call", "e_call", "ae_call", "get_timestamp", "create_path", "to_flat_dict", "append_to_jsonl",
7
8
  "dir_to_path", "read_text", "dir_to_files", "chunk_text", "file_to_chunks", "file_to_chunks", "get_bins",
8
- "DataLogger"
9
+ "DataLogger", "ToolManager"
9
10
  ]
lionagi/utils/doc_util.py CHANGED
@@ -26,7 +26,7 @@ def dir_to_path(dir: str, ext, recursive: bool = False, flat: bool = True):
26
26
  def _dir_to_path(ext, recursive=recursive):
27
27
  tem = '**/*' if recursive else '*'
28
28
  return list(Path(dir).glob(tem + ext))
29
-
29
+
30
30
  return to_list(l_call(ext, _dir_to_path, flat=True), flat=flat)
31
31
 
32
32
  def read_text(filepath: str, clean: bool = True) -> str:
@@ -48,15 +48,15 @@ def read_text(filepath: str, clean: bool = True) -> str:
48
48
  content = f.read()
49
49
  if clean:
50
50
  # Define characters to replace and their replacements
51
- replacements = {'\\': ' ', '\\\n': ' ', '\\\t': ' ', ' ': ' ', '\'': ' '}
51
+ replacements = {'\\': ' ', '\n': ' ', '\t': ' ', ' ': ' ', '\'': ' '}
52
52
  for old, new in replacements.items():
53
53
  content = content.replace(old, new)
54
54
  return content
55
55
 
56
- def dir_to_files(dir: str, ext: str, recursive: bool = False,
57
- reader: Callable = read_text, clean: bool = True,
56
+ def dir_to_files(dir: str, ext: str, recursive: bool = False,
57
+ reader: Callable = read_text, clean: bool = True,
58
58
  to_csv: bool = False, project: str = 'project',
59
- output_dir: str = 'data/logs/sources/', filename: Optional[str] = None,
59
+ output_dir: str = 'data/logs/sources/', filename: Optional[str] = None,
60
60
  verbose: bool = True, timestamp: bool = True, logger: Optional[DataLogger] = None):
61
61
  """
62
62
  Reads and processes files in a specified directory with the given extension.
@@ -81,9 +81,9 @@ def dir_to_files(dir: str, ext: str, recursive: bool = False,
81
81
  Examples:
82
82
  >>> logs = dir_to_files(dir='my_directory', ext='.txt', to_csv=True)
83
83
  """
84
-
84
+
85
85
  sources = dir_to_path(dir, ext, recursive)
86
-
86
+
87
87
  def split_path(path: Path) -> tuple:
88
88
  folder_name = path.parent.name
89
89
  file_name = path.name
@@ -99,9 +99,9 @@ def dir_to_files(dir: str, ext: str, recursive: bool = False,
99
99
  "file_size": len(str(content)),
100
100
  'content': content
101
101
  } if content else None
102
-
102
+
103
103
  logs = to_list(l_call(sources, to_dict, flat=True), dropna=True)
104
-
104
+
105
105
  if to_csv:
106
106
  filename = filename or f"{project}_sources.csv"
107
107
  logger = DataLogger(dir=output_dir, log=logs) if not logger else logger
@@ -109,7 +109,7 @@ def dir_to_files(dir: str, ext: str, recursive: bool = False,
109
109
 
110
110
  return logs
111
111
 
112
- def chunk_text(input: str, chunk_size: int, overlap: float,
112
+ def chunk_text(input: str, chunk_size: int, overlap: float,
113
113
  threshold: int) -> List[Union[str, None]]:
114
114
  """
115
115
  Splits a string into chunks of a specified size, allowing for optional overlap between chunks.
@@ -127,19 +127,19 @@ def chunk_text(input: str, chunk_size: int, overlap: float,
127
127
  Returns:
128
128
  List[Union[str, None]]: List of text chunks.
129
129
  """
130
-
130
+
131
131
  try:
132
132
  # Ensure text is a string
133
133
  if not isinstance(input, str):
134
134
  input = str(input)
135
-
135
+
136
136
  chunks = []
137
137
  n_chunks = math.ceil(len(input) / chunk_size)
138
138
  overlap_size = int(chunk_size * overlap / 2)
139
-
139
+
140
140
  if n_chunks == 1:
141
141
  return [input]
142
-
142
+
143
143
  elif n_chunks == 2:
144
144
  chunks.append(input[:chunk_size + overlap_size])
145
145
  if len(input) - chunk_size > threshold:
@@ -147,28 +147,28 @@ def chunk_text(input: str, chunk_size: int, overlap: float,
147
147
  else:
148
148
  return [input]
149
149
  return chunks
150
-
150
+
151
151
  elif n_chunks > 2:
152
152
  chunks.append(input[:chunk_size + overlap_size])
153
153
  for i in range(1, n_chunks - 1):
154
154
  start_idx = chunk_size * i - overlap_size
155
155
  end_idx = chunk_size * (i + 1) + overlap_size
156
156
  chunks.append(input[start_idx:end_idx])
157
-
157
+
158
158
  if len(input) - chunk_size * (n_chunks - 1) > threshold:
159
159
  chunks.append(input[chunk_size * (n_chunks - 1) - overlap_size:])
160
160
  else:
161
- chunks[-1] += input[chunk_size * (n_chunks - 1):]
162
-
161
+ chunks[-1] += input[chunk_size * (n_chunks - 1) + overlap_size:]
162
+
163
163
  return chunks
164
-
164
+
165
165
  except Exception as e:
166
166
  raise ValueError(f"An error occurred while chunking the text. {e}")
167
167
 
168
- def _file_to_chunks(input: Dict[str, Any],
169
- field: str = 'content',
170
- chunk_size: int = 1500,
171
- overlap: float = 0.2,
168
+ def _file_to_chunks(input: Dict[str, Any],
169
+ field: str = 'content',
170
+ chunk_size: int = 1500,
171
+ overlap: float = 0.2,
172
172
  threshold: int = 200) -> List[Dict[str, Any]]:
173
173
  """
174
174
  Splits text from a specified dictionary field into chunks and returns a list of dictionaries.
@@ -195,7 +195,7 @@ def _file_to_chunks(input: Dict[str, Any],
195
195
  try:
196
196
  out = {key: value for key, value in input.items() if key != field}
197
197
  out.update({"chunk_overlap": overlap, "chunk_threshold": threshold})
198
-
198
+
199
199
  chunks = chunk_text(input[field], chunk_size=chunk_size, overlap=overlap, threshold=threshold)
200
200
  logs = []
201
201
  for i, chunk in enumerate(chunks):
@@ -209,22 +209,22 @@ def _file_to_chunks(input: Dict[str, Any],
209
209
  logs.append(chunk_dict)
210
210
 
211
211
  return logs
212
-
212
+
213
213
  except Exception as e:
214
214
  raise ValueError(f"An error occurred while chunking the file. {e}")
215
-
216
- def file_to_chunks(input,
217
- field: str = 'content',
218
- chunk_size: int = 1500,
219
- overlap: float = 0.2,
220
- threshold: int = 200,
221
- to_csv=False,
215
+
216
+ def file_to_chunks(input,
217
+ field: str = 'content',
218
+ chunk_size: int = 1500,
219
+ overlap: float = 0.2,
220
+ threshold: int = 200,
221
+ to_csv=False,
222
222
  project='project',
223
- output_dir='data/logs/sources/',
223
+ output_dir='data/logs/sources/',
224
224
  chunk_func = _file_to_chunks,
225
- filename=None,
226
- verbose=True,
227
- timestamp=True,
225
+ filename=None,
226
+ verbose=True,
227
+ timestamp=True,
228
228
  logger=None):
229
229
  """
230
230
  Splits text from a specified dictionary field into chunks and returns a list of dictionaries.
@@ -243,10 +243,10 @@ def file_to_chunks(input,
243
243
  timestamp: If True, include a timestamp in the exported file name.
244
244
  logger: An optional DataLogger instance for logging.
245
245
  """
246
-
246
+
247
247
  f = lambda x: chunk_func(x, field=field, chunk_size=chunk_size, overlap=overlap, threshold=threshold)
248
248
  logs = to_list(l_call(input, f), flat=True)
249
-
249
+
250
250
  if to_csv:
251
251
  filename = filename if filename else f"{project}_sources.csv"
252
252
  logger = DataLogger(log=logs) if not logger else logger
lionagi/utils/sys_util.py CHANGED
@@ -670,7 +670,7 @@ def create_id() -> str:
670
670
  random_bytes = os.urandom(16)
671
671
  return hashlib.sha256(current_time + random_bytes).hexdigest()[:16]
672
672
 
673
- def create_path(dir: str, filename: str, timestamp: bool = True, dir_exist_ok: bool = True) -> str:
673
+ def create_path(dir: str, filename: str, timestamp: bool = True, dir_exist_ok: bool = True, time_prefix=False) -> str:
674
674
  """
675
675
  Creates a file path by optionally appending a timestamp to the filename.
676
676
 
@@ -690,10 +690,14 @@ def create_path(dir: str, filename: str, timestamp: bool = True, dir_exist_ok: b
690
690
  >>> create_path('/tmp/', 'log.txt', timestamp=False)
691
691
  '/tmp/log.txt'
692
692
  """
693
+
694
+ dir = dir + '/' if str(dir)[-1] != '/' else dir
695
+ filename, ext = filename.split('.')
693
696
  os.makedirs(dir, exist_ok=dir_exist_ok)
697
+
694
698
  if timestamp:
695
699
  timestamp = get_timestamp()
696
- return f"{dir}{timestamp}{filename}"
700
+ return f"{dir}{timestamp}_{filename}.{ext}" if time_prefix else f"{dir}{filename}_{timestamp}.{ext}"
697
701
  else:
698
702
  return f"{dir}{filename}"
699
703
 
@@ -0,0 +1,194 @@
1
+ import json
2
+ import asyncio
3
+ from .sys_util import l_call
4
+
5
+
6
+ class ToolManager:
7
+ """
8
+ A manager class for handling and invoking registered tools and functions.
9
+
10
+ This class allows the registration of tools and functions, enabling their invocation.
11
+
12
+ Attributes:
13
+ registry (dict): A dictionary storing the registered tools and their corresponding functions.
14
+
15
+ Methods:
16
+ _to_dict(name, function, content=None) -> dict:
17
+ Convert tool information to a dictionary entry.
18
+
19
+ _name_existed(name) -> bool:
20
+ Check if a given name exists in the registry.
21
+
22
+ _register_function(name, function, content=None, update=False, new=False, prefix=None, postfix=None) -> None:
23
+ Register a function with a specified name in the registry.
24
+
25
+ invoke(name, args) -> Any:
26
+ Invoke a registered function with the provided arguments.
27
+
28
+ ainvoke(name, args) -> Any:
29
+ Asynchronously invoke a registered function with the provided arguments.
30
+
31
+ _get_function_call(response) -> Tuple[str, dict]:
32
+ Extract function name and arguments from a response JSON.
33
+
34
+ _from_tool(tool, func) -> Tuple[str, callable, list]:
35
+ Convert tool information to function registration parameters.
36
+
37
+ register_tools(tools, functions, update=False, new=False, prefix=None, postfix=None) -> None:
38
+ Register multiple tools and their corresponding functions.
39
+ """
40
+ def __init__(self):
41
+ """
42
+ Initialize a ToolManager object with an empty registry.
43
+ """
44
+ self.registry = {}
45
+
46
+ @staticmethod
47
+ def _to_dict(name, function, content=None):
48
+ """
49
+ Convert tool information to a dictionary entry.
50
+
51
+ Parameters:
52
+ name (str): The name of the tool.
53
+ function (callable): The function associated with the tool.
54
+ content (Optional[str]): Additional content for the tool.
55
+
56
+ Returns:
57
+ dict: A dictionary entry representing the tool.
58
+ """
59
+ return {name: {"function": function, "content": content or "none"}}
60
+
61
+ def _name_existed(self, name):
62
+ """
63
+ Check if a given name exists in the registry.
64
+
65
+ Parameters:
66
+ name (str): The name to check.
67
+
68
+ Returns:
69
+ bool: True if the name exists in the registry, False otherwise.
70
+
71
+ """
72
+ return True if name in self.registry.keys() else False
73
+
74
+ def _register_function(self, name, function, content=None, update=False, new=False, prefix=None, postfix=None):
75
+ """
76
+ Register a function with a specified name in the registry.
77
+
78
+ Parameters:
79
+ name (str): The name of the function.
80
+ function (callable): The function to register.
81
+ content (Optional[str]): Additional content for the function.
82
+ update (bool): Whether to update an existing function with the same name.
83
+ new (bool): Whether to create a new registry for an existing function.
84
+ prefix (Optional[str]): A prefix to add to the function name.
85
+ postfix (Optional[str]): A postfix to add to the function name.
86
+
87
+ """
88
+ if self._name_existed(name):
89
+ if update and new:
90
+ raise ValueError(f"Cannot both update and create new registry for existing function {name} at the same time")
91
+
92
+ name = f"{prefix or ''}{name}{postfix or '1'}" if new else name
93
+ self.registry.update(self._to_dict(name, function, content))
94
+
95
+ def invoke(self, name, args):
96
+ """
97
+ Invoke a registered function with the provided arguments.
98
+
99
+ Parameters:
100
+ name (str): The name of the function to invoke.
101
+ args (dict): The arguments to pass to the function.
102
+
103
+ Returns:
104
+ Any: The result of invoking the function.
105
+ """
106
+ if self._name_existed(name):
107
+ try:
108
+ return self.registry[name](**args)
109
+ except Exception as e:
110
+ raise ValueError(f"Error when invoking function {name} with arguments {args} with error message {e}")
111
+ else:
112
+ raise ValueError(f"Function {name} is not registered.")
113
+
114
+ async def ainvoke(self, name, args):
115
+ """
116
+ Asynchronously invoke a registered function with the provided arguments.
117
+
118
+ Parameters:
119
+ name (str): The name of the function to invoke.
120
+ args (dict): The arguments to pass to the function.
121
+
122
+ Returns:
123
+ Any: The result of invoking the function asynchronously.
124
+
125
+ """
126
+ if self._name_existed(name):
127
+ function = self.registry[name]["function"]
128
+ try:
129
+ if asyncio.iscoroutinefunction(function):
130
+ return await function(**args)
131
+ else:
132
+ return function(**args)
133
+ except Exception as e:
134
+ raise ValueError(f"Error when invoking function {name} with arguments {args} with error message {e}")
135
+ else:
136
+ raise ValueError(f"Function {name} is not registered.")
137
+
138
+ @staticmethod
139
+ def _get_function_call(response):
140
+ """
141
+ Extract function name and arguments from a response JSON.
142
+
143
+ Parameters:
144
+ response (str): The JSON response containing function information.
145
+
146
+ Returns:
147
+ Tuple[str, dict]: The function name and its arguments.
148
+ """
149
+ try:
150
+ out = json.loads(response)
151
+ func = out['function'][5:]
152
+ args = json.loads(out['arguments'])
153
+ return (func, args)
154
+ except:
155
+ try:
156
+ out = json.loads(response)
157
+ out = out['tool_uses'][0]
158
+ func = out['recipient_name'].split('.')[-1]
159
+ args = out['parameters']
160
+ return (func, args)
161
+ except:
162
+ raise ValueError('response is not a valid function call')
163
+
164
+ @staticmethod
165
+ def _from_tool(tool, func):
166
+ """
167
+ Convert tool information to function registration parameters.
168
+
169
+ Parameters:
170
+ tool (dict): The tool information.
171
+ func (callable): The function associated with the tool.
172
+
173
+ Returns:
174
+ Tuple[str, callable, list]: The function name, the function, and the list of function parameters.
175
+
176
+ """
177
+ return (tool['function']['name'], func,
178
+ tool['function']['parameters']['properties'].keys())
179
+
180
+ def register_tools(self, tools, functions, update=False, new=False, prefix=None, postfix=None):
181
+ """
182
+ Register multiple tools and their corresponding functions.
183
+
184
+ Parameters:
185
+ tools (list): The list of tool information dictionaries.
186
+ functions (list): The list of corresponding functions.
187
+ update (bool): Whether to update existing functions.
188
+ new (bool): Whether to create new registries for existing functions.
189
+ prefix (Optional[str]): A prefix to add to the function names.
190
+ postfix (Optional[str]): A postfix to add to the function names.
191
+
192
+ """
193
+ funcs = l_call(range(len(tools)), lambda i: self._from_tool(tools[i], functions[i]))
194
+ l_call(range(len(tools)), lambda i: self._register_function(funcs[i][0], funcs[i][1], update=update, new=new, prefix=prefix, postfix=postfix))
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.0.104"
1
+ __version__ = "0.0.105"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lionagi
3
- Version: 0.0.104
3
+ Version: 0.0.105
4
4
  Summary: Towards automated general intelligence.
5
5
  Author: HaiyangLi
6
6
  Author-email: Haiyang Li <ocean@lionagi.ai>
@@ -227,7 +227,8 @@ Requires-Dist: httpx ==0.25.1
227
227
  - PyPI: https://pypi.org/project/lionagi/
228
228
  - Documentation: https://lionagi.readthedocs.io/en/latest/ (still a lot TODO)
229
229
  - Website: TODO
230
- - Discord: [Join Our Discord](https://discord.gg/ACnynvvPjt)
230
+ - Discord: [Join Our Discord](https://discord.gg/7RGWqpSxze)
231
+
231
232
 
232
233
  # LionAGI
233
234
  **Towards Automated General Intelligence**
@@ -286,7 +287,7 @@ Visit our notebooks for our examples.
286
287
 
287
288
  ### Community
288
289
 
289
- We encourage contributions to LionAGI and invite you to enrich its features and capabilities. Engage with us and other community members on [Discord](https://discord.gg/ACnynvvPjt)
290
+ We encourage contributions to LionAGI and invite you to enrich its features and capabilities. Engage with us and other community members [Join Our Discord](https://discord.gg/7RGWqpSxze)
290
291
 
291
292
  ### Citation
292
293
 
@@ -0,0 +1,21 @@
1
+ lionagi/__init__.py,sha256=2Rko3tw94ZFVN_GSvcxAY1O77FxswcaMxNHKH5Bj7jc,788
2
+ lionagi/version.py,sha256=WyIu1E1JGmXY5vMstqMyTqow6kk_Dcs2wEzR6Z1x6Ts,24
3
+ lionagi/api/__init__.py,sha256=RcmOxPnbaj5R6JYqQzQZ67KyVByJfyUw6QSw22KSo8g,134
4
+ lionagi/api/oai_config.py,sha256=yhyZ4aEaF6r3XBbhxI47r8CL2-amc-4IKJhbXv2W9CM,356
5
+ lionagi/api/oai_service.py,sha256=ctX4k3du_sl52n2LilSxXGHdce-igHXtEfpB6RrKbwQ,11209
6
+ lionagi/session/__init__.py,sha256=hbM6VwWz0Oh-Vld79JDFo5eYaCIqAn_OswmLiT0z4UA,58
7
+ lionagi/session/conversation.py,sha256=ZeaNJgmhA6aMG8cZMagRSF4gfsJNQKsNWAFxY6M2Y34,4057
8
+ lionagi/session/message.py,sha256=rjNeOSDgweW_eQfmsgsWTJ30slnfMEv0Tn4LHeAOgxo,6147
9
+ lionagi/session/session.py,sha256=007xhhUUbn60LpOqLsGlvRcio7t_77bx3z_GFir0rOk,12194
10
+ lionagi/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ lionagi/utils/__init__.py,sha256=jTZigmOboszESjWr9dP8PKtZ8XF_RqVd4Ni8s-GkaVs,760
12
+ lionagi/utils/api_util.py,sha256=WE51kMpKzmBwRqD0dkzxAMWzK04_k_5dth2kiOjVkMA,14837
13
+ lionagi/utils/doc_util.py,sha256=uT2paXguEs26kkW7oe2rR3CozQmpP2P9eJJdnZ9uM_E,12338
14
+ lionagi/utils/log_util.py,sha256=qbmaZxiX_bKY-LLaZcpMbTwi3aeBcK9-Lc93vkLIBuk,3103
15
+ lionagi/utils/sys_util.py,sha256=K4dumJ0th082RITpoz_F_eUw-OwkaLOz-BHoezuxwlU,28045
16
+ lionagi/utils/tool_util.py,sha256=OWQsGqAxiyxz2Q7cVE_JmnF19GKN2D9BNvJ09c98DlM,7461
17
+ lionagi-0.0.105.dist-info/LICENSE,sha256=TBnSyG8fs_tMRtK805GzA1cIyExleKyzoN_kuVxT9IY,11358
18
+ lionagi-0.0.105.dist-info/METADATA,sha256=SACNHjsB9hpR-d3Y5kfIhUsox3cdMTe_dLPHHFl08YU,17370
19
+ lionagi-0.0.105.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
20
+ lionagi-0.0.105.dist-info/top_level.txt,sha256=szvch_d2jE1Lu9ZIKsl26Ll6BGfYfbOgt5lm-UpFSo4,8
21
+ lionagi-0.0.105.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- lionagi/__init__.py,sha256=2Rko3tw94ZFVN_GSvcxAY1O77FxswcaMxNHKH5Bj7jc,788
2
- lionagi/version.py,sha256=m9tOf0gVCkqN3dmK4Ruh3l4dO8KbQ-WtCnvEBME8wSU,24
3
- lionagi/api/__init__.py,sha256=RcmOxPnbaj5R6JYqQzQZ67KyVByJfyUw6QSw22KSo8g,134
4
- lionagi/api/oai_config.py,sha256=yhyZ4aEaF6r3XBbhxI47r8CL2-amc-4IKJhbXv2W9CM,356
5
- lionagi/api/oai_service.py,sha256=ctX4k3du_sl52n2LilSxXGHdce-igHXtEfpB6RrKbwQ,11209
6
- lionagi/session/__init__.py,sha256=hbM6VwWz0Oh-Vld79JDFo5eYaCIqAn_OswmLiT0z4UA,58
7
- lionagi/session/conversation.py,sha256=dedqlGEfIT26WfTJhBOlYWpz_-BFad1BkzIya2mkFwA,3436
8
- lionagi/session/message.py,sha256=bxvJbR0z9z97suz4sMKbNYIuJYsHuAXuTDgj3CI0qnM,2851
9
- lionagi/session/session.py,sha256=zTRMNaV8R3DKD10hm-wOAW8dSRVobu_aa7_lAT8I9kg,6812
10
- lionagi/utils/__init__.py,sha256=-9k5ILJjZ9bTq6U4NA3vNURG2HS7wsUdE1fEWItTGqM,710
11
- lionagi/utils/api_util.py,sha256=WE51kMpKzmBwRqD0dkzxAMWzK04_k_5dth2kiOjVkMA,14837
12
- lionagi/utils/doc_util.py,sha256=kZ3qRIKc5kAXFjeR8Z6oDzM4vRQVDw6rG5YDavme2zQ,12461
13
- lionagi/utils/log_util.py,sha256=qbmaZxiX_bKY-LLaZcpMbTwi3aeBcK9-Lc93vkLIBuk,3103
14
- lionagi/utils/sys_util.py,sha256=8S1S7V3Sk_Yyp2pfqrGyO_9w-wDHQ3Kzpez4yGvpZuM,27860
15
- lionagi-0.0.104.dist-info/LICENSE,sha256=TBnSyG8fs_tMRtK805GzA1cIyExleKyzoN_kuVxT9IY,11358
16
- lionagi-0.0.104.dist-info/METADATA,sha256=640tGgNFlJ91RYqHBU2B4VLx1dcGVlMztLmbXBPXeEs,17363
17
- lionagi-0.0.104.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
18
- lionagi-0.0.104.dist-info/top_level.txt,sha256=szvch_d2jE1Lu9ZIKsl26Ll6BGfYfbOgt5lm-UpFSo4,8
19
- lionagi-0.0.104.dist-info/RECORD,,