Quellcode durchsuchen

Merge remote-tracking branch 'upstream/main'

fengzai6 vor 1 Jahr
Ursprung
Commit
052524dabd
5 geänderte Dateien mit 78 neuen und 22 gelöschten Zeilen
  1. 10 0
      app/client/platforms/openai.ts
  2. 42 0
      app/components/chat.tsx
  3. 3 0
      app/config/server.ts
  4. 17 17
      app/locales/tw.ts
  5. 6 5
      app/utils.ts

+ 10 - 0
app/client/platforms/openai.ts

@@ -110,6 +110,16 @@ export class ChatGPTApi implements LLMApi {
       // Please do not ask me why not send max_tokens, no reason, this param is just shit, I dont want to explain anymore.
     };
 
+    // add max_tokens to vision model
+    if (visionModel) {
+      Object.defineProperty(requestPayload, "max_tokens", {
+        enumerable: true,
+        configurable: true,
+        writable: true,
+        value: modelConfig.max_tokens,
+      });
+    }
+
     console.log("[Request] openai payload: ", requestPayload);
 
     const shouldStream = !!options.config.stream;

+ 42 - 0
app/components/chat.tsx

@@ -1104,6 +1104,47 @@ function _Chat() {
     };
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, []);
+  
+  const handlePaste = useCallback(
+    async (event: React.ClipboardEvent<HTMLTextAreaElement>) => {
+      const currentModel = chatStore.currentSession().mask.modelConfig.model;
+      if(!isVisionModel(currentModel)){return;}
+      const items = (event.clipboardData || window.clipboardData).items;
+      for (const item of items) {
+        if (item.kind === "file" && item.type.startsWith("image/")) {
+          event.preventDefault();
+          const file = item.getAsFile();
+          if (file) {
+            const images: string[] = [];
+            images.push(...attachImages);
+            images.push(
+              ...(await new Promise<string[]>((res, rej) => {
+                setUploading(true);
+                const imagesData: string[] = [];
+                compressImage(file, 256 * 1024)
+                  .then((dataUrl) => {
+                    imagesData.push(dataUrl);
+                    setUploading(false);
+                    res(imagesData);
+                  })
+                  .catch((e) => {
+                    setUploading(false);
+                    rej(e);
+                  });
+              })),
+            );
+            const imagesLength = images.length;
+
+            if (imagesLength > 3) {
+              images.splice(3, imagesLength - 3);
+            }
+            setAttachImages(images);
+          }
+        }
+      }
+    },
+    [attachImages, chatStore],
+  );
 
   async function uploadImage() {
     const images: string[] = [];
@@ -1453,6 +1494,7 @@ function _Chat() {
             onKeyDown={onInputKeyDown}
             onFocus={scrollToBottom}
             onClick={scrollToBottom}
+            onPaste={handlePaste}
             rows={inputRows}
             autoFocus={autoFocus}
             style={{

+ 3 - 0
app/config/server.ts

@@ -30,6 +30,9 @@ declare global {
       // google only
       GOOGLE_API_KEY?: string;
       GOOGLE_URL?: string;
+
+      // google tag manager
+      GTM_ID?: string;
     }
   }
 }

+ 17 - 17
app/locales/tw.ts

@@ -7,8 +7,8 @@ const tw = {
   WIP: "該功能仍在開發中……",
   Error: {
     Unauthorized: isApp
-      ? "檢測到無效 API Key,請前往[設定](/#/settings)頁檢查 API Key 是否配置正確。"
-      : "訪問密碼不正確或為空,請前往[登](/#/auth)頁輸入正確的訪問密碼,或者在[設定](/#/settings)頁填入你自己的 OpenAI API Key。",
+      ? "檢測到無效 API Key,請前往[設定](/#/settings)頁檢查 API Key 是否設定正確。"
+      : "訪問密碼不正確或為空,請前往[登](/#/auth)頁輸入正確的訪問密碼,或者在[設定](/#/settings)頁填入你自己的 OpenAI API Key。",
   },
 
   Auth: {
@@ -17,7 +17,7 @@ const tw = {
     SubTips: "或者輸入你的 OpenAI 或 Google API 密鑰",
     Input: "在此處填寫訪問碼",
     Confirm: "確認",
-    Later: "稍再說",
+    Later: "稍再說",
   },
   ChatItem: {
     ChatItemCount: (count: number) => `${count} 則對話`,
@@ -53,8 +53,8 @@ const tw = {
       del: "刪除聊天",
     },
     InputActions: {
-      Stop: "停止應",
-      ToBottom: "滾到最新",
+      Stop: "停止應",
+      ToBottom: "移至最新",
       Theme: {
         auto: "自動主題",
         light: "亮色模式",
@@ -107,7 +107,7 @@ const tw = {
     },
   },
   Select: {
-    Search: "搜索消息",
+    Search: "查詢消息",
     All: "選取全部",
     Latest: "最近幾條",
     Clear: "清除選中",
@@ -133,15 +133,15 @@ const tw = {
     Danger: {
       Reset: {
         Title: "重置所有設定",
-        SubTitle: "重置所有設定項回默認值",
+        SubTitle: "重置所有設定項回預設值",
         Action: "立即重置",
         Confirm: "確認重置所有設定?",
       },
       Clear: {
-        Title: "清除所有數據",
-        SubTitle: "清除所有聊天、設定數據",
+        Title: "清除所有資料",
+        SubTitle: "清除所有聊天、設定資料",
         Action: "立即清除",
-        Confirm: "確認清除所有聊天、設定數據?",
+        Confirm: "確認清除所有聊天、設定資料?",
       },
     },
     Lang: {
@@ -182,14 +182,14 @@ const tw = {
       SubTitle: "根據對話內容生成合適的標題",
     },
     Sync: {
-      CloudState: "雲端數據",
+      CloudState: "雲端資料",
       NotSyncYet: "還沒有進行過同步",
       Success: "同步成功",
       Fail: "同步失敗",
 
       Config: {
         Modal: {
-          Title: "配置雲端同步",
+          Title: "設定雲端同步",
           Check: "檢查可用性",
         },
         SyncType: {
@@ -218,7 +218,7 @@ const tw = {
         },
       },
 
-      LocalState: "本地數據",
+      LocalState: "本地資料",
       Overview: (overview: any) => {
         return `${overview.chat} 次對話,${overview.message} 條消息,${overview.prompt} 條提示詞,${overview.mask} 個面具`;
       },
@@ -385,7 +385,7 @@ const tw = {
     Edit: "前置上下文和歷史記憶",
     Add: "新增一條",
     Clear: "上下文已清除",
-    Revert: "恢上下文",
+    Revert: "恢上下文",
   },
   Plugin: { Name: "外掛" },
   FineTuned: { Sysmessage: "你是一個助手" },
@@ -440,8 +440,8 @@ const tw = {
     More: "搜尋更多",
   },
   URLCommand: {
-    Code: "檢測到鏈接中已經包含訪問碼,是否自動填入?",
-    Settings: "檢測到鏈接中包含了預制設置,是否自動填入?",
+    Code: "檢測到連結中已經包含訪問碼,是否自動填入?",
+    Settings: "檢測到連結中包含了預設設定,是否自動填入?",
   },
   UI: {
     Confirm: "確認",
@@ -452,7 +452,7 @@ const tw = {
     Export: "導出",
     Import: "導入",
     Sync: "同步",
-    Config: "配置",
+    Config: "設定",
   },
   Exporter: {
     Description: {

+ 6 - 5
app/utils.ts

@@ -9,8 +9,9 @@ export function trimTopic(topic: string) {
   // This will remove the specified punctuation from the end of the string
   // and also trim quotes from both the start and end if they exist.
   return topic
-    .replace(/^["“”]+|["“”]+$/g, "")
-    .replace(/[,。!?”“"、,.!?]*$/, "");
+    // fix for gemini
+    .replace(/^["“”*]+|["“”*]+$/g, "")
+    .replace(/[,。!?”“"、,.!?*]*$/, "");
 }
 
 export async function copyToClipboard(text: string) {
@@ -292,8 +293,8 @@ export function getMessageImages(message: RequestMessage): string[] {
 
 export function isVisionModel(model: string) {
   return (
-    model.startsWith("gpt-4-vision") ||
-    model.startsWith("gemini-pro-vision") ||
-    !DEFAULT_MODELS.find((m) => m.name == model)
+    // model.startsWith("gpt-4-vision") ||
+    // model.startsWith("gemini-pro-vision") ||
+    model.includes("vision")
   );
 }