From 9c371f79938c8dc4b3dfbe3d4d0dbcb0b3af3d4b Mon Sep 17 00:00:00 2001 From: josc146 Date: Sun, 4 Aug 2024 23:03:20 +0800 Subject: [PATCH] improve chatglm support (#696, #464) --- build.mjs | 8 -- src/config/index.mjs | 7 +- src/services/apis/chatglm-api.mjs | 113 +++-------------------------- src/services/apis/moonshot-api.mjs | 2 +- src/services/apis/openai-api.mjs | 4 +- 5 files changed, 18 insertions(+), 116 deletions(-) diff --git a/build.mjs b/build.mjs index e2c678c..5dd87a0 100644 --- a/build.mjs +++ b/build.mjs @@ -250,14 +250,6 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, callback) search: 'await generateAnswersWithChatGLMApi', replace: '//', }, - { - search: 'chatglmTurbo', - replace: '//', - }, - { - search: "'chatglmTurbo", - replace: '//', - }, ], }, } diff --git a/src/config/index.mjs b/src/config/index.mjs index 1b5b86c..4f7f260 100644 --- a/src/config/index.mjs +++ b/src/config/index.mjs @@ -63,7 +63,7 @@ export const claudeApiModelKeys = [ 'claude3SonnetApi', 'claude3OpusApi', ] -export const chatglmApiModelKeys = ['chatglmTurbo'] +export const chatglmApiModelKeys = ['chatglmTurbo', 'chatglm4', 'chatglmEmohaa', 'chatglmCharGLM3'] export const githubThirdPartyApiModelKeys = ['waylaidwandererApi'] export const poeWebModelKeys = [ 'poeAiWebSage', //poe.com/Assistant @@ -145,7 +145,10 @@ export const Models = { bardWebFree: { value: '', desc: 'Gemini (Web)' }, - chatglmTurbo: { value: 'chatglm_turbo', desc: 'ChatGLM (ChatGLM-Turbo)' }, + chatglmTurbo: { value: 'GLM-4-Air', desc: 'ChatGLM (GLM-4-Air)' }, + chatglm4: { value: 'GLM-4-0520', desc: 'ChatGLM (GLM-4-0520)' }, + chatglmEmohaa: { value: 'Emohaa', desc: 'ChatGLM (Emohaa)' }, + chatglmCharGLM3: { value: 'CharGLM-3', desc: 'ChatGLM (CharGLM-3)' }, chatgptFree35Mobile: { value: 'text-davinci-002-render-sha-mobile', desc: 'ChatGPT (Mobile)' }, chatgptPlus4Mobile: { value: 'gpt-4-mobile', desc: 'ChatGPT (Mobile, GPT-4)' }, diff --git a/src/services/apis/chatglm-api.mjs b/src/services/apis/chatglm-api.mjs index 28e0305..e3540f4 100644 --- a/src/services/apis/chatglm-api.mjs +++ b/src/services/apis/chatglm-api.mjs @@ -1,39 +1,6 @@ -import { Models, getUserConfig } from '../../config/index.mjs' -import { pushRecord, setAbortController } from './shared.mjs' -import { isEmpty } from 'lodash-es' +import { getUserConfig } from '../../config/index.mjs' import { getToken } from '../../utils/jwt-token-generator.mjs' -import { createParser } from '../../utils/eventsource-parser.mjs' - -async function fetchSSE(resource, options) { - const { onMessage, onStart, onEnd, onError, ...fetchOptions } = options - const resp = await fetch(resource, fetchOptions).catch(async (err) => { - await onError(err) - }) - if (!resp) return - if (!resp.ok) { - await onError(resp) - return - } - - const parser = createParser((event) => { - if (event.type === 'event') { - onMessage(event) - } - }) - - let hasStarted = false - const reader = resp.body.getReader() - let result - while (!(result = await reader.read()).done) { - const chunk = result.value - if (!hasStarted) { - hasStarted = true - await onStart(new TextDecoder().decode(chunk)) - } - parser.feed(chunk) - } - await onEnd() -} +import { generateAnswersWithChatgptApiCompat } from './openai-api.mjs' /** * @param {Runtime.Port} port @@ -42,74 +9,14 @@ async function fetchSSE(resource, options) { * @param {string} modelName */ export async function generateAnswersWithChatGLMApi(port, question, session, modelName) { - const { controller, messageListener, disconnectListener } = setAbortController(port) + const baseUrl = 'https://open.bigmodel.cn/api/paas/v4' const config = await getUserConfig() - - const prompt = [] - for (const record of session.conversationRecords.slice(-config.maxConversationContextLength)) { - prompt.push({ role: 'user', content: record.question }) - prompt.push({ role: 'assistant', content: record.answer }) - } - prompt.push({ role: 'user', content: question }) - - let answer = '' - await fetchSSE( - `https://open.bigmodel.cn/api/paas/v3/model-api/${Models[modelName].value}/sse-invoke`, - { - method: 'POST', - signal: controller.signal, - headers: { - 'Content-Type': 'application/json; charset=UTF-8', - Accept: 'text/event-stream', - Authorization: getToken(config.chatglmApiKey), - }, - body: JSON.stringify({ - prompt: prompt, - // temperature: config.temperature, - // top_t: 0.7, - // request_id: string - // incremental: true, - // return_type: "json_string", - // ref: {"enable": "true", "search_query": "history"}, - }), - onMessage(event) { - console.debug('sse event', event) - - // Handle different types of events - switch (event.event) { - case 'add': - // In the case of an "add" event, append the completion to the answer - if (event.data) { - answer += event.data - port.postMessage({ answer: answer, done: false, session: null }) - } - break - case 'error': - case 'interrupted': - case 'finish': - pushRecord(session, question, answer) - console.debug('conversation history', { content: session.conversationRecords }) - port.postMessage({ answer: null, done: true, session: session }) - break - default: - break - } - }, - async onStart() {}, - async onEnd() { - port.postMessage({ done: true }) - port.onMessage.removeListener(messageListener) - port.onDisconnect.removeListener(disconnectListener) - }, - async onError(resp) { - port.onMessage.removeListener(messageListener) - port.onDisconnect.removeListener(disconnectListener) - if (resp instanceof Error) throw resp - const error = await resp.json().catch(() => ({})) - throw new Error( - !isEmpty(error) ? JSON.stringify(error) : `${resp.status} ${resp.statusText}`, - ) - }, - }, + return generateAnswersWithChatgptApiCompat( + baseUrl, + port, + question, + session, + getToken(config.chatglmApiKey), + modelName, ) } diff --git a/src/services/apis/moonshot-api.mjs b/src/services/apis/moonshot-api.mjs index 5dbc4bb..07fe4f7 100644 --- a/src/services/apis/moonshot-api.mjs +++ b/src/services/apis/moonshot-api.mjs @@ -14,6 +14,6 @@ export async function generateAnswersWithMoonshotCompletionApi( apiKey, modelName, ) { - const baseUrl = 'https://api.moonshot.cn' + const baseUrl = 'https://api.moonshot.cn/v1' return generateAnswersWithChatgptApiCompat(baseUrl, port, question, session, apiKey, modelName) } diff --git a/src/services/apis/openai-api.mjs b/src/services/apis/openai-api.mjs index 9b4bb4b..43d6b82 100644 --- a/src/services/apis/openai-api.mjs +++ b/src/services/apis/openai-api.mjs @@ -109,7 +109,7 @@ export async function generateAnswersWithGptCompletionApi( export async function generateAnswersWithChatgptApi(port, question, session, apiKey, modelName) { const config = await getUserConfig() return generateAnswersWithChatgptApiCompat( - config.customOpenAiApiUrl, + config.customOpenAiApiUrl + '/v1', port, question, session, @@ -144,7 +144,7 @@ export async function generateAnswersWithChatgptApiCompat( console.debug('conversation history', { content: session.conversationRecords }) port.postMessage({ answer: null, done: true, session: session }) } - await fetchSSE(`${baseUrl}/v1/chat/completions`, { + await fetchSSE(`${baseUrl}/chat/completions`, { method: 'POST', signal: controller.signal, headers: {