Преглед на файлове

feat: parse response message

butterfly преди 1 година
родител
ревизия
768decde93
променени са 3 файла, в които са добавени 86 реда и са изтрити 53 реда
  1. 74 50
      app/client/platforms/anthropic.ts
  2. 11 2
      app/constant.ts
  3. 1 1
      app/store/chat.ts

+ 74 - 50
app/client/platforms/anthropic.ts

@@ -3,7 +3,7 @@ import { ChatOptions, LLMApi, MultimodalContent } from "../api";
 import { useAccessStore, useAppConfig, useChatStore } from "@/app/store";
 import { getClientConfig } from "@/app/config/client";
 import { DEFAULT_API_HOST } from "@/app/constant";
-import { MessageRole, RequestMessage } from "@/app/typing";
+import { RequestMessage } from "@/app/typing";
 import {
   EventStreamContentType,
   fetchEventSource,
@@ -237,45 +237,53 @@ export class ClaudeApi implements LLMApi {
 
     const shouldStream = !!options.config.stream;
 
-    const prompt = options.messages.map((v) => {
-      const { role, content } = v;
-      const insideRole = ClaudeMapper[role] ?? "user";
-
-      if (!visionModel || typeof content === "string") {
+    const prompt = options.messages
+      .filter((v) => {
+        if (!v.content) return false;
+        if (typeof v.content === "string" && !v.content.trim()) return false;
+        return true;
+      })
+      .map((v) => {
+        const { role, content } = v;
+        const insideRole = ClaudeMapper[role] ?? "user";
+
+        if (!visionModel || typeof content === "string") {
+          return {
+            role: insideRole,
+            content: getMessageTextContent(v),
+          };
+        }
         return {
           role: insideRole,
-          content: getMessageTextContent(v),
+          content: content
+            .filter((v) => v.image_url || v.text)
+            .map(({ type, text, image_url }) => {
+              if (type === "text") {
+                return {
+                  type,
+                  text: text!,
+                };
+              }
+              const { url = "" } = image_url || {};
+              const colonIndex = url.indexOf(":");
+              const semicolonIndex = url.indexOf(";");
+              const comma = url.indexOf(",");
+
+              const mimeType = url.slice(colonIndex + 1, semicolonIndex);
+              const encodeType = url.slice(semicolonIndex + 1, comma);
+              const data = url.slice(comma + 1);
+
+              return {
+                type: "image" as const,
+                source: {
+                  type: encodeType,
+                  media_type: mimeType,
+                  data,
+                },
+              };
+            }),
         };
-      }
-      return {
-        role: insideRole,
-        content: content.map(({ type, text, image_url }) => {
-          if (type === "text") {
-            return {
-              type,
-              text: text!,
-            };
-          }
-          const { url = "" } = image_url || {};
-          const colonIndex = url.indexOf(":");
-          const semicolonIndex = url.indexOf(";");
-          const comma = url.indexOf(",");
-
-          const mimeType = url.slice(colonIndex + 1, semicolonIndex);
-          const encodeType = url.slice(semicolonIndex + 1, comma);
-          const data = url.slice(comma + 1);
-
-          return {
-            type: "image" as const,
-            source: {
-              type: encodeType,
-              media_type: mimeType,
-              data,
-            },
-          };
-        }),
-      };
-    });
+      });
 
     const modelConfig = {
       ...useAppConfig.getState().modelConfig,
@@ -372,19 +380,30 @@ export class ClaudeApi implements LLMApi {
             }
           },
           onmessage(msg) {
-            if (msg.data === "[DONE]" || context.finished) {
-              return finish();
-            }
-            const chunk = msg.data;
+            let chunkJson:
+              | undefined
+              | {
+                  type: "content_block_delta" | "content_block_stop";
+                  delta?: {
+                    type: "text_delta";
+                    text: string;
+                  };
+                  index: number;
+                };
             try {
-              const chunkJson = JSON.parse(chunk) as ChatStreamResponse;
-              const delta = chunkJson.completion;
-              if (delta) {
-                context.text += delta;
-                options.onUpdate?.(context.text, delta);
-              }
+              chunkJson = JSON.parse(msg.data);
             } catch (e) {
-              console.error("[Request] parse error", chunk, msg);
+              console.error("[Response] parse error", msg.data);
+            }
+
+            if (!chunkJson || chunkJson.type === "content_block_stop") {
+              return finish();
+            }
+
+            const { delta } = chunkJson;
+            if (delta?.text) {
+              context.text += delta.text;
+              options.onUpdate?.(context.text, delta.text);
             }
           },
           onclose() {
@@ -430,12 +449,17 @@ export class ClaudeApi implements LLMApi {
 
     return [
       {
-        name: "claude-instant-1",
+        name: "claude-instant-1.2",
+        available: true,
+        provider,
+      },
+      {
+        name: "claude-2.0",
         available: true,
         provider,
       },
       {
-        name: "claude-2",
+        name: "claude-2.1",
         available: true,
         provider,
       },

+ 11 - 2
app/constant.ts

@@ -301,7 +301,7 @@ export const DEFAULT_MODELS = [
     },
   },
   {
-    name: "claude-instant-1",
+    name: "claude-instant-1.2",
     available: true,
     provider: {
       id: "anthropic",
@@ -310,7 +310,16 @@ export const DEFAULT_MODELS = [
     },
   },
   {
-    name: "claude-2",
+    name: "claude-2.0",
+    available: true,
+    provider: {
+      id: "anthropic",
+      providerName: "Anthropic",
+      providerType: "anthropic",
+    },
+  },
+  {
+    name: "claude-2.1",
     available: true,
     provider: {
       id: "anthropic",

+ 1 - 1
app/store/chat.ts

@@ -287,7 +287,7 @@ export const useChatStore = createPersistStore(
           session.lastUpdate = Date.now();
         });
         get().updateStat(message);
-        // get().summarizeSession();
+        get().summarizeSession();
       },
 
       async onUserInput(content: string, attachImages?: string[]) {