Spaces:
Build error
Build error
import * as dotenv from 'dotenv' | |
import 'isomorphic-fetch' | |
import type { ChatGPTAPIOptions, ChatMessage, SendMessageOptions } from 'chatgpt' | |
import { ChatGPTAPI, ChatGPTUnofficialProxyAPI } from 'chatgpt' | |
import { SocksProxyAgent } from 'socks-proxy-agent' | |
import { HttpsProxyAgent } from 'https-proxy-agent' | |
import fetch from 'node-fetch' | |
import { sendResponse } from '../utils' | |
import type { ApiModel, ChatContext, ChatGPTUnofficialProxyAPIOptions, ModelConfig } from '../types' | |
const ErrorCodeMessage: Record<string, string> = { | |
401: '[OpenAI] 提供错误的API密钥 | Incorrect API key provided', | |
403: '[OpenAI] 服务器拒绝访问,请稍后再试 | Server refused to access, please try again later', | |
502: '[OpenAI] 错误的网关 | Bad Gateway', | |
503: '[OpenAI] 服务器繁忙,请稍后再试 | Server is busy, please try again later', | |
504: '[OpenAI] 网关超时 | Gateway Time-out', | |
500: '[OpenAI] 服务器繁忙,请稍后再试 | Internal Server Error', | |
} | |
dotenv.config() | |
const timeoutMs: number = !isNaN(+process.env.TIMEOUT_MS) ? +process.env.TIMEOUT_MS : 30 * 1000 | |
let apiModel: ApiModel | |
if (!process.env.OPENAI_API_KEY && !process.env.OPENAI_ACCESS_TOKEN) | |
throw new Error('Missing OPENAI_API_KEY or OPENAI_ACCESS_TOKEN environment variable') | |
let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI | |
(async () => { | |
// More Info: https://github.com/transitive-bullshit/chatgpt-api | |
if (process.env.OPENAI_API_KEY) { | |
const OPENAI_API_MODEL = process.env.OPENAI_API_MODEL | |
const model = (typeof OPENAI_API_MODEL === 'string' && OPENAI_API_MODEL.length > 0) | |
? OPENAI_API_MODEL | |
: 'gpt-3.5-turbo' | |
const options: ChatGPTAPIOptions = { | |
apiKey: process.env.OPENAI_API_KEY, | |
completionParams: { model }, | |
debug: false, | |
} | |
if (process.env.OPENAI_API_BASE_URL && process.env.OPENAI_API_BASE_URL.trim().length > 0) | |
options.apiBaseUrl = process.env.OPENAI_API_BASE_URL | |
if (process.env.SOCKS_PROXY_HOST && process.env.SOCKS_PROXY_PORT) { | |
const agent = new SocksProxyAgent({ | |
hostname: process.env.SOCKS_PROXY_HOST, | |
port: process.env.SOCKS_PROXY_PORT, | |
}) | |
options.fetch = (url, options) => { | |
return fetch(url, { agent, ...options }) | |
} | |
} | |
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.ALL_PROXY || process.env.all_proxy | |
if (httpsProxy) { | |
const agent = new HttpsProxyAgent(httpsProxy) | |
options.fetch = (url, options) => { | |
return fetch(url, { agent, ...options }) | |
} | |
} | |
api = new ChatGPTAPI({ ...options }) | |
apiModel = 'ChatGPTAPI' | |
} | |
else { | |
const options: ChatGPTUnofficialProxyAPIOptions = { | |
accessToken: process.env.OPENAI_ACCESS_TOKEN, | |
debug: false, | |
} | |
if (process.env.SOCKS_PROXY_HOST && process.env.SOCKS_PROXY_PORT) { | |
const agent = new SocksProxyAgent({ | |
hostname: process.env.SOCKS_PROXY_HOST, | |
port: process.env.SOCKS_PROXY_PORT, | |
}) | |
options.fetch = (url, options) => { | |
return fetch(url, { agent, ...options }) | |
} | |
} | |
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.ALL_PROXY || process.env.all_proxy | |
if (httpsProxy) { | |
const agent = new HttpsProxyAgent(httpsProxy) | |
options.fetch = (url, options) => { | |
return fetch(url, { agent, ...options }) | |
} | |
} | |
if (process.env.API_REVERSE_PROXY) | |
options.apiReverseProxyUrl = process.env.API_REVERSE_PROXY | |
api = new ChatGPTUnofficialProxyAPI({ ...options }) | |
apiModel = 'ChatGPTUnofficialProxyAPI' | |
} | |
})() | |
async function chatReplyProcess( | |
message: string, | |
lastContext?: { conversationId?: string; parentMessageId?: string }, | |
process?: (chat: ChatMessage) => void, | |
) { | |
// if (!message) | |
// return sendResponse({ type: 'Fail', message: 'Message is empty' }) | |
try { | |
let options: SendMessageOptions = { timeoutMs } | |
if (lastContext) { | |
if (apiModel === 'ChatGPTAPI') | |
options = { parentMessageId: lastContext.parentMessageId } | |
else | |
options = { ...lastContext } | |
} | |
const response = await api.sendMessage(message, { | |
...options, | |
onProgress: (partialResponse) => { | |
process?.(partialResponse) | |
}, | |
}) | |
return sendResponse({ type: 'Success', data: response }) | |
} | |
catch (error: any) { | |
const code = error.statusCode | |
global.console.log(error) | |
if (Reflect.has(ErrorCodeMessage, code)) | |
return sendResponse({ type: 'Fail', message: ErrorCodeMessage[code] }) | |
return sendResponse({ type: 'Fail', message: error.message ?? 'Please check the back-end console' }) | |
} | |
} | |
async function chatConfig() { | |
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.ALL_PROXY || process.env.all_proxy | |
return sendResponse({ | |
type: 'Success', | |
data: { | |
apiModel, | |
reverseProxy: process.env.API_REVERSE_PROXY, | |
timeoutMs, | |
socksProxy: (process.env.SOCKS_PROXY_HOST && process.env.SOCKS_PROXY_PORT) ? (`${process.env.SOCKS_PROXY_HOST}:${process.env.SOCKS_PROXY_PORT}`) : '-', | |
httpsProxy, | |
} as ModelConfig, | |
}) | |
} | |
export type { ChatContext, ChatMessage } | |
export { chatReplyProcess, chatConfig } | |