lionagi 0.0.105__py3-none-any.whl → 0.0.107__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lionagi/api/oai_service.py +25 -13
- lionagi/session/conversation.py +22 -12
- lionagi/session/message.py +57 -30
- lionagi/session/session.py +130 -45
- lionagi/utils/__init__.py +4 -7
- lionagi/utils/api_util.py +91 -45
- lionagi/utils/doc_util.py +69 -26
- lionagi/utils/log_util.py +15 -4
- lionagi/utils/sys_util.py +74 -11
- lionagi/utils/tool_util.py +44 -29
- lionagi/version.py +1 -1
- {lionagi-0.0.105.dist-info → lionagi-0.0.107.dist-info}/METADATA +7 -12
- lionagi-0.0.107.dist-info/RECORD +20 -0
- lionagi/tools/__init__.py +0 -0
- lionagi-0.0.105.dist-info/RECORD +0 -21
- {lionagi-0.0.105.dist-info → lionagi-0.0.107.dist-info}/LICENSE +0 -0
- {lionagi-0.0.105.dist-info → lionagi-0.0.107.dist-info}/WHEEL +0 -0
- {lionagi-0.0.105.dist-info → lionagi-0.0.107.dist-info}/top_level.txt +0 -0
lionagi/api/oai_service.py
CHANGED
@@ -19,20 +19,25 @@ class OpenAIRateLimiter(RateLimiter):
|
|
19
19
|
and replenishing these limits at regular intervals.
|
20
20
|
|
21
21
|
Attributes:
|
22
|
-
max_requests_per_minute (int):
|
23
|
-
|
22
|
+
max_requests_per_minute (int):
|
23
|
+
Maximum number of requests allowed per minute.
|
24
|
+
max_tokens_per_minute (int):
|
25
|
+
Maximum number of tokens allowed per minute.
|
24
26
|
|
25
27
|
Methods:
|
26
|
-
rate_limit_replenisher:
|
27
|
-
|
28
|
+
rate_limit_replenisher:
|
29
|
+
Coroutine to replenish rate limits over time.
|
30
|
+
calculate_num_token:
|
31
|
+
Calculates the required tokens for a request.
|
28
32
|
"""
|
29
33
|
|
30
34
|
def __init__(self, max_requests_per_minute: int, max_tokens_per_minute: int) -> None:
|
31
35
|
"""
|
32
36
|
Initializes the rate limiter with specific limits for OpenAI API.
|
33
37
|
|
34
|
-
|
38
|
+
Parameters:
|
35
39
|
max_requests_per_minute (int): The maximum number of requests allowed per minute.
|
40
|
+
|
36
41
|
max_tokens_per_minute (int): The maximum number of tokens that can accumulate per minute.
|
37
42
|
"""
|
38
43
|
super().__init__(max_requests_per_minute, max_tokens_per_minute)
|
@@ -66,8 +71,9 @@ class OpenAIRateLimiter(RateLimiter):
|
|
66
71
|
This method should be implemented in a subclass to provide the specific calculation logic
|
67
72
|
for the OpenAI API.
|
68
73
|
|
69
|
-
|
74
|
+
Parameters:
|
70
75
|
payload (Dict[str, Any]): The payload of the request.
|
76
|
+
|
71
77
|
api_endpoint (str): The specific API endpoint for the request.
|
72
78
|
|
73
79
|
Returns:
|
@@ -160,12 +166,17 @@ class OpenAIService(BaseAPIService):
|
|
160
166
|
"""
|
161
167
|
Initializes the OpenAI service with configuration for API interaction.
|
162
168
|
|
163
|
-
|
169
|
+
Parameters:
|
164
170
|
api_key (str): The API key for authenticating with OpenAI.
|
171
|
+
|
165
172
|
token_encoding_name (str): The name of the text encoding used by OpenAI.
|
173
|
+
|
166
174
|
max_attempts (int): The maximum number of attempts for calling an API endpoint.
|
175
|
+
|
167
176
|
status_tracker (Optional[StatusTracker]): Tracker for API call outcomes.
|
168
|
-
|
177
|
+
|
178
|
+
ratelimiter (Optional[OpenAIRateLimiter]): Rate limiter for OpenAI's limits.
|
179
|
+
|
169
180
|
queue (Optional[AsyncQueue]): Queue for managing asynchronous API calls.
|
170
181
|
|
171
182
|
Example:
|
@@ -183,15 +194,16 @@ class OpenAIService(BaseAPIService):
|
|
183
194
|
super().__init__(api_key, token_encoding_name, max_attempts,
|
184
195
|
max_requests_per_minute, max_tokens_per_minute,
|
185
196
|
ratelimiter, status_tracker, queue)
|
186
|
-
|
187
197
|
|
188
|
-
async def call_api(self, http_session, endpoint, payload: Dict[str, any] =None) -> Optional[Dict[str, any]]:
|
198
|
+
async def call_api(self, http_session, endpoint, payload: Dict[str, any] = None) -> Optional[Dict[str, any]]:
|
189
199
|
"""
|
190
200
|
Call an OpenAI API endpoint with a specific payload and handle the response.
|
191
201
|
|
192
|
-
|
193
|
-
|
194
|
-
|
202
|
+
Parameters:
|
203
|
+
http_session: The session object for making HTTP requests.
|
204
|
+
|
205
|
+
endpoint (str): The full URL of the OpenAI API endpoint to be called.
|
206
|
+
|
195
207
|
payload (Dict[str, any]): The payload to send with the API request.
|
196
208
|
|
197
209
|
Returns:
|
lionagi/session/conversation.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from .message import Message
|
2
2
|
|
3
|
+
|
3
4
|
class Conversation:
|
4
5
|
"""
|
5
6
|
A class representing a conversation between users and the assistant.
|
@@ -8,21 +9,22 @@ class Conversation:
|
|
8
9
|
user instructions, and assistant responses.
|
9
10
|
|
10
11
|
Attributes:
|
11
|
-
response_counts (int):
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
response_counts (int):
|
13
|
+
The count of assistant responses in the conversation.
|
14
|
+
messages (list):
|
15
|
+
A list to store messages in the conversation.
|
16
|
+
msg (Message):
|
17
|
+
An instance of the Message class for creating messages.
|
18
|
+
responses (list):
|
19
|
+
A list to store assistant responses in the conversation.
|
15
20
|
|
16
21
|
Methods:
|
17
22
|
initiate_conversation(system, instruction, context=None, name=None):
|
18
23
|
Initiate a conversation with a system setting and user instruction.
|
19
|
-
|
20
24
|
add_messages(system, instruction, context=None, response=None, tool=None, name=None):
|
21
25
|
Add messages to the conversation, including system setting, user instruction, and assistant response.
|
22
|
-
|
23
26
|
change_system(system):
|
24
27
|
Change the system setting in the conversation.
|
25
|
-
|
26
28
|
keep_last_n_exchanges(n: int):
|
27
29
|
Keep the last n exchanges in the conversation.
|
28
30
|
"""
|
@@ -40,14 +42,17 @@ class Conversation:
|
|
40
42
|
self.msg = Message()
|
41
43
|
self.responses = []
|
42
44
|
|
43
|
-
def initiate_conversation(self, system, instruction, context=None, name=None):
|
45
|
+
def initiate_conversation(self, system=None, instruction=None, context=None, name=None):
|
44
46
|
"""
|
45
47
|
Initiate a conversation with a system setting and user instruction.
|
46
48
|
|
47
49
|
Parameters:
|
48
50
|
system (str): The system setting for the conversation.
|
51
|
+
|
49
52
|
instruction (str): The user instruction to initiate the conversation.
|
53
|
+
|
50
54
|
context (dict): Additional context for the conversation. Default is None.
|
55
|
+
|
51
56
|
name (str): The name associated with the user. Default is None.
|
52
57
|
"""
|
53
58
|
self.messages, self.responses = [], []
|
@@ -55,19 +60,23 @@ class Conversation:
|
|
55
60
|
self.add_messages(instruction=instruction, context=context, name=name)
|
56
61
|
|
57
62
|
# modify the message adding to accomodate tools
|
58
|
-
def add_messages(self, system=None, instruction=None, context=None, response=None,
|
63
|
+
def add_messages(self, system=None, instruction=None, context=None, response=None, name=None):
|
59
64
|
"""
|
60
65
|
Add messages to the conversation, including system setting, user instruction, and assistant response.
|
61
66
|
|
62
67
|
Parameters:
|
63
68
|
system (str): The system setting for the message. Default is None.
|
69
|
+
|
64
70
|
instruction (str): The instruction content for the message. Default is None.
|
71
|
+
|
65
72
|
context (dict): Additional context for the message. Default is None.
|
73
|
+
|
66
74
|
response (dict): The response content for the message. Default is None.
|
67
|
-
|
75
|
+
|
68
76
|
name (str): The name associated with the message. Default is None.
|
69
77
|
"""
|
70
|
-
msg = self.msg(system=system, instruction=instruction, context=context,
|
78
|
+
msg = self.msg(system=system, instruction=instruction, context=context,
|
79
|
+
response=response, name=name)
|
71
80
|
self.messages.append(msg)
|
72
81
|
|
73
82
|
def change_system(self, system):
|
@@ -92,4 +101,5 @@ class Conversation:
|
|
92
101
|
]
|
93
102
|
if len(response_indices) >= n:
|
94
103
|
first_index_to_keep = response_indices[-n] + 1
|
95
|
-
self.messages =
|
104
|
+
self.messages = self.messages[0] + self.messages[first_index_to_keep:]
|
105
|
+
|
lionagi/session/message.py
CHANGED
@@ -11,11 +11,16 @@ class Message:
|
|
11
11
|
This class encapsulates messages from users, the assistant, systems, and external tools.
|
12
12
|
|
13
13
|
Attributes:
|
14
|
-
role (str):
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
role (str):
|
15
|
+
The role of the message, indicating if it's from the user, assistant, system, or tool.
|
16
|
+
content:
|
17
|
+
The content of the message, which can be an instruction, response, system setting, or tool information.
|
18
|
+
name (str):
|
19
|
+
The name associated with the message, specifying the source (user, assistant, system, or tool).
|
20
|
+
metadata (dict):
|
21
|
+
Additional metadata including id, timestamp, and name.
|
22
|
+
_logger (DataLogger):
|
23
|
+
An instance of the DataLogger class for logging message details.
|
19
24
|
|
20
25
|
Methods:
|
21
26
|
create_message(system, instruction, context, response, tool, name):
|
@@ -40,37 +45,52 @@ class Message:
|
|
40
45
|
self.metadata = None
|
41
46
|
self._logger = DataLogger()
|
42
47
|
|
43
|
-
def create_message(self, system=None, instruction=None, context=None, response=None,
|
48
|
+
def create_message(self, system=None, instruction=None, context=None, response=None, name=None):
|
49
|
+
|
44
50
|
"""
|
45
51
|
Create a message based on the provided information.
|
46
52
|
|
47
53
|
Parameters:
|
48
54
|
system (str): The system setting for the message. Default is None.
|
55
|
+
|
49
56
|
instruction (str): The instruction content for the message. Default is None.
|
57
|
+
|
50
58
|
context (dict): Additional context for the message. Default is None.
|
59
|
+
|
51
60
|
response (dict): The response content for the message. Default is None.
|
52
|
-
|
61
|
+
|
53
62
|
name (str): The name associated with the message. Default is None.
|
54
63
|
"""
|
55
|
-
if sum(l_call([system, instruction, response
|
64
|
+
if sum(l_call([system, instruction, response], bool)) > 1:
|
56
65
|
raise ValueError("Error: Message cannot have more than one role.")
|
57
66
|
|
58
67
|
else:
|
59
68
|
if response:
|
60
69
|
self.role = "assistant"
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
try:
|
71
|
+
response = response["message"]
|
72
|
+
if str(response['content']) == "None":
|
73
|
+
try:
|
74
|
+
tool_count = 0
|
75
|
+
func_list = []
|
76
|
+
while tool_count < len(response['tool_calls']):
|
77
|
+
if response['tool_calls'][tool_count]['type'] == 'function':
|
78
|
+
func_content = {"function": ("func_" + response['tool_calls'][tool_count]['function']['name']),
|
79
|
+
"arguments": response['tool_calls'][tool_count]['function']['arguments']}
|
80
|
+
func_list.append(func_content)
|
81
|
+
tool_count += 1
|
82
|
+
|
83
|
+
self.name = name or "func_request"
|
84
|
+
self.content = {'function_list': func_list}
|
85
|
+
except:
|
86
|
+
raise ValueError("Response message must be one of regular response or function calling")
|
87
|
+
else:
|
88
|
+
self.content = response['content']
|
89
|
+
self.name = name or "assistant"
|
90
|
+
except:
|
91
|
+
self.name = name or "func_call"
|
92
|
+
self.content = response
|
93
|
+
|
74
94
|
elif instruction:
|
75
95
|
self.role = "user"
|
76
96
|
self.content = {"instruction": instruction}
|
@@ -81,17 +101,13 @@ class Message:
|
|
81
101
|
self.role = "system"
|
82
102
|
self.content = system
|
83
103
|
self.name = name or "system"
|
84
|
-
elif tool:
|
85
|
-
self.role = "tool"
|
86
|
-
self.content = tool
|
87
|
-
self.name = name or "tool"
|
88
104
|
|
89
105
|
def to_json(self):
|
90
106
|
"""
|
91
107
|
Convert the message to a JSON format.
|
92
108
|
|
93
109
|
Returns:
|
94
|
-
|
110
|
+
dict: The message in JSON format.
|
95
111
|
"""
|
96
112
|
out = {
|
97
113
|
"role": self.role,
|
@@ -106,22 +122,27 @@ class Message:
|
|
106
122
|
self._logger({**self.metadata, **out})
|
107
123
|
return out
|
108
124
|
|
109
|
-
def __call__(self, system=None, instruction=None, context=None,
|
125
|
+
def __call__(self, system=None, instruction=None, context=None,
|
126
|
+
response=None, name=None):
|
110
127
|
"""
|
111
128
|
Create and return a message in JSON format.
|
112
129
|
|
113
130
|
Parameters:
|
114
131
|
system (str): The system setting for the message. Default is None.
|
132
|
+
|
115
133
|
instruction (str): The instruction content for the message. Default is None.
|
134
|
+
|
116
135
|
context (dict): Additional context for the message. Default is None.
|
136
|
+
|
117
137
|
response (dict): The response content for the message. Default is None.
|
138
|
+
|
118
139
|
name (str): The name associated with the message. Default is None.
|
119
|
-
tool (dict): The tool information for the message. Default is None.
|
120
140
|
|
121
141
|
Returns:
|
122
142
|
dict: The message in JSON format.
|
123
143
|
"""
|
124
|
-
self.create_message(system, instruction,
|
144
|
+
self.create_message(system=system, instruction=instruction,
|
145
|
+
context=context, response=response, name=name)
|
125
146
|
return self.to_json()
|
126
147
|
|
127
148
|
def to_csv(self, dir=None, filename=None, verbose=True, timestamp=True, dir_exist_ok=True, file_exist_ok=False):
|
@@ -130,10 +151,16 @@ class Message:
|
|
130
151
|
|
131
152
|
Parameters:
|
132
153
|
dir (str): The directory path for saving the CSV file. Default is None.
|
154
|
+
|
133
155
|
filename (str): The filename for the CSV file. Default is None.
|
156
|
+
|
134
157
|
verbose (bool): Whether to include verbose information in the CSV. Default is True.
|
158
|
+
|
135
159
|
timestamp (bool): Whether to include timestamps in the CSV. Default is True.
|
160
|
+
|
136
161
|
dir_exist_ok (bool): Whether to allow the directory to exist. Default is True.
|
162
|
+
|
137
163
|
file_exist_ok (bool): Whether to allow the file to exist. Default is False.
|
138
164
|
"""
|
139
|
-
self._logger.to_csv(dir, filename, verbose, timestamp, dir_exist_ok, file_exist_ok)
|
165
|
+
self._logger.to_csv(dir, filename, verbose, timestamp, dir_exist_ok, file_exist_ok)
|
166
|
+
|
lionagi/session/session.py
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
import aiohttp
|
2
2
|
import asyncio
|
3
|
+
import json
|
3
4
|
from typing import Any
|
4
5
|
|
6
|
+
import lionagi
|
5
7
|
from .conversation import Conversation
|
6
|
-
from ..utils.sys_util import to_list
|
8
|
+
from ..utils.sys_util import to_list, l_call, al_call
|
7
9
|
from ..utils.log_util import DataLogger
|
8
10
|
from ..utils.api_util import StatusTracker
|
9
11
|
from ..utils.tool_util import ToolManager
|
10
12
|
from ..api.oai_service import OpenAIService
|
11
|
-
|
12
13
|
from ..api.oai_config import oai_llmconfig
|
13
14
|
|
14
|
-
|
15
15
|
status_tracker = StatusTracker()
|
16
16
|
OAIService = OpenAIService()
|
17
17
|
|
18
|
+
|
18
19
|
class Session():
|
19
20
|
"""
|
20
21
|
A class representing a conversation session with a conversational AI system.
|
@@ -22,12 +23,18 @@ class Session():
|
|
22
23
|
This class manages the flow of conversation, system settings, and interactions with external tools.
|
23
24
|
|
24
25
|
Attributes:
|
25
|
-
conversation (Conversation):
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
conversation (Conversation):
|
27
|
+
An instance of the Conversation class to manage messages.
|
28
|
+
system (str):
|
29
|
+
The current system setting for the conversation.
|
30
|
+
llmconfig (dict):
|
31
|
+
Configuration settings for the language model.
|
32
|
+
_logger (DataLogger):
|
33
|
+
An instance of the DataLogger class for logging conversation details.
|
34
|
+
api_service:
|
35
|
+
An instance of the API service for making calls to the conversational AI model.
|
36
|
+
_toolmanager (ToolManager):
|
37
|
+
An instance of the ToolManager class for managing external tools.
|
31
38
|
|
32
39
|
Methods:
|
33
40
|
set_dir(dir):
|
@@ -54,6 +61,9 @@ class Session():
|
|
54
61
|
followup(instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
|
55
62
|
Continue the conversation with the provided instruction.
|
56
63
|
|
64
|
+
auto_followup(self, instruct, num=3, tool_parser=None, **kwags):
|
65
|
+
Automates the follow-up process for a specified number of times or until the session concludes.
|
66
|
+
|
57
67
|
create_payload_chatcompletion(**kwargs) -> dict:
|
58
68
|
Create a payload for chat completion based on the conversation state and configuration.
|
59
69
|
|
@@ -73,8 +83,11 @@ class Session():
|
|
73
83
|
|
74
84
|
Parameters:
|
75
85
|
system (str): The initial system setting for the conversation.
|
86
|
+
|
76
87
|
dir (Optional[str]): The directory for logging. Default is None.
|
88
|
+
|
77
89
|
llmconfig (Optional[dict]): Configuration settings for the language model. Default is oai_llmconfig.
|
90
|
+
|
78
91
|
api_service: An instance of the API service for making calls to the conversational AI model.
|
79
92
|
"""
|
80
93
|
self.conversation = Conversation()
|
@@ -82,7 +95,7 @@ class Session():
|
|
82
95
|
self.llmconfig = llmconfig
|
83
96
|
self._logger = DataLogger(dir=dir)
|
84
97
|
self.api_service = api_service
|
85
|
-
self.
|
98
|
+
self._toolmanager = ToolManager()
|
86
99
|
|
87
100
|
def set_dir(self, dir):
|
88
101
|
"""
|
@@ -120,55 +133,94 @@ class Session():
|
|
120
133
|
"""
|
121
134
|
self.api_service = api_service
|
122
135
|
|
123
|
-
async def _output(self,
|
136
|
+
async def _output(self, invoke=True, out=True, tool_parser=None):
|
124
137
|
"""
|
125
138
|
Process the output, invoke tools if needed, and optionally return the output.
|
126
139
|
|
127
140
|
Parameters:
|
128
|
-
output: The output to process.
|
129
141
|
invoke (bool): Whether to invoke tools based on the output. Default is True.
|
142
|
+
|
130
143
|
out (bool): Whether to return the output. Default is True.
|
131
144
|
|
132
145
|
Returns:
|
133
146
|
Any: The processed output.
|
134
147
|
"""
|
135
148
|
if invoke:
|
136
|
-
try:
|
137
|
-
|
138
|
-
|
139
|
-
|
149
|
+
try:
|
150
|
+
tool_uses = json.loads(self.conversation.responses[-1]['content'])
|
151
|
+
if 'function_list' in tool_uses.keys():
|
152
|
+
func_calls = l_call(tool_uses['function_list'], self._toolmanager._get_function_call)
|
153
|
+
|
154
|
+
else:
|
155
|
+
func_calls = l_call(tool_uses['tool_uses'], self._toolmanager._get_function_call)
|
156
|
+
|
157
|
+
outs = await al_call(func_calls, self._toolmanager.ainvoke)
|
158
|
+
if tool_parser:
|
159
|
+
outs = l_call(outs, tool_parser)
|
160
|
+
for out, f in zip(outs, func_calls):
|
161
|
+
response = {"function": f[0], "arguments": f[1], "output": out}
|
162
|
+
self.conversation.add_messages(response=response)
|
163
|
+
|
140
164
|
except:
|
141
165
|
pass
|
166
|
+
|
142
167
|
if out:
|
143
|
-
return
|
144
|
-
|
168
|
+
return self.conversation.responses[-1]['content']
|
169
|
+
|
170
|
+
def _is_invoked(self):
|
171
|
+
"""
|
172
|
+
Checks if the current message indicates the invocation of a function call.
|
173
|
+
|
174
|
+
Returns:
|
175
|
+
bool: True if a function call is detected in the content of the last message, False otherwise.
|
176
|
+
"""
|
177
|
+
msg = self.conversation.messages[-1]
|
178
|
+
try:
|
179
|
+
if json.loads(msg['content']).keys() >= {'function', 'arguments', 'output'}:
|
180
|
+
return True
|
181
|
+
except:
|
182
|
+
return False
|
183
|
+
|
145
184
|
def register_tools(self, tools, funcs, update=False, new=False, prefix=None, postfix=None):
|
146
185
|
"""
|
147
186
|
Register tools and their corresponding functions.
|
148
187
|
|
149
188
|
Parameters:
|
150
189
|
tools (list): The list of tool information dictionaries.
|
190
|
+
|
151
191
|
funcs (list): The list of corresponding functions.
|
192
|
+
|
152
193
|
update (bool): Whether to update existing functions.
|
194
|
+
|
153
195
|
new (bool): Whether to create new registries for existing functions.
|
196
|
+
|
154
197
|
prefix (Optional[str]): A prefix to add to the function names.
|
198
|
+
|
155
199
|
postfix (Optional[str]): A postfix to add to the function names.
|
156
200
|
"""
|
157
201
|
funcs = to_list(funcs)
|
158
|
-
self.
|
202
|
+
self._toolmanager.register_tools(tools, funcs, update, new, prefix, postfix)
|
159
203
|
|
160
|
-
async def initiate(self, instruction, system=None, context=None,
|
204
|
+
async def initiate(self, instruction, system=None, context=None, name=None, invoke=True, out=True, tool_parser=None, **kwargs) -> Any:
|
161
205
|
"""
|
162
206
|
Start a new conversation session with the provided instruction.
|
163
207
|
|
164
208
|
Parameters:
|
165
|
-
instruction (str): The instruction to initiate the conversation.
|
209
|
+
instruction (Union[str, dict]): The instruction to initiate the conversation.
|
210
|
+
|
166
211
|
system (Optional[str]): The system setting for the conversation. Default is None.
|
212
|
+
|
167
213
|
context (Optional[dict]): Additional context for the instruction. Default is None.
|
214
|
+
|
168
215
|
out (bool): Whether to return the output. Default is True.
|
216
|
+
|
169
217
|
name (Optional[str]): The name associated with the instruction. Default is None.
|
218
|
+
|
170
219
|
invoke (bool): Whether to invoke tools based on the output. Default is True.
|
171
|
-
|
220
|
+
|
221
|
+
tool_parser (Optional[callable]): A custom tool parser function. Default is None.
|
222
|
+
|
223
|
+
**kwargs: Additional keyword arguments for configuration.
|
172
224
|
|
173
225
|
Returns:
|
174
226
|
Any: The processed output.
|
@@ -176,23 +228,30 @@ class Session():
|
|
176
228
|
config = {**self.llmconfig, **kwargs}
|
177
229
|
system = system or self.system
|
178
230
|
self.conversation.initiate_conversation(system=system, instruction=instruction, context=context, name=name)
|
179
|
-
await self.
|
180
|
-
output = self.conversation.responses[-1]['content']
|
231
|
+
await self._call_chatcompletion(**config)
|
181
232
|
|
182
|
-
return await self._output(
|
233
|
+
return await self._output(invoke, out, tool_parser)
|
183
234
|
|
184
|
-
async def followup(self, instruction, system=None, context=None, out=True, name=None, invoke=True, **kwargs) -> Any:
|
235
|
+
async def followup(self, instruction, system=None, context=None, out=True, name=None, invoke=True, tool_parser=None, **kwargs) -> Any:
|
185
236
|
"""
|
186
237
|
Continue the conversation with the provided instruction.
|
187
238
|
|
188
239
|
Parameters:
|
189
|
-
instruction (str): The instruction to continue the conversation.
|
240
|
+
instruction (Union[str, dict]): The instruction to continue the conversation.
|
241
|
+
|
190
242
|
system (Optional[str]): The system setting for the conversation. Default is None.
|
243
|
+
|
191
244
|
context (Optional[dict]): Additional context for the instruction. Default is None.
|
245
|
+
|
192
246
|
out (bool): Whether to return the output. Default is True.
|
247
|
+
|
193
248
|
name (Optional[str]): The name associated with the instruction. Default is None.
|
249
|
+
|
194
250
|
invoke (bool): Whether to invoke tools based on the output. Default is True.
|
195
|
-
|
251
|
+
|
252
|
+
tool_parser (Optional[callable]): A custom tool parser function. Default is None.
|
253
|
+
|
254
|
+
**kwargs: Additional keyword arguments for configuration.
|
196
255
|
|
197
256
|
Returns:
|
198
257
|
Any: The processed output.
|
@@ -201,17 +260,38 @@ class Session():
|
|
201
260
|
self.conversation.change_system(system)
|
202
261
|
self.conversation.add_messages(instruction=instruction, context=context, name=name)
|
203
262
|
config = {**self.llmconfig, **kwargs}
|
204
|
-
await self.
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
263
|
+
await self._call_chatcompletion(**config)
|
264
|
+
|
265
|
+
return await self._output(invoke, out, tool_parser)
|
266
|
+
|
267
|
+
async def auto_followup(self, instruct, num=3, tool_parser=None, **kwargs):
|
268
|
+
"""
|
269
|
+
Automates the follow-up process for a specified number of times or until the session concludes.
|
270
|
+
|
271
|
+
Parameters:
|
272
|
+
instruct (Union[str, dict]): The instruction for the follow-up.
|
273
|
+
|
274
|
+
num (int, optional): The number of times to automatically follow up. Defaults to 3.
|
275
|
+
|
276
|
+
tool_parser (callable, optional): A custom tool parser function. Defaults to None.
|
277
|
+
|
278
|
+
**kwargs: Additional keyword arguments passed to the underlying `followup` method.
|
279
|
+
|
280
|
+
"""
|
281
|
+
cont_ = True
|
282
|
+
while num > 0 and cont_ is True:
|
283
|
+
await self.followup(instruct, tool_parser=tool_parser, tool_choice="auto", **kwargs)
|
284
|
+
num -= 1
|
285
|
+
cont_ = True if self._is_invoked() else False
|
286
|
+
if num == 0:
|
287
|
+
await self.followup(instruct, **kwargs)
|
288
|
+
|
289
|
+
def _create_payload_chatcompletion(self, **kwargs):
|
210
290
|
"""
|
211
291
|
Create a payload for chat completion based on the conversation state and configuration.
|
212
292
|
|
213
293
|
Parameters:
|
214
|
-
kwargs: Additional keyword arguments for configuration.
|
294
|
+
**kwargs: Additional keyword arguments for configuration.
|
215
295
|
|
216
296
|
Returns:
|
217
297
|
dict: The payload for chat completion.
|
@@ -235,22 +315,23 @@ class Session():
|
|
235
315
|
payload.update({key: config[key]})
|
236
316
|
return payload
|
237
317
|
|
238
|
-
async def
|
318
|
+
async def _call_chatcompletion(self, sleep=0.1, **kwargs):
|
239
319
|
"""
|
240
320
|
Make a call to the chat completion API and process the response.
|
241
321
|
|
242
322
|
Parameters:
|
243
323
|
sleep (float): The sleep duration after making the API call. Default is 0.1.
|
244
|
-
|
324
|
+
|
325
|
+
**kwargs: Additional keyword arguments for configuration.
|
245
326
|
"""
|
246
327
|
endpoint = f"chat/completions"
|
247
328
|
try:
|
248
329
|
async with aiohttp.ClientSession() as session:
|
249
|
-
payload = self.
|
330
|
+
payload = self._create_payload_chatcompletion(**kwargs)
|
250
331
|
completion = await self.api_service.call_api(
|
251
332
|
session, endpoint, payload)
|
252
333
|
if "choices" in completion:
|
253
|
-
self._logger({"input":payload, "output": completion})
|
334
|
+
self._logger({"input": payload, "output": completion})
|
254
335
|
self.conversation.add_messages(response=completion['choices'][0])
|
255
336
|
self.conversation.responses.append(self.conversation.messages[-1])
|
256
337
|
self.conversation.response_counts += 1
|
@@ -262,30 +343,34 @@ class Session():
|
|
262
343
|
status_tracker.num_tasks_failed += 1
|
263
344
|
raise e
|
264
345
|
|
265
|
-
def messages_to_csv(self, dir=None, filename="_messages.csv", **
|
346
|
+
def messages_to_csv(self, dir=None, filename="_messages.csv", **kwargs):
|
266
347
|
"""
|
267
348
|
Save conversation messages to a CSV file.
|
268
349
|
|
269
350
|
Parameters:
|
270
351
|
dir (Optional[str]): The directory path for saving the CSV file. Default is None.
|
352
|
+
|
271
353
|
filename (Optional[str]): The filename for the CSV file. Default is "_messages.csv".
|
272
|
-
|
354
|
+
|
355
|
+
**kwargs: Additional keyword arguments for CSV file settings.
|
273
356
|
"""
|
274
357
|
dir = dir or self._logger.dir
|
275
358
|
if dir is None:
|
276
359
|
raise ValueError("No directory specified.")
|
277
|
-
self.conversation.msg.to_csv(dir=dir, filename=filename, **
|
360
|
+
self.conversation.msg.to_csv(dir=dir, filename=filename, **kwargs)
|
278
361
|
|
279
|
-
def log_to_csv(self, dir=None, filename="_llmlog.csv", **
|
362
|
+
def log_to_csv(self, dir=None, filename="_llmlog.csv", **kwargs):
|
280
363
|
"""
|
281
364
|
Save conversation logs to a CSV file.
|
282
365
|
|
283
366
|
Parameters:
|
284
367
|
dir (Optional[str]): The directory path for saving the CSV file. Default is None.
|
368
|
+
|
285
369
|
filename (Optional[str]): The filename for the CSV file. Default is "_llmlog.csv".
|
286
|
-
|
370
|
+
|
371
|
+
**kwargs: Additional keyword arguments for CSV file settings.
|
287
372
|
"""
|
288
373
|
dir = dir or self._logger.dir
|
289
374
|
if dir is None:
|
290
375
|
raise ValueError("No directory specified.")
|
291
|
-
self._logger.to_csv(dir=dir, filename=filename, **
|
376
|
+
self._logger.to_csv(dir=dir, filename=filename, **kwargs)
|