chase535
commited on
Commit
·
3fda982
1
Parent(s):
b47606f
同步上游更新
Browse files- OPENAI.md +8 -8
- docker-compose.yml +10 -0
- server.js +8 -0
- src/lib/bots/bing/types.ts +1 -0
- src/lib/utils.ts +13 -12
- src/pages/api/sydney.ts +7 -2
OPENAI.md
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
### 示例
|
21 |
以下以 `curl` 为例
|
22 |
```
|
23 |
-
curl -kL 'https://
|
24 |
-H 'Content-Type: application/json' \
|
25 |
-d '{
|
26 |
"messages":[{"role":"user","content":"你好"}],
|
@@ -41,7 +41,7 @@ curl -kL 'https://hf4all-bingo-api.hf.space/api/v1/chat/completions' \
|
|
41 |
```
|
42 |
import openai
|
43 |
openai.api_key = "dummy"
|
44 |
-
openai.api_base = "https://
|
45 |
|
46 |
# create a chat completion
|
47 |
chat_completion = openai.ChatCompletion.create(model="Creative", messages=[{"role": "user", "content": "Hello"}])
|
@@ -54,7 +54,7 @@ print(chat_completion.choices[0].message.content)
|
|
54 |
```
|
55 |
import openai
|
56 |
openai.api_key = "dummy"
|
57 |
-
openai.api_base = "https://
|
58 |
|
59 |
# create a chat completion
|
60 |
completion = openai.ChatCompletion.create(model="Creative", stream=True, messages=[{"role": "user", "content": "Hello"}])
|
@@ -71,7 +71,7 @@ for chat_completion in completion:
|
|
71 |
import OpenAI from 'openai';
|
72 |
|
73 |
const openai = new OpenAI({
|
74 |
-
baseURL: 'https://
|
75 |
});
|
76 |
|
77 |
async function main() {
|
@@ -92,9 +92,9 @@ main();
|
|
92 |
|
93 |
## 在线演示
|
94 |
|
95 |
-
https://huggingface.co/spaces/hf4all/next-
|
|
|
|
|
96 |
|
97 |
-
[![Deploy to HuggingFace](https://img.shields.io/badge/点此部署-%F0%9F%A4%97-fff)](https://huggingface.co/login?next=%2Fspaces%2Fhf4all%2Fnext-web-bing%3Fduplicate%3Dtrue%26visibility%3Dpublic) 配置可以不改
|
98 |
|
99 |
-
|
100 |
-
[![gpt-next-web-bing](./docs/images/openai.png)](https://huggingface.co/spaces/hf4all/next-web-bing)
|
|
|
20 |
### 示例
|
21 |
以下以 `curl` 为例
|
22 |
```
|
23 |
+
curl -kL 'https://copilot.github1s.tk/api/v1/chat/completions' \
|
24 |
-H 'Content-Type: application/json' \
|
25 |
-d '{
|
26 |
"messages":[{"role":"user","content":"你好"}],
|
|
|
41 |
```
|
42 |
import openai
|
43 |
openai.api_key = "dummy"
|
44 |
+
openai.api_base = "https://copilot.github1s.tk" # 这里可以改为你自己部署的服务,bingo 服务版本需要 >= 0.9.0
|
45 |
|
46 |
# create a chat completion
|
47 |
chat_completion = openai.ChatCompletion.create(model="Creative", messages=[{"role": "user", "content": "Hello"}])
|
|
|
54 |
```
|
55 |
import openai
|
56 |
openai.api_key = "dummy"
|
57 |
+
openai.api_base = "https://copilot.github1s.tk" # 这里可以改为你自己部署的服务,bingo 服务版本需要 >= 0.9.0
|
58 |
|
59 |
# create a chat completion
|
60 |
completion = openai.ChatCompletion.create(model="Creative", stream=True, messages=[{"role": "user", "content": "Hello"}])
|
|
|
71 |
import OpenAI from 'openai';
|
72 |
|
73 |
const openai = new OpenAI({
|
74 |
+
baseURL: 'https://copilot.github1s.tk' // 这里可以改为你自己部署的服务,bingo 服务版本需要 >= 0.9.0
|
75 |
});
|
76 |
|
77 |
async function main() {
|
|
|
92 |
|
93 |
## 在线演示
|
94 |
|
95 |
+
1. https://huggingface.co/spaces/hf4all/chatbot-ui-bing [![Deploy Chatbot UI](https://img.shields.io/badge/点此部署-%F0%9F%A4%97-fff)](https://huggingface.co/login?next=%2Fspaces%2Fhf4all%2Fchatbot-ui-bing%3Fduplicate%3Dtrue%26visibility%3Dpublic)
|
96 |
+
2. https://huggingface.co/spaces/hf4all/chatgpt-next-web-bing
|
97 |
+
[![Deploy ChatGPT Next Web](https://img.shields.io/badge/点此部署-%F0%9F%A4%97-fff)](https://huggingface.co/login?next=%2Fspaces%2Fhf4all%2Fchatgpt-next-web-bing%3Fduplicate%3Dtrue%26visibility%3Dpublic)
|
98 |
|
|
|
99 |
|
100 |
+
[![效果图](./docs/images/openai.png)](https://huggingface.co/spaces/hf4all/chatgpt-next-web-bing)
|
|
docker-compose.yml
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: '3.5'
|
2 |
+
|
3 |
+
services:
|
4 |
+
bingo:
|
5 |
+
image: weaigc/bingo
|
6 |
+
container_name: bingo
|
7 |
+
ports:
|
8 |
+
- "7860:7860"
|
9 |
+
environment:
|
10 |
+
# - BING_HEADER=xxx # 这里配置自己的 BING_HEADER 信息
|
server.js
CHANGED
@@ -33,6 +33,14 @@ app.prepare().then(() => {
|
|
33 |
})
|
34 |
} else if (pathname.endsWith('/completions')) {
|
35 |
await app.render(req, res, '/api/openai/chat/completions', query)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
} else {
|
37 |
await handle(req, res, parsedUrl)
|
38 |
}
|
|
|
33 |
})
|
34 |
} else if (pathname.endsWith('/completions')) {
|
35 |
await app.render(req, res, '/api/openai/chat/completions', query)
|
36 |
+
} else if (pathname.endsWith('/models')) {
|
37 |
+
res.end(JSON.stringify({
|
38 |
+
data: [
|
39 |
+
{
|
40 |
+
id: 'gpt-4',
|
41 |
+
}
|
42 |
+
],
|
43 |
+
}))
|
44 |
} else {
|
45 |
await handle(req, res, parsedUrl)
|
46 |
}
|
src/lib/bots/bing/types.ts
CHANGED
@@ -146,6 +146,7 @@ export interface ConversationInfo extends ConversationInfoBase {
|
|
146 |
conversationStyle: BingConversationStyle
|
147 |
prompt: string
|
148 |
imageUrl?: string
|
|
|
149 |
}
|
150 |
|
151 |
export interface Throttling {
|
|
|
146 |
conversationStyle: BingConversationStyle
|
147 |
prompt: string
|
148 |
imageUrl?: string
|
149 |
+
source?: 'cib' | 'WindowsCopilot'
|
150 |
}
|
151 |
|
152 |
export interface Throttling {
|
src/lib/utils.ts
CHANGED
@@ -82,7 +82,7 @@ export function parseHeadersFromCurl(content: string) {
|
|
82 |
return headers
|
83 |
}
|
84 |
|
85 |
-
export const ChunkKeys = ['
|
86 |
|
87 |
export function encodeHeadersToCookie(content: string) {
|
88 |
const base64Content = btoa(content)
|
@@ -90,11 +90,8 @@ export function encodeHeadersToCookie(content: string) {
|
|
90 |
return ChunkKeys.map((key, index) => `${key}=${contentChunks[index] ?? ''}`)
|
91 |
}
|
92 |
|
93 |
-
export function extraCurlFromCookie(cookies: Partial<{ [key: string]: string }>) {
|
94 |
-
|
95 |
-
ChunkKeys.forEach((key) => {
|
96 |
-
base64Content += (cookies[key] || '')
|
97 |
-
})
|
98 |
try {
|
99 |
return atob(base64Content)
|
100 |
} catch (e) {
|
@@ -133,7 +130,7 @@ export function parseCookies(cookie: string, cookieNames: string[]) {
|
|
133 |
}
|
134 |
|
135 |
export function resetCookies() {
|
136 |
-
[...ChunkKeys, 'BING_COOKIE', 'BING_UA', '_U', 'BING_IP', 'MUID'].forEach(key => setCookie(key, ''))
|
137 |
}
|
138 |
|
139 |
export const DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.0.0'
|
@@ -145,14 +142,16 @@ export function parseUA(ua?: string, default_ua = DEFAULT_UA) {
|
|
145 |
|
146 |
export function mockUser(cookies: Partial<{ [key: string]: string }>) {
|
147 |
const {
|
148 |
-
BING_HEADER
|
|
|
149 |
BING_UA = process.env.BING_UA,
|
150 |
-
BING_IP = process.env.BING_IP
|
151 |
} = cookies
|
152 |
const ua = parseUA(BING_UA)
|
153 |
|
154 |
const { _U, MUID } = parseCookies(extraHeadersFromCookie({
|
155 |
BING_HEADER,
|
|
|
156 |
...cookies,
|
157 |
}).cookie, ['MUID'])
|
158 |
|
@@ -169,16 +168,18 @@ export function mockUser(cookies: Partial<{ [key: string]: string }>) {
|
|
169 |
|
170 |
export function createHeaders(cookies: Partial<{ [key: string]: string }>, useMock?: boolean) {
|
171 |
let {
|
172 |
-
BING_HEADER
|
173 |
-
|
|
|
174 |
IMAGE_ONLY = process.env.IMAGE_ONLY ?? '1',
|
175 |
} = cookies || {}
|
176 |
useMock = useMock ?? /^(1|true|yes)$/i.test(String(IMAGE_ONLY))
|
177 |
-
if (!BING_HEADER || useMock) {
|
178 |
return mockUser(cookies)
|
179 |
}
|
180 |
const headers = extraHeadersFromCookie({
|
181 |
BING_HEADER,
|
|
|
182 |
...cookies,
|
183 |
})
|
184 |
headers['x-forwarded-for'] = BING_IP || randomIP()
|
|
|
82 |
return headers
|
83 |
}
|
84 |
|
85 |
+
export const ChunkKeys = ['BING_HEADER0', 'BING_HEADER1', 'BING_HEADER2']
|
86 |
|
87 |
export function encodeHeadersToCookie(content: string) {
|
88 |
const base64Content = btoa(content)
|
|
|
90 |
return ChunkKeys.map((key, index) => `${key}=${contentChunks[index] ?? ''}`)
|
91 |
}
|
92 |
|
93 |
+
export function extraCurlFromCookie(cookies: Partial<{ [key: string]: string }> = {}) {
|
94 |
+
const base64Content = cookies.BING_HEADER || ChunkKeys.map((key) => cookies[key] || '').join('')
|
|
|
|
|
|
|
95 |
try {
|
96 |
return atob(base64Content)
|
97 |
} catch (e) {
|
|
|
130 |
}
|
131 |
|
132 |
export function resetCookies() {
|
133 |
+
[...ChunkKeys, 'BING_HEADER', '', 'BING_COOKIE', 'BING_UA', '_U', 'BING_IP', 'MUID'].forEach(key => setCookie(key, ''))
|
134 |
}
|
135 |
|
136 |
export const DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.0.0'
|
|
|
142 |
|
143 |
export function mockUser(cookies: Partial<{ [key: string]: string }>) {
|
144 |
const {
|
145 |
+
BING_HEADER,
|
146 |
+
BING_HEADER0 = process.env.BING_HEADER,
|
147 |
BING_UA = process.env.BING_UA,
|
148 |
+
BING_IP = process.env.BING_IP,
|
149 |
} = cookies
|
150 |
const ua = parseUA(BING_UA)
|
151 |
|
152 |
const { _U, MUID } = parseCookies(extraHeadersFromCookie({
|
153 |
BING_HEADER,
|
154 |
+
BING_HEADER0,
|
155 |
...cookies,
|
156 |
}).cookie, ['MUID'])
|
157 |
|
|
|
168 |
|
169 |
export function createHeaders(cookies: Partial<{ [key: string]: string }>, useMock?: boolean) {
|
170 |
let {
|
171 |
+
BING_HEADER,
|
172 |
+
BING_HEADER0 = process.env.BING_HEADER,
|
173 |
+
BING_IP = process.env.BING_IP,
|
174 |
IMAGE_ONLY = process.env.IMAGE_ONLY ?? '1',
|
175 |
} = cookies || {}
|
176 |
useMock = useMock ?? /^(1|true|yes)$/i.test(String(IMAGE_ONLY))
|
177 |
+
if ((!BING_HEADER && !BING_HEADER0) || useMock) {
|
178 |
return mockUser(cookies)
|
179 |
}
|
180 |
const headers = extraHeadersFromCookie({
|
181 |
BING_HEADER,
|
182 |
+
BING_HEADER0,
|
183 |
...cookies,
|
184 |
})
|
185 |
headers['x-forwarded-for'] = BING_IP || randomIP()
|
src/pages/api/sydney.ts
CHANGED
@@ -14,7 +14,7 @@ const { WS_ENDPOINT = 'sydney.bing.com' } = process.env
|
|
14 |
|
15 |
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
16 |
const conversationContext = req.body
|
17 |
-
const headers = createHeaders(req.cookies
|
18 |
const id = headers['x-forwarded-for']
|
19 |
// headers['x-forwarded-for'] = conversationContext?.userIpAddress || headers['x-forwarded-for']
|
20 |
|
@@ -62,7 +62,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|
62 |
await new Promise((resolve) => ws.onopen = resolve)
|
63 |
ws.send(websocketUtils.packMessage({ protocol: 'json', version: 1 }))
|
64 |
ws.send(websocketUtils.packMessage({ type: 6 }))
|
65 |
-
ws.send(websocketUtils.packMessage(
|
|
|
|
|
|
|
|
|
|
|
66 |
req.socket.once('close', () => {
|
67 |
debug(id, 'connection close')
|
68 |
ws.close()
|
|
|
14 |
|
15 |
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
16 |
const conversationContext = req.body
|
17 |
+
const headers = createHeaders(req.cookies)
|
18 |
const id = headers['x-forwarded-for']
|
19 |
// headers['x-forwarded-for'] = conversationContext?.userIpAddress || headers['x-forwarded-for']
|
20 |
|
|
|
62 |
await new Promise((resolve) => ws.onopen = resolve)
|
63 |
ws.send(websocketUtils.packMessage({ protocol: 'json', version: 1 }))
|
64 |
ws.send(websocketUtils.packMessage({ type: 6 }))
|
65 |
+
ws.send(websocketUtils.packMessage(
|
66 |
+
BingWebBot.buildChatRequest({
|
67 |
+
...conversationContext,
|
68 |
+
source: req.cookies?.BING_SOURCE,
|
69 |
+
})
|
70 |
+
))
|
71 |
req.socket.once('close', () => {
|
72 |
debug(id, 'connection close')
|
73 |
ws.close()
|