mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			f19193b5ac
			...
			d6f4f5efc6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					d6f4f5efc6 | ||
| 
						 | 
					b6f5d75656 | ||
| 
						 | 
					0d41a17ef6 | ||
| 
						 | 
					e2429d444b | ||
| 
						 | 
					c15dbf5296 | 
@@ -117,7 +117,7 @@ export class DoubaoApi implements LLMApi {
 | 
			
		||||
    options.onController?.(controller);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const chatPath = this.path(ByteDance.ChatPath);
 | 
			
		||||
      const chatPath = this.path(ByteDance.ChatPath(modelConfig.model));
 | 
			
		||||
      const chatPayload = {
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        body: JSON.stringify(requestPayload),
 | 
			
		||||
 
 | 
			
		||||
@@ -1868,7 +1868,7 @@ function _Chat() {
 | 
			
		||||
                            </div>
 | 
			
		||||
                            {!isUser && (
 | 
			
		||||
                              <div className={styles["chat-model-name"]}>
 | 
			
		||||
                                {message.model}
 | 
			
		||||
                                {message.modelDisplayName ?? message.model}
 | 
			
		||||
                              </div>
 | 
			
		||||
                            )}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,11 @@ export function Avatar(props: { model?: ModelType; avatar?: string }) {
 | 
			
		||||
      LlmIcon = BotIconGrok;
 | 
			
		||||
    } else if (modelName.startsWith("hunyuan")) {
 | 
			
		||||
      LlmIcon = BotIconHunyuan;
 | 
			
		||||
    } else if (modelName.startsWith("doubao") || modelName.startsWith("ep-")) {
 | 
			
		||||
    } else if (
 | 
			
		||||
      modelName.startsWith("doubao") ||
 | 
			
		||||
      modelName.startsWith("ep-") ||
 | 
			
		||||
      modelName.startsWith("bot-")
 | 
			
		||||
    ) {
 | 
			
		||||
      LlmIcon = BotIconDoubao;
 | 
			
		||||
    } else if (
 | 
			
		||||
      modelName.includes("glm") ||
 | 
			
		||||
 
 | 
			
		||||
@@ -216,7 +216,13 @@ export const Baidu = {
 | 
			
		||||
 | 
			
		||||
export const ByteDance = {
 | 
			
		||||
  ExampleEndpoint: "https://ark.cn-beijing.volces.com/api/",
 | 
			
		||||
  ChatPath: "api/v3/chat/completions",
 | 
			
		||||
  ChatPath: (modelName: string) => {
 | 
			
		||||
    if (modelName.startsWith("bot-")) {
 | 
			
		||||
      return "api/v3/bots/chat/completions";
 | 
			
		||||
    } else {
 | 
			
		||||
      return "api/v3/chat/completions";
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Alibaba = {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,7 @@ export type ChatMessage = RequestMessage & {
 | 
			
		||||
  isError?: boolean;
 | 
			
		||||
  id: string;
 | 
			
		||||
  model?: ModelType;
 | 
			
		||||
  modelDisplayName?: string;
 | 
			
		||||
  tools?: ChatMessageTool[];
 | 
			
		||||
  audio_url?: string;
 | 
			
		||||
  isMcpResponse?: boolean;
 | 
			
		||||
@@ -151,6 +152,24 @@ function getSummarizeModel(
 | 
			
		||||
  return [currentModel, providerName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getModelDisplayName(
 | 
			
		||||
  model: ModelType,
 | 
			
		||||
  providerName: ServiceProvider,
 | 
			
		||||
): string | undefined {
 | 
			
		||||
  const configStore = useAppConfig.getState();
 | 
			
		||||
  const accessStore = useAccessStore.getState();
 | 
			
		||||
  const allModel = collectModelsWithDefaultModel(
 | 
			
		||||
    configStore.models,
 | 
			
		||||
    [configStore.customModels, accessStore.customModels].join(","),
 | 
			
		||||
    accessStore.defaultModel,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const matchedModel = allModel.find(
 | 
			
		||||
    (m) => m.name === model && m.provider?.providerName === providerName,
 | 
			
		||||
  );
 | 
			
		||||
  return matchedModel ? matchedModel.displayName : undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function countMessages(msgs: ChatMessage[]) {
 | 
			
		||||
  return msgs.reduce(
 | 
			
		||||
    (pre, cur) => pre + estimateTokenLength(getMessageTextContent(cur)),
 | 
			
		||||
@@ -437,6 +456,10 @@ export const useChatStore = createPersistStore(
 | 
			
		||||
          role: "assistant",
 | 
			
		||||
          streaming: true,
 | 
			
		||||
          model: modelConfig.model,
 | 
			
		||||
          modelDisplayName: getModelDisplayName(
 | 
			
		||||
            modelConfig.model,
 | 
			
		||||
            modelConfig.providerName,
 | 
			
		||||
          ),
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // get recent messages
 | 
			
		||||
 
 | 
			
		||||
@@ -304,7 +304,9 @@ export function getTimeoutMSByModel(model: string) {
 | 
			
		||||
    model.startsWith("o1") ||
 | 
			
		||||
    model.startsWith("o3") ||
 | 
			
		||||
    model.includes("deepseek-r") ||
 | 
			
		||||
    model.includes("-thinking")
 | 
			
		||||
    model.includes("-thinking") ||
 | 
			
		||||
    model.startsWith("ep-") ||
 | 
			
		||||
    model.startsWith("bot-")
 | 
			
		||||
  )
 | 
			
		||||
    return REQUEST_TIMEOUT_MS_FOR_THINKING;
 | 
			
		||||
  return REQUEST_TIMEOUT_MS;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,8 @@ const config: Config = {
 | 
			
		||||
  moduleNameMapper: {
 | 
			
		||||
    "^@/(.*)$": "<rootDir>/$1",
 | 
			
		||||
  },
 | 
			
		||||
  extensionsToTreatAsEsm: [".ts", ".tsx"],
 | 
			
		||||
  injectGlobals: true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,22 @@
 | 
			
		||||
// Learn more: https://github.com/testing-library/jest-dom
 | 
			
		||||
import "@testing-library/jest-dom";
 | 
			
		||||
import { jest } from "@jest/globals";
 | 
			
		||||
 | 
			
		||||
global.fetch = jest.fn(() =>
 | 
			
		||||
  Promise.resolve({
 | 
			
		||||
    ok: true,
 | 
			
		||||
    status: 200,
 | 
			
		||||
    json: () => Promise.resolve({}),
 | 
			
		||||
    json: () => Promise.resolve([]),
 | 
			
		||||
    headers: new Headers(),
 | 
			
		||||
    redirected: false,
 | 
			
		||||
    statusText: "OK",
 | 
			
		||||
    type: "basic",
 | 
			
		||||
    url: "",
 | 
			
		||||
    clone: function () {
 | 
			
		||||
      return this;
 | 
			
		||||
    },
 | 
			
		||||
    body: null,
 | 
			
		||||
    bodyUsed: false,
 | 
			
		||||
    arrayBuffer: () => Promise.resolve(new ArrayBuffer(0)),
 | 
			
		||||
    blob: () => Promise.resolve(new Blob()),
 | 
			
		||||
    formData: () => Promise.resolve(new FormData()),
 | 
			
		||||
    text: () => Promise.resolve(""),
 | 
			
		||||
  }),
 | 
			
		||||
  } as Response),
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,8 @@
 | 
			
		||||
    "prompts": "node ./scripts/fetch-prompts.mjs",
 | 
			
		||||
    "prepare": "husky install",
 | 
			
		||||
    "proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev",
 | 
			
		||||
    "test": "jest --watch",
 | 
			
		||||
    "test:ci": "jest --ci"
 | 
			
		||||
    "test": "node --no-warnings --experimental-vm-modules $(yarn bin jest) --watch",
 | 
			
		||||
    "test:ci": "node --no-warnings --experimental-vm-modules $(yarn bin jest) --ci"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@fortaine/fetch-event-source": "^3.0.6",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
import { jest } from "@jest/globals";
 | 
			
		||||
import { isVisionModel } from "../app/utils";
 | 
			
		||||
 | 
			
		||||
describe("isVisionModel", () => {
 | 
			
		||||
@@ -50,7 +51,7 @@ describe("isVisionModel", () => {
 | 
			
		||||
 | 
			
		||||
  test("should identify models from VISION_MODELS env var", () => {
 | 
			
		||||
    process.env.VISION_MODELS = "custom-vision-model,another-vision-model";
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    expect(isVisionModel("custom-vision-model")).toBe(true);
 | 
			
		||||
    expect(isVisionModel("another-vision-model")).toBe(true);
 | 
			
		||||
    expect(isVisionModel("unrelated-model")).toBe(false);
 | 
			
		||||
@@ -64,4 +65,4 @@ describe("isVisionModel", () => {
 | 
			
		||||
    expect(isVisionModel("unrelated-model")).toBe(false);
 | 
			
		||||
    expect(isVisionModel("gpt-4-vision")).toBe(true);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user