-
Notifications
You must be signed in to change notification settings - Fork 274
Expand file tree
/
Copy pathhttp_agent.py
More file actions
224 lines (193 loc) · 6.92 KB
/
Copy pathhttp_agent.py
File metadata and controls
224 lines (193 loc) · 6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import contextlib
import time
import warnings
import requests
from urllib3.exceptions import InsecureRequestWarning
from src.typings import *
from src.utils import *
from ..agent import AgentClient
old_merge_environment_settings = requests.Session.merge_environment_settings
@contextlib.contextmanager
def no_ssl_verification():
opened_adapters = set()
def merge_environment_settings(self, url, proxies, stream, verify, cert):
# Verification happens only once per connection so we need to close
# all the opened adapters once we're done. Otherwise, the effects of
# verify=False persist beyond the end of this context manager.
opened_adapters.add(self.get_adapter(url))
settings = old_merge_environment_settings(self, url, proxies, stream, verify, cert)
settings['verify'] = False
return settings
requests.Session.merge_environment_settings = merge_environment_settings
try:
with warnings.catch_warnings():
warnings.simplefilter('ignore', InsecureRequestWarning)
yield
finally:
requests.Session.merge_environment_settings = old_merge_environment_settings
for adapter in opened_adapters:
try:
adapter.close()
except:
pass
class Prompter:
@staticmethod
def get_prompter(prompter: Union[Dict[str, Any], None]):
# check if prompter_name is a method and its variable
if not prompter:
return Prompter.default()
assert isinstance(prompter, dict)
prompter_name = prompter.get("name", None)
prompter_args = prompter.get("args", {})
if hasattr(Prompter, prompter_name) and callable(
getattr(Prompter, prompter_name)
):
return getattr(Prompter, prompter_name)(**prompter_args)
return Prompter.default()
@staticmethod
def default():
return Prompter.role_content_dict()
@staticmethod
def batched_role_content_dict(*args, **kwargs):
base = Prompter.role_content_dict(*args, **kwargs)
def batched(messages):
result = base(messages)
return {key: [result[key]] for key in result}
return batched
@staticmethod
def role_content_dict(
message_key: str = "messages",
role_key: str = "role",
content_key: str = "content",
user_role: str = "user",
agent_role: str = "agent",
):
def prompter(messages: List[Dict[str, str]]):
nonlocal message_key, role_key, content_key, user_role, agent_role
role_dict = {
"user": user_role,
"agent": agent_role,
}
prompt = []
for item in messages:
prompt.append(
{role_key: role_dict[item["role"]], content_key: item["content"]}
)
return {message_key: prompt}
return prompter
@staticmethod
def prompt_string(
prefix: str = "",
suffix: str = "AGENT:",
user_format: str = "USER: {content}\n\n",
agent_format: str = "AGENT: {content}\n\n",
prompt_key: str = "prompt",
):
def prompter(messages: List[Dict[str, str]]):
nonlocal prefix, suffix, user_format, agent_format, prompt_key
prompt = prefix
for item in messages:
if item["role"] == "user":
prompt += user_format.format(content=item["content"])
else:
prompt += agent_format.format(content=item["content"])
prompt += suffix
print(prompt)
return {prompt_key: prompt}
return prompter
@staticmethod
def claude():
return Prompter.prompt_string(
prefix="",
suffix="Assistant:",
user_format="Human: {content}\n\n",
agent_format="Assistant: {content}\n\n",
)
@staticmethod
def palm():
def prompter(messages):
return {"instances": [
Prompter.role_content_dict("messages", "author", "content", "user", "bot")(messages)
]}
return prompter
def check_context_limit(content: str):
content = content.lower()
and_words = [
["prompt", "context", "tokens"],
[
"limit",
"exceed",
"max",
"long",
"much",
"many",
"reach",
"over",
"up",
"beyond",
],
]
rule = AndRule(
[
OrRule([ContainRule(word) for word in and_words[i]])
for i in range(len(and_words))
]
)
return rule.check(content)
class HTTPAgent(AgentClient):
def __init__(
self,
url,
proxies=None,
body=None,
headers=None,
return_format="{response}",
prompter=None,
**kwargs,
) -> None:
super().__init__(**kwargs)
self.url = url
self.proxies = proxies or {}
self.headers = headers or {}
self.body = body or {}
self.return_format = return_format
self.prompter = Prompter.get_prompter(prompter)
self.key_list = self.headers["Authorization"] if type(self.headers["Authorization"]) == list else [self.headers["Authorization"]]
self.key_amount = len(self.key_list)
self.key_idx = 0
if not self.url:
raise Exception("Please set 'url' parameter")
def _handle_history(self, history: List[dict]) -> Dict[str, Any]:
return self.prompter(history)
def _authorization_scheduling(self):
self.headers["Authorization"] = self.key_list[self.key_idx]
self.key_idx = (self.key_idx + 1) % self.key_amount
def inference(self, history: List[dict]) -> str:
self._authorization_scheduling()
for _ in range(3):
try:
body = self.body.copy()
body.update(self._handle_history(history))
with no_ssl_verification():
resp = requests.post(
self.url, json=body, headers=self.headers, proxies=self.proxies, timeout=120
)
# print(resp.status_code, resp.text)
if resp.status_code != 200:
# print(resp.text)
if check_context_limit(resp.text):
raise AgentContextLimitException(resp.text)
else:
raise Exception(
f"Invalid status code {resp.status_code}:\n\n{resp.text}"
)
except AgentClientException as e:
raise e
except Exception as e:
print("Warning: ", e)
pass
else:
resp = resp.json()
return self.return_format.format(response=resp)
time.sleep(_ + 2)
raise Exception("Failed.")