From d65ddead11ad9e14a6b7eb522c5e2fceb6e5df53 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Mon, 1 Jul 2024 09:41:01 +0000 Subject: [PATCH 1/7] fix: anthropic client using common getHeaders --- app/client/api.ts | 7 +++++-- app/client/platforms/anthropic.ts | 6 ++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/client/api.ts b/app/client/api.ts index 7bee546b4f6..502c7469848 100644 --- a/app/client/api.ts +++ b/app/client/api.ts @@ -162,14 +162,17 @@ export function getHeaders() { const modelConfig = useChatStore.getState().currentSession().mask.modelConfig; const isGoogle = modelConfig.model.startsWith("gemini"); const isAzure = accessStore.provider === ServiceProvider.Azure; - const authHeader = isAzure ? "api-key" : "Authorization"; + const isAnthropic = accessStore.provider === ServiceProvider.Anthropic; + const authHeader = isAzure ? "api-key" : isAnthropic ? 'x-api-key' : "Authorization"; const apiKey = isGoogle ? accessStore.googleApiKey : isAzure ? accessStore.azureApiKey + : isAnthropic + ? accessStore.anthropicApiKey : accessStore.openaiApiKey; const clientConfig = getClientConfig(); - const makeBearer = (s: string) => `${isAzure ? "" : "Bearer "}${s.trim()}`; + const makeBearer = (s: string) => `${isAzure || isAnthropic ? "" : "Bearer "}${s.trim()}`; const validString = (x: string) => x && x.length > 0; // when using google api in app, not set auth header diff --git a/app/client/platforms/anthropic.ts b/app/client/platforms/anthropic.ts index e90c8f057b2..b8eca694633 100644 --- a/app/client/platforms/anthropic.ts +++ b/app/client/platforms/anthropic.ts @@ -1,5 +1,5 @@ import { ACCESS_CODE_PREFIX, Anthropic, ApiPath } from "@/app/constant"; -import { ChatOptions, LLMApi, MultimodalContent } from "../api"; +import { ChatOptions, getHeaders, LLMApi, MultimodalContent, } from "../api"; import { useAccessStore, useAppConfig, useChatStore } from "@/app/store"; import { getClientConfig } from "@/app/config/client"; import { DEFAULT_API_HOST } from "@/app/constant"; @@ -190,9 +190,7 @@ export class ClaudeApi implements LLMApi { body: JSON.stringify(requestBody), signal: controller.signal, headers: { - "Content-Type": "application/json", - Accept: "application/json", - "x-api-key": accessStore.anthropicApiKey, + ...getHeaders(), // get common headers "anthropic-version": accessStore.anthropicApiVersion, Authorization: getAuthKey(accessStore.anthropicApiKey), }, From 37e2517dac850aef0bec0430f02356402b8610d8 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Mon, 1 Jul 2024 10:24:19 +0000 Subject: [PATCH 2/7] fix: 1. anthropic client using common getHeaders; 2. always using `Authorization` header send access code --- app/client/api.ts | 3 ++- app/client/platforms/anthropic.ts | 27 ++------------------------- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/app/client/api.ts b/app/client/api.ts index 502c7469848..edee993424a 100644 --- a/app/client/api.ts +++ b/app/client/api.ts @@ -184,7 +184,8 @@ export function getHeaders() { accessStore.enabledAccessControl() && validString(accessStore.accessCode) ) { - headers[authHeader] = makeBearer( + // access_code must send with header named `Authorization`, will using in auth middleware. + headers['Authorization'] = makeBearer( ACCESS_CODE_PREFIX + accessStore.accessCode, ); } diff --git a/app/client/platforms/anthropic.ts b/app/client/platforms/anthropic.ts index b8eca694633..18c3decac8e 100644 --- a/app/client/platforms/anthropic.ts +++ b/app/client/platforms/anthropic.ts @@ -192,7 +192,8 @@ export class ClaudeApi implements LLMApi { headers: { ...getHeaders(), // get common headers "anthropic-version": accessStore.anthropicApiVersion, - Authorization: getAuthKey(accessStore.anthropicApiKey), + // do not send `anthropicApiKey` in browser!!! + // Authorization: getAuthKey(accessStore.anthropicApiKey), }, }; @@ -387,27 +388,3 @@ function trimEnd(s: string, end = " ") { return s; } - -function bearer(value: string) { - return `Bearer ${value.trim()}`; -} - -function getAuthKey(apiKey = "") { - const accessStore = useAccessStore.getState(); - const isApp = !!getClientConfig()?.isApp; - let authKey = ""; - - if (apiKey) { - // use user's api key first - authKey = bearer(apiKey); - } else if ( - accessStore.enabledAccessControl() && - !isApp && - !!accessStore.accessCode - ) { - // or use access code - authKey = bearer(ACCESS_CODE_PREFIX + accessStore.accessCode); - } - - return authKey; -} From 69974d5651e30c879579e3fe1bd63982548b5dbe Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Mon, 1 Jul 2024 13:24:01 +0000 Subject: [PATCH 3/7] gemini using real sse format response #3677 #3688 --- app/api/google/[...path]/route.ts | 4 +- app/client/platforms/google.ts | 147 +++++++++++++++++------------- 2 files changed, 87 insertions(+), 64 deletions(-) diff --git a/app/api/google/[...path]/route.ts b/app/api/google/[...path]/route.ts index ebd19289129..81e50538a56 100644 --- a/app/api/google/[...path]/route.ts +++ b/app/api/google/[...path]/route.ts @@ -63,7 +63,9 @@ async function handle( ); } - const fetchUrl = `${baseUrl}/${path}?key=${key}`; + const fetchUrl = `${baseUrl}/${path}?key=${key}${ + req?.nextUrl?.searchParams?.get("alt") == "sse" ? "&alt=sse" : "" + }`; const fetchOptions: RequestInit = { headers: { "Content-Type": "application/json", diff --git a/app/client/platforms/google.ts b/app/client/platforms/google.ts index a786f5275f4..7ecba1de404 100644 --- a/app/client/platforms/google.ts +++ b/app/client/platforms/google.ts @@ -3,6 +3,12 @@ import { ChatOptions, getHeaders, LLMApi, LLMModel, LLMUsage } from "../api"; import { useAccessStore, useAppConfig, useChatStore } from "@/app/store"; import { getClientConfig } from "@/app/config/client"; import { DEFAULT_API_HOST } from "@/app/constant"; +import Locale from "../../locales"; +import { + EventStreamContentType, + fetchEventSource, +} from "@fortaine/fetch-event-source"; +import { prettyObject } from "@/app/utils/format"; import { getMessageTextContent, getMessageImages, @@ -20,7 +26,7 @@ export class GeminiProApi implements LLMApi { ); } async chat(options: ChatOptions): Promise { - // const apiClient = this; + const apiClient = this; let multimodal = false; const messages = options.messages.map((v) => { let parts: any[] = [{ text: getMessageTextContent(v) }]; @@ -120,7 +126,9 @@ export class GeminiProApi implements LLMApi { if (!baseUrl) { baseUrl = isApp - ? DEFAULT_API_HOST + "/api/proxy/google/" + Google.ChatPath(modelConfig.model) + ? DEFAULT_API_HOST + + "/api/proxy/google/" + + Google.ChatPath(modelConfig.model) : this.path(Google.ChatPath(modelConfig.model)); } @@ -139,16 +147,15 @@ export class GeminiProApi implements LLMApi { () => controller.abort(), REQUEST_TIMEOUT_MS, ); - + if (shouldStream) { let responseText = ""; let remainText = ""; let finished = false; - let existingTexts: string[] = []; const finish = () => { finished = true; - options.onFinish(existingTexts.join("")); + options.onFinish(responseText + remainText); }; // animate response to make it looks smooth @@ -173,72 +180,86 @@ export class GeminiProApi implements LLMApi { // start animaion animateResponseText(); - fetch( - baseUrl.replace("generateContent", "streamGenerateContent"), - chatPayload, - ) - .then((response) => { - const reader = response?.body?.getReader(); - const decoder = new TextDecoder(); - let partialData = ""; + controller.signal.onabort = finish; + + // https://github.com/google-gemini/cookbook/blob/main/quickstarts/rest/Streaming_REST.ipynb + const chatPath = + baseUrl.replace("generateContent", "streamGenerateContent") + + (baseUrl.indexOf("?") > -1 ? "&alt=sse" : "?alt=sse"); + console.log("chatPath", chatPath); + fetchEventSource(chatPath, { + ...chatPayload, + async onopen(res) { + clearTimeout(requestTimeoutId); + const contentType = res.headers.get("content-type"); + console.log( + "[Gemini] request response content type: ", + contentType, + ); - return reader?.read().then(function processText({ - done, - value, - }): Promise { - if (done) { - if (response.status !== 200) { - try { - let data = JSON.parse(ensureProperEnding(partialData)); - if (data && data[0].error) { - options.onError?.(new Error(data[0].error.message)); - } else { - options.onError?.(new Error("Request failed")); - } - } catch (_) { - options.onError?.(new Error("Request failed")); - } - } + if (contentType?.startsWith("text/plain")) { + responseText = await res.clone().text(); + return finish(); + } + + if ( + !res.ok || + !res.headers + .get("content-type") + ?.startsWith(EventStreamContentType) || + res.status !== 200 + ) { + const responseTexts = [responseText]; + let extraInfo = await res.clone().text(); + try { + const resJson = await res.clone().json(); + extraInfo = prettyObject(resJson); + } catch {} - console.log("Stream complete"); - // options.onFinish(responseText + remainText); - finished = true; - return Promise.resolve(); + if (res.status === 401) { + responseTexts.push(Locale.Error.Unauthorized); } - partialData += decoder.decode(value, { stream: true }); + if (extraInfo) { + responseTexts.push(extraInfo); + } - try { - let data = JSON.parse(ensureProperEnding(partialData)); + responseText = responseTexts.join("\n\n"); - const textArray = data.reduce( - (acc: string[], item: { candidates: any[] }) => { - const texts = item.candidates.map((candidate) => - candidate.content.parts - .map((part: { text: any }) => part.text) - .join(""), - ); - return acc.concat(texts); - }, - [], - ); + return finish(); + } + }, + onmessage(msg) { + if (msg.data === "[DONE]" || finished) { + return finish(); + } + const text = msg.data; + try { + const json = JSON.parse(text); + const delta = apiClient.extractMessage(json); - if (textArray.length > existingTexts.length) { - const deltaArray = textArray.slice(existingTexts.length); - existingTexts = textArray; - remainText += deltaArray.join(""); - } - } catch (error) { - // console.log("[Response Animation] error: ", error,partialData); - // skip error message when parsing json + if (delta) { + remainText += delta; } - return reader.read().then(processText); - }); - }) - .catch((error) => { - console.error("Error:", error); - }); + const blockReason = json?.promptFeedback?.blockReason; + if (blockReason) { + // being blocked + console.log(`[Google] [Safety Ratings] result:`, blockReason); + } + } catch (e) { + console.error("[Request] parse error", text, msg); + } + }, + onclose() { + finish(); + }, + onerror(e) { + options.onError?.(e); + throw e; + }, + openWhenHidden: true, + }); } else { const res = await fetch(baseUrl, chatPayload); clearTimeout(requestTimeoutId); @@ -252,7 +273,7 @@ export class GeminiProApi implements LLMApi { ), ); } - const message = this.extractMessage(resJson); + const message = apiClient.extractMessage(resJson); options.onFinish(message); } } catch (e) { From c4ad66f745a539602910f49156d90be5208986e0 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Mon, 1 Jul 2024 13:27:06 +0000 Subject: [PATCH 4/7] remove console.log --- app/client/platforms/google.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/client/platforms/google.ts b/app/client/platforms/google.ts index 7ecba1de404..4aac1dbff99 100644 --- a/app/client/platforms/google.ts +++ b/app/client/platforms/google.ts @@ -186,7 +186,6 @@ export class GeminiProApi implements LLMApi { const chatPath = baseUrl.replace("generateContent", "streamGenerateContent") + (baseUrl.indexOf("?") > -1 ? "&alt=sse" : "?alt=sse"); - console.log("chatPath", chatPath); fetchEventSource(chatPath, { ...chatPayload, async onopen(res) { From 88c74ae18d74b79caded849f9a022b6d5a8a101d Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Wed, 3 Jul 2024 14:09:49 +0800 Subject: [PATCH 5/7] feat: using fetch to get buildin masks --- app/masks/build.ts | 23 ++++++ app/masks/index.ts | 20 ++++- package.json | 16 ++-- yarn.lock | 191 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 app/masks/build.ts diff --git a/app/masks/build.ts b/app/masks/build.ts new file mode 100644 index 00000000000..36ced6adf92 --- /dev/null +++ b/app/masks/build.ts @@ -0,0 +1,23 @@ +import fs from "fs"; +import path from "path"; +import { CN_MASKS } from "./cn"; +import { TW_MASKS } from "./tw"; +import { EN_MASKS } from "./en"; + +const BUILTIN_MASKS: BuiltinMask[] = { + cn: CN_MASKS, + tw: TW_MASKS, + en: EN_MASKS, +}; + +const dirname = path.dirname(__filename); + +fs.writeFile( + dirname + "/../../public/masks.json", + JSON.stringify(BUILTIN_MASKS, null, 4), + function (error) { + if (error) { + console.error("[Build] failed to build masks", error); + } + }, +); diff --git a/app/masks/index.ts b/app/masks/index.ts index aa4917e3e3c..92f21c6aea7 100644 --- a/app/masks/index.ts +++ b/app/masks/index.ts @@ -22,6 +22,20 @@ export const BUILTIN_MASK_STORE = { }, }; -export const BUILTIN_MASKS: BuiltinMask[] = [...CN_MASKS, ...TW_MASKS, ...EN_MASKS].map( - (m) => BUILTIN_MASK_STORE.add(m), -); +export const BUILTIN_MASKS: BuiltinMask[] = []; + +if (typeof window != "undefined") { + // run in browser skip in next server + fetch("/masks.json") + .then((res) => res.json()) + .catch((error) => { + console.error("[Fetch] failed to fetch masks", error); + return { cn: [], tw: [], en: [] }; + }) + .then((masks) => { + const { cn = [], tw = [], en = [] } = masks; + return [...cn, ...tw, ...en].map((m) => { + BUILTIN_MASKS.push(BUILTIN_MASK_STORE.add(m)); + }); + }); +} diff --git a/package.json b/package.json index 4d06b0b14e4..ed5edb04330 100644 --- a/package.json +++ b/package.json @@ -3,14 +3,16 @@ "private": false, "license": "mit", "scripts": { - "dev": "next dev", - "build": "cross-env BUILD_MODE=standalone next build", + "mask": "npx tsx app/masks/build.ts", + "mask:watch": "npx watch 'yarn mask' app/masks", + "dev": "yarn run mask:watch & next dev", + "build": "yarn mask && cross-env BUILD_MODE=standalone next build", "start": "next start", "lint": "next lint", - "export": "cross-env BUILD_MODE=export BUILD_APP=1 next build", - "export:dev": "cross-env BUILD_MODE=export BUILD_APP=1 next dev", - "app:dev": "yarn tauri dev", - "app:build": "yarn tauri build", + "export": "yarn mask && cross-env BUILD_MODE=export BUILD_APP=1 next build", + "export:dev": "yarn mask:watch & cross-env BUILD_MODE=export BUILD_APP=1 next dev", + "app:dev": "yarn mask:watch & yarn tauri dev", + "app:build": "yarn mask && yarn tauri build", "prompts": "node ./scripts/fetch-prompts.mjs", "prepare": "husky install", "proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev" @@ -59,7 +61,9 @@ "husky": "^8.0.0", "lint-staged": "^13.2.2", "prettier": "^3.0.2", + "tsx": "^4.16.0", "typescript": "5.2.2", + "watch": "^1.0.2", "webpack": "^5.88.1" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index 72df8cafc54..c323a5c38db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1092,6 +1092,121 @@ resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783" integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -2981,6 +3096,35 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@~0.21.5: + version "0.21.5" + resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -3234,6 +3378,13 @@ events@^3.2.0: resolved "https://registry.npmmirror.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.npmmirror.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== + dependencies: + merge "^1.2.0" + execa@^7.0.0: version "7.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" @@ -3376,6 +3527,11 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3433,6 +3589,13 @@ get-tsconfig@^4.5.0: resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ== +get-tsconfig@^4.7.5: + version "4.7.5" + resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.7.5.tgz#5e012498579e9a6947511ed0cd403272c7acbbaf" + integrity sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw== + dependencies: + resolve-pkg-maps "^1.0.0" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -4387,6 +4550,11 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.npmmirror.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + mermaid@^10.6.1: version "10.6.1" resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.6.1.tgz#701f4160484137a417770ce757ce1887a98c00fc" @@ -5317,6 +5485,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve@^1.14.2, resolve@^1.22.1: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -5823,6 +5996,16 @@ tslib@^2.6.2: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tsx@^4.16.0: + version "4.16.0" + resolved "https://registry.npmmirror.com/tsx/-/tsx-4.16.0.tgz#913dd96f191b76f07a8744201d8c15d510aa1352" + integrity sha512-MPgN+CuY+4iKxGoJNPv+1pyo5YWZAQ5XfsyobUG+zoKG7IkvCPLZDEyoIb8yLS2FcWci1nlxAqmvPlFWD5AFiQ== + dependencies: + esbuild "~0.21.5" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -6043,6 +6226,14 @@ vfile@^5.0.0: unist-util-stringify-position "^3.0.0" vfile-message "^3.0.0" +watch@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c" + integrity sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA== + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + watchpack@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" From 1609abd16666cb31f0b3f0019450655496273158 Mon Sep 17 00:00:00 2001 From: lloydzhou Date: Wed, 3 Jul 2024 14:18:22 +0800 Subject: [PATCH 6/7] fix ts --- app/masks/build.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/masks/build.ts b/app/masks/build.ts index 36ced6adf92..10c09ad7556 100644 --- a/app/masks/build.ts +++ b/app/masks/build.ts @@ -4,7 +4,9 @@ import { CN_MASKS } from "./cn"; import { TW_MASKS } from "./tw"; import { EN_MASKS } from "./en"; -const BUILTIN_MASKS: BuiltinMask[] = { +import { type BuiltinMask } from "./typing"; + +const BUILTIN_MASKS: Record = { cn: CN_MASKS, tw: TW_MASKS, en: EN_MASKS, From 2803a91673483d35eae983650bc5a196e0a5c0fa Mon Sep 17 00:00:00 2001 From: ji-jinlong <61379293+ji-jinlong@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:18:24 +0800 Subject: [PATCH 7/7] =?UTF-8?q?readme=20=E6=B7=BB=E5=8A=A0=20DEFAULT=5FMOD?= =?UTF-8?q?EL=20=E5=8F=82=E6=95=B0=20(#4915)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * README_CN.md 添加 DEFAULT_MODEL 的说明 更改默认模型, 很久之前就有大佬支持了, 但更多人只会看readme, readme没有的就以为不支持(包括我). https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/pull/4545 * Update README.md Change default model, it has been supported by experts long ago, but more people only read the readme. If it's not in the readme, they assume it's not supported (including me). https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/pull/4545 * Update README.md ch to en * en2cn * 保持位置和readme.md一致 --- README.md | 4 ++++ README_CN.md | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e96e2f58875..c77d2023c97 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,10 @@ To control custom models, use `+` to add a custom model, use `-` to hide a model User `-all` to disable all default models, `+all` to enable all default models. +### `DEFAULT_MODEL` (optional) + +Change default model + ### `WHITE_WEBDEV_ENDPOINTS` (optional) You can use this option if you want to increase the number of webdav service addresses you are allowed to access, as required by the format: diff --git a/README_CN.md b/README_CN.md index 6811102b675..970ecdef2f9 100644 --- a/README_CN.md +++ b/README_CN.md @@ -106,23 +106,23 @@ Azure 密钥。 Azure Api 版本,你可以在这里找到:[Azure 文档](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)。 -### `GOOGLE_API_KEY` (optional) +### `GOOGLE_API_KEY` (可选) Google Gemini Pro 密钥. -### `GOOGLE_URL` (optional) +### `GOOGLE_URL` (可选) Google Gemini Pro Api Url. -### `ANTHROPIC_API_KEY` (optional) +### `ANTHROPIC_API_KEY` (可选) anthropic claude Api Key. -### `ANTHROPIC_API_VERSION` (optional) +### `ANTHROPIC_API_VERSION` (可选) anthropic claude Api version. -### `ANTHROPIC_URL` (optional) +### `ANTHROPIC_URL` (可选) anthropic claude Api Url. @@ -156,7 +156,12 @@ anthropic claude Api Url. 用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 +### `DEFAULT_MODEL` (可选) + +更改默认模型 + ### `DEFAULT_INPUT_TEMPLATE` (可选) + 自定义默认的 template,用于初始化『设置』中的『用户输入预处理』配置项 ## 开发