返回提交历史
Modified
docs/async_client.md
+6
-5
Modified
docs/client.md
+3
-2
Modified
g4f/Provider/Copilot.py
+49
-4
Modified
g4f/cli.py
+4
-2
Modified
g4f/gui/client/static/css/style.css
+4
-0
XFEstudio/gpt4free
Add .har file support for Copilot Update provider in Vision documentation Hide
46038c6a
代码差异
5 个文件
+66
-13
@@ -154,13 +154,14 @@ import asyncio
154
154
from g4f.client import AsyncClient
155
155
156
156
async def main():
157
client = AsyncClient()
158
157
client = AsyncClient(
158
provider=g4f.Provider.CopilotAccount
159
)
160
159
161
image = requests.get("https://raw.githubusercontent.com/xtekky/gpt4free/refs/heads/main/docs/cat.jpeg", stream=True).raw
160
162
161
163
response = await client.chat.completions.create(
162
164
model=g4f.models.default,
163
provider=g4f.Provider.Bing,
164
165
messages=[
165
166
{
166
167
"role": "user",
@@ -169,7 +170,7 @@ async def main():
169
170
],
170
171
image=image
171
172
)
172
173
173
174
print(response.choices[0].message.content)
174
175
175
176
asyncio.run(main())
@@ -265,7 +265,9 @@ from g4f.client import Client
265
265
image = requests.get("https://raw.githubusercontent.com/xtekky/gpt4free/refs/heads/main/docs/cat.jpeg", stream=True).raw
266
266
# Or: image = open("docs/cat.jpeg", "rb")
267
267
268
client = Client()
268
client = Client(
269
provider=CopilotAccount
270
)
269
271
270
272
response = client.chat.completions.create(
271
273
model=g4f.models.default,
@@ -275,7 +277,6 @@ response = client.chat.completions.create(
275
277
"content": "What are on this image?"
276
278
}
277
279
],
278
provider=g4f.Provider.Bing,
279
280
image=image
280
281
# Add any other necessary parameters
281
282
)
@@ -1,5 +1,6 @@
1
1
from __future__ import annotations
2
2
3
import os
3
4
import json
4
5
import asyncio
5
6
from http.cookiejar import CookieJar
@@ -21,9 +22,11 @@ from .helper import format_prompt
21
22
from ..typing import CreateResult, Messages, ImageType
22
23
from ..errors import MissingRequirementsError
23
24
from ..requests.raise_for_status import raise_for_status
24
from ..providers.helper import format_cookies
25
from ..providers.asyncio import get_running_loop
26
from ..Provider.openai.har_file import NoValidHarFileError, get_headers
25
27
from ..requests import get_nodriver
26
28
from ..image import ImageResponse, to_bytes, is_accepted_format
29
from ..cookies import get_cookies_dir
27
30
from .. import debug
28
31
29
32
class Conversation(BaseConversation):
@@ -69,7 +72,15 @@ class Copilot(AbstractProvider):
69
72
cookies = conversation.cookie_jar if conversation is not None else None
70
73
if cls.needs_auth or image is not None:
71
74
if conversation is None or conversation.access_token is None:
72
access_token, cookies = asyncio.run(cls.get_access_token_and_cookies(proxy))
75
try:
76
access_token, cookies = readHAR()
77
except NoValidHarFileError as h:
78
debug.log(f"Copilot: {h}")
79
try:
80
get_running_loop(check_nested=True)
81
access_token, cookies = asyncio.run(cls.get_access_token_and_cookies(proxy))
82
except MissingRequirementsError:
83
raise h
73
84
else:
74
85
access_token = conversation.access_token
75
86
debug.log(f"Copilot: Access token: {access_token[:7]}...{access_token[-5:]}")
@@ -159,7 +170,9 @@ class Copilot(AbstractProvider):
159
170
for (var i = 0; i < localStorage.length; i++) {
160
171
try {
161
172
item = JSON.parse(localStorage.getItem(localStorage.key(i)));
162
if (item.credentialType == "AccessToken") {
173
if (item.credentialType == "AccessToken"
174
&& item.expiresOn > Math.floor(Date.now() / 1000)
175
&& item.target.includes("ChatAI")) {
163
176
return item.secret;
164
177
}
165
178
} catch(e) {}
@@ -172,4 +185,36 @@ class Copilot(AbstractProvider):
172
185
for c in await page.send(nodriver.cdp.network.get_cookies([cls.url])):
173
186
cookies[c.name] = c.value
174
187
await page.close()
175
return access_token, cookies
188
return access_token, cookies
189
190
def readHAR():
191
harPath = []
192
for root, _, files in os.walk(get_cookies_dir()):
193
for file in files:
194
if file.endswith(".har"):
195
harPath.append(os.path.join(root, file))
196
if not harPath:
197
raise NoValidHarFileError("No .har file found")
198
api_key = None
199
cookies = None
200
for path in harPath:
201
with open(path, 'rb') as file:
202
try:
203
harFile = json.loads(file.read())
204
except json.JSONDecodeError:
205
# Error: not a HAR file!
206
continue
207
for v in harFile['log']['entries']:
208
v_headers = get_headers(v)
209
if v['request']['url'].startswith(Copilot.url):
210
try:
211
if "authorization" in v_headers:
212
api_key = v_headers["authorization"].split(maxsplit=1).pop()
213
except Exception as e:
214
debug.log(f"Error on read headers: {e}")
215
if v['request']['cookies']:
216
cookies = {c['name']: c['value'] for c in v['request']['cookies']}
217
if api_key is None:
218
raise NoValidHarFileError("No access token found in .har files")
219
220
return api_key, cookies
@@ -10,8 +10,9 @@ def main():
10
10
parser = argparse.ArgumentParser(description="Run gpt4free")
11
11
subparsers = parser.add_subparsers(dest="mode", help="Mode to run the g4f in.")
12
12
api_parser = subparsers.add_parser("api")
13
api_parser.add_argument("--bind", default="0.0.0.0:1337", help="The bind string.")
14
api_parser.add_argument("--debug", action="store_true", help="Enable verbose logging.")
13
api_parser.add_argument("--bind", default=None, help="The bind string. (Default: 0.0.0.0:1337)")
14
api_parser.add_argument("--port", default=None, help="Change the port of the server.")
15
api_parser.add_argument("--debug", "-d", action="store_true", help="Enable verbose logging.")
15
16
api_parser.add_argument("--gui", "-g", default=False, action="store_true", help="Add gui to the api.")
16
17
api_parser.add_argument("--model", default=None, help="Default model for chat completion. (incompatible with --reload and --workers)")
17
18
api_parser.add_argument("--provider", choices=[provider.__name__ for provider in Provider.__providers__ if provider.working],
@@ -55,6 +56,7 @@ def run_api_args(args):
55
56
g4f.cookies.browsers = [g4f.cookies[browser] for browser in args.cookie_browsers]
56
57
run_api(
57
58
bind=args.bind,
59
port=args.port,
58
60
debug=args.debug,
59
61
workers=args.workers,
60
62
use_colors=not args.disable_colors,
@@ -177,6 +177,10 @@ body {
177
177
filter: blur(calc(0.5 * 70vw)) opacity(var(--opacity));
178
178
}
179
179
180
body.white .gradient{
181
display: none;
182
}
183
180
184
.conversations {
181
185
display: flex;
182
186
flex-direction: column;