返回提交历史
Modified
g4f/Provider/airforce/AirforceChat.py
+93
-93
XFEstudio/gpt4free
Update (g4f/Provider/airforce/AirforceChat.py)
9a034619
代码差异
1 个文件
+93
-93
@@ -1,14 +1,15 @@
1
1
from __future__ import annotations
2
2
import re
3
from aiohttp import ClientSession
4
3
import json
5
from typing import List
4
from aiohttp import ClientSession
6
5
import requests
6
from typing import List
7
7
8
8
from ...typing import AsyncResult, Messages
9
9
from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
10
10
from ..helper import format_prompt
11
11
12
# Helper function to clean the response
12
13
def clean_response(text: str) -> str:
13
14
"""Clean response from unwanted patterns."""
14
15
patterns = [
@@ -16,35 +17,27 @@ def clean_response(text: str) -> str:
16
17
r"Rate limit \(\d+\/minute\) exceeded\. Join our discord for more: .+https:\/\/discord\.com\/invite\/\S+",
17
18
r"Rate limit \(\d+\/hour\) exceeded\. Join our discord for more: https:\/\/discord\.com\/invite\/\S+",
18
19
r"</s>", # zephyr-7b-beta
20
r"\[ERROR\] '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}'", # Matches [ERROR] 'UUID'
19
21
]
20
21
22
for pattern in patterns:
22
23
text = re.sub(pattern, '', text)
23
24
return text.strip()
24
25
25
def split_message(message: dict, chunk_size: int = 995) -> List[dict]:
26
"""Split a message into chunks of specified size."""
27
content = message.get('content', '')
28
if len(content) <= chunk_size:
29
return [message]
30
26
def split_message(message: str, max_length: int = 1000) -> List[str]:
27
"""Splits the message into chunks of a given length (max_length)"""
28
# Split the message into smaller chunks to avoid exceeding the limit
31
29
chunks = []
32
while content:
33
chunk = content[:chunk_size]
34
content = content[chunk_size:]
35
chunks.append({
36
'role': message['role'],
37
'content': chunk
38
})
30
while len(message) > max_length:
31
# Find the last space or punctuation before max_length to avoid cutting words
32
split_point = message.rfind(' ', 0, max_length)
33
if split_point == -1: # No space found, split at max_length
34
split_point = max_length
35
chunks.append(message[:split_point])
36
message = message[split_point:].strip()
37
if message:
38
chunks.append(message) # Append the remaining part of the message
39
39
return chunks
40
40
41
def split_messages(messages: Messages, chunk_size: int = 995) -> Messages:
42
"""Split all messages that exceed chunk_size into smaller messages."""
43
result = []
44
for message in messages:
45
result.extend(split_message(message, chunk_size))
46
return result
47
48
41
class AirforceChat(AsyncGeneratorProvider, ProviderModelMixin):
49
42
label = "AirForce Chat"
50
43
api_endpoint = "https://api.airforce/chat/completions"
@@ -57,45 +50,44 @@ class AirforceChat(AsyncGeneratorProvider, ProviderModelMixin):
57
50
data = response.json()
58
51
59
52
text_models = [model['id'] for model in data['data']]
60
61
53
models = [*text_models]
62
54
63
55
model_aliases = {
64
# openchat
65
"openchat-3.5": "openchat-3.5-0106",
66
67
# deepseek-ai
68
"deepseek-coder": "deepseek-coder-6.7b-instruct",
69
70
# NousResearch
71
"hermes-2-dpo": "Nous-Hermes-2-Mixtral-8x7B-DPO",
72
"hermes-2-pro": "hermes-2-pro-mistral-7b",
73
74
# teknium
75
"openhermes-2.5": "openhermes-2.5-mistral-7b",
76
77
# liquid
78
"lfm-40b": "lfm-40b-moe",
79
80
# DiscoResearch
81
"german-7b": "discolm-german-7b-v1",
82
83
# meta-llama
84
"llama-2-7b": "llama-2-7b-chat-int8",
85
"llama-2-7b": "llama-2-7b-chat-fp16",
86
"llama-3.1-70b": "llama-3.1-70b-chat",
87
"llama-3.1-8b": "llama-3.1-8b-chat",
88
"llama-3.1-70b": "llama-3.1-70b-turbo",
89
"llama-3.1-8b": "llama-3.1-8b-turbo",
90
91
# inferless
92
"neural-7b": "neural-chat-7b-v3-1",
93
94
# HuggingFaceH4
95
"zephyr-7b": "zephyr-7b-beta",
96
97
# llmplayground.net
98
#"any-uncensored": "any-uncensored",
56
# openchat
57
"openchat-3.5": "openchat-3.5-0106",
58
59
# deepseek-ai
60
"deepseek-coder": "deepseek-coder-6.7b-instruct",
61
62
# NousResearch
63
"hermes-2-dpo": "Nous-Hermes-2-Mixtral-8x7B-DPO",
64
"hermes-2-pro": "hermes-2-pro-mistral-7b",
65
66
# teknium
67
"openhermes-2.5": "openhermes-2.5-mistral-7b",
68
69
# liquid
70
"lfm-40b": "lfm-40b-moe",
71
72
# DiscoResearch
73
"german-7b": "discolm-german-7b-v1",
74
75
# meta-llama
76
"llama-2-7b": "llama-2-7b-chat-int8",
77
"llama-2-7b": "llama-2-7b-chat-fp16",
78
"llama-3.1-70b": "llama-3.1-70b-chat",
79
"llama-3.1-8b": "llama-3.1-8b-chat",
80
"llama-3.1-70b": "llama-3.1-70b-turbo",
81
"llama-3.1-8b": "llama-3.1-8b-turbo",
82
83
# inferless
84
"neural-7b": "neural-chat-7b-v3-1",
85
86
# HuggingFaceH4
87
"zephyr-7b": "zephyr-7b-beta",
88
89
# llmplayground.net
90
#"any-uncensored": "any-uncensored",
99
91
}
100
92
101
93
@classmethod
@@ -112,8 +104,6 @@ class AirforceChat(AsyncGeneratorProvider, ProviderModelMixin):
112
104
) -> AsyncResult:
113
105
model = cls.get_model(model)
114
106
115
chunked_messages = split_messages(messages)
116
117
107
headers = {
118
108
'accept': '*/*',
119
109
'accept-language': 'en-US,en;q=0.9',
@@ -133,36 +123,46 @@ class AirforceChat(AsyncGeneratorProvider, ProviderModelMixin):
133
123
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36'
134
124
}
135
125
136
data = {
137
"messages": chunked_messages,
138
"model": model,
139
"max_tokens": max_tokens,
140
"temperature": temperature,
141
"top_p": top_p,
142
"stream": stream
143
}
126
# Format the messages for the API
127
formatted_messages = format_prompt(messages)
128
message_chunks = split_message(formatted_messages)
129
130
full_response = ""
131
for chunk in message_chunks:
132
data = {
133
"messages": [{"role": "user", "content": chunk}],
134
"model": model,
135
"max_tokens": max_tokens,
136
"temperature": temperature,
137
"top_p": top_p,
138
"stream": stream
139
}
140
141
async with ClientSession(headers=headers) as session:
142
async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
143
response.raise_for_status()
144
144
145
async with ClientSession(headers=headers) as session:
146
async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response:
147
response.raise_for_status()
148
text = ""
149
if stream:
150
async for line in response.content:
151
line = line.decode('utf-8')
152
if line.startswith('data: '):
153
json_str = line[6:]
154
try:
155
chunk = json.loads(json_str)
156
if 'choices' in chunk and chunk['choices']:
157
content = chunk['choices'][0].get('delta', {}).get('content', '')
158
text += content
159
except json.JSONDecodeError as e:
160
print(f"Error decoding JSON: {json_str}, Error: {e}")
161
elif line.strip() == "[DONE]":
162
break
163
yield clean_response(text)
164
else:
165
response_json = await response.json()
166
text = response_json["choices"][0]["message"]["content"]
167
yield clean_response(text)
145
text = ""
146
if stream:
147
async for line in response.content:
148
line = line.decode('utf-8').strip()
149
if line.startswith('data: '):
150
json_str = line[6:]
151
try:
152
if json_str and json_str != "[DONE]":
153
chunk = json.loads(json_str)
154
if 'choices' in chunk and chunk['choices']:
155
content = chunk['choices'][0].get('delta', {}).get('content', '')
156
text += content
157
except json.JSONDecodeError as e:
158
print(f"Error decoding JSON: {json_str}, Error: {e}")
159
elif line == "[DONE]":
160
break
161
full_response += clean_response(text)
162
else:
163
response_json = await response.json()
164
text = response_json["choices"][0]["message"]["content"]
165
full_response += clean_response(text)
168
166
167
# Return the complete response after all chunks
168
yield full_response