@lobehub/chat 1.45.15 → 1.45.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.45.17](https://github.com/lobehub/lobe-chat/compare/v1.45.16...v1.45.17)
6
+
7
+ <sup>Released on **2025-01-15**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor Minimax with LobeOpenAICompatibleFactory.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor Minimax with LobeOpenAICompatibleFactory, closes [#5325](https://github.com/lobehub/lobe-chat/issues/5325) ([da11b55](https://github.com/lobehub/lobe-chat/commit/da11b55))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 1.45.16](https://github.com/lobehub/lobe-chat/compare/v1.45.15...v1.45.16)
31
+
32
+ <sup>Released on **2025-01-14**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: Improve ai provider code.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Code refactoring
44
+
45
+ - **misc**: Improve ai provider code, closes [#5442](https://github.com/lobehub/lobe-chat/issues/5442) ([32013b4](https://github.com/lobehub/lobe-chat/commit/32013b4))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 1.45.15](https://github.com/lobehub/lobe-chat/compare/v1.45.14...v1.45.15)
6
56
 
7
57
  <sup>Released on **2025-01-14**</sup>
package/README.ja-JP.md CHANGED
@@ -158,11 +158,11 @@ LobeChat の継続的な開発において、AI 会話サービスを提供す
158
158
  - **[Baichuan](https://lobechat.com/discover/provider/baichuan)**: 百川智能は、人工知能大モデルの研究開発に特化した企業であり、そのモデルは国内の知識百科、長文処理、生成創作などの中国語タスクで卓越したパフォーマンスを示し、海外の主流モデルを超えています。百川智能は、業界をリードする多モーダル能力を持ち、複数の権威ある評価で優れたパフォーマンスを示しています。そのモデルには、Baichuan 4、Baichuan 3 Turbo、Baichuan 3 Turbo 128k などが含まれ、異なるアプリケーションシーンに最適化され、高コストパフォーマンスのソリューションを提供しています。
159
159
  - **[Minimax](https://lobechat.com/discover/provider/minimax)**: MiniMax は 2021 年に設立された汎用人工知能テクノロジー企業であり、ユーザーと共に知能を共創することに取り組んでいます。MiniMax は、さまざまなモードの汎用大モデルを独自に開発しており、トリリオンパラメータの MoE テキスト大モデル、音声大モデル、画像大モデルを含んでいます。また、海螺 AI などのアプリケーションも展開しています。
160
160
  - **[360 AI](https://lobechat.com/discover/provider/ai360)**: 360 AI は、360 社が提供する AI モデルとサービスプラットフォームであり、360GPT2 Pro、360GPT Pro、360GPT Turbo、360GPT Turbo Responsibility 8K など、さまざまな先進的な自然言語処理モデルを提供しています。これらのモデルは、大規模なパラメータと多モーダル能力を組み合わせており、テキスト生成、意味理解、対話システム、コード生成などの分野で広く使用されています。柔軟な価格戦略を通じて、360 AI は多様なユーザーのニーズに応え、開発者の統合をサポートし、スマートアプリケーションの革新と発展を促進します。
161
- - **[Taichu](https://lobechat.com/discover/provider/taichu)**: 中科院自動化研究所と武漢人工知能研究院が新世代の多モーダル大モデルを発表し、多輪問答、テキスト創作、画像生成、3D 理解、信号分析などの包括的な問答タスクをサポートし、より強力な認知、理解、創作能力を持ち、新しいインタラクティブな体験を提供します。
162
- - **[InternLM](https://lobechat.com/discover/provider/internlm)**: 大規模モデルの研究と開発ツールチェーンに特化したオープンソース組織です。すべての AI 開発者に対して、高効率で使いやすいオープンプラットフォームを提供し、最先端の大規模モデルとアルゴリズム技術を身近に感じられるようにします。
163
161
  - **[SiliconCloud](https://lobechat.com/discover/provider/siliconcloud)**: SiliconFlow は、AGI を加速させ、人類に利益をもたらすことを目指し、使いやすくコスト効率の高い GenAI スタックを通じて大規模 AI の効率を向上させることに取り組んでいます。
162
+ - **[InternLM](https://lobechat.com/discover/provider/internlm)**: 大規模モデルの研究と開発ツールチェーンに特化したオープンソース組織です。すべての AI 開発者に対して、高効率で使いやすいオープンプラットフォームを提供し、最先端の大規模モデルとアルゴリズム技術を身近に感じられるようにします。
164
163
  - **[Higress](https://lobechat.com/discover/provider/higress)**: Higress は、阿里内部で Tengine のリロードが長期接続のビジネスに悪影響を及ぼすことや、gRPC/Dubbo の負荷分散能力が不足している問題を解決するために生まれた、クラウドネイティブな API ゲートウェイです。
165
164
  - **[Gitee AI](https://lobechat.com/discover/provider/giteeai)**: Gitee AI の Serverless API は、AI 開発者に開梱即使用の大モデル推論 API サービスを提供する。
165
+ - **[Taichu](https://lobechat.com/discover/provider/taichu)**: 中科院自動化研究所と武漢人工知能研究院が新世代の多モーダル大モデルを発表し、多輪問答、テキスト創作、画像生成、3D 理解、信号分析などの包括的な問答タスクをサポートし、より強力な認知、理解、創作能力を持ち、新しいインタラクティブな体験を提供します。
166
166
 
167
167
  </details>
168
168
 
package/README.md CHANGED
@@ -177,11 +177,11 @@ We have implemented support for the following model service providers:
177
177
  - **[Baichuan](https://lobechat.com/discover/provider/baichuan)**: Baichuan Intelligence is a company focused on the research and development of large AI models, with its models excelling in domestic knowledge encyclopedias, long text processing, and generative creation tasks in Chinese, surpassing mainstream foreign models. Baichuan Intelligence also possesses industry-leading multimodal capabilities, performing excellently in multiple authoritative evaluations. Its models include Baichuan 4, Baichuan 3 Turbo, and Baichuan 3 Turbo 128k, each optimized for different application scenarios, providing cost-effective solutions.
178
178
  - **[Minimax](https://lobechat.com/discover/provider/minimax)**: MiniMax is a general artificial intelligence technology company established in 2021, dedicated to co-creating intelligence with users. MiniMax has independently developed general large models of different modalities, including trillion-parameter MoE text models, voice models, and image models, and has launched applications such as Conch AI.
179
179
  - **[360 AI](https://lobechat.com/discover/provider/ai360)**: 360 AI is an AI model and service platform launched by 360 Company, offering various advanced natural language processing models, including 360GPT2 Pro, 360GPT Pro, 360GPT Turbo, and 360GPT Turbo Responsibility 8K. These models combine large-scale parameters and multimodal capabilities, widely applied in text generation, semantic understanding, dialogue systems, and code generation. With flexible pricing strategies, 360 AI meets diverse user needs, supports developer integration, and promotes the innovation and development of intelligent applications.
180
- - **[Taichu](https://lobechat.com/discover/provider/taichu)**: The Institute of Automation, Chinese Academy of Sciences, and Wuhan Artificial Intelligence Research Institute have launched a new generation of multimodal large models, supporting comprehensive question-answering tasks such as multi-turn Q\&A, text creation, image generation, 3D understanding, and signal analysis, with stronger cognitive, understanding, and creative abilities, providing a new interactive experience.
181
- - **[InternLM](https://lobechat.com/discover/provider/internlm)**: An open-source organization dedicated to the research and development of large model toolchains. It provides an efficient and user-friendly open-source platform for all AI developers, making cutting-edge large models and algorithm technologies easily accessible.
182
180
  - **[SiliconCloud](https://lobechat.com/discover/provider/siliconcloud)**: SiliconFlow is dedicated to accelerating AGI for the benefit of humanity, enhancing large-scale AI efficiency through an easy-to-use and cost-effective GenAI stack.
181
+ - **[InternLM](https://lobechat.com/discover/provider/internlm)**: An open-source organization dedicated to the research and development of large model toolchains. It provides an efficient and user-friendly open-source platform for all AI developers, making cutting-edge large models and algorithm technologies easily accessible.
183
182
  - **[Higress](https://lobechat.com/discover/provider/higress)**: Higress is a cloud-native API gateway that was developed internally at Alibaba to address the issues of Tengine reload affecting long-lived connections and the insufficient load balancing capabilities for gRPC/Dubbo.
184
183
  - **[Gitee AI](https://lobechat.com/discover/provider/giteeai)**: Gitee AI's Serverless API provides AI developers with an out of the box large model inference API service.
184
+ - **[Taichu](https://lobechat.com/discover/provider/taichu)**: The Institute of Automation, Chinese Academy of Sciences, and Wuhan Artificial Intelligence Research Institute have launched a new generation of multimodal large models, supporting comprehensive question-answering tasks such as multi-turn Q\&A, text creation, image generation, 3D understanding, and signal analysis, with stronger cognitive, understanding, and creative abilities, providing a new interactive experience.
185
185
 
186
186
  </details>
187
187
 
package/README.zh-CN.md CHANGED
@@ -177,11 +177,11 @@ LobeChat 支持文件上传与知识库功能,你可以上传文件、图片
177
177
  - **[Baichuan](https://lobechat.com/discover/provider/baichuan)**: 百川智能是一家专注于人工智能大模型研发的公司,其模型在国内知识百科、长文本处理和生成创作等中文任务上表现卓越,超越了国外主流模型。百川智能还具备行业领先的多模态能力,在多项权威评测中表现优异。其模型包括 Baichuan 4、Baichuan 3 Turbo 和 Baichuan 3 Turbo 128k 等,分别针对不同应用场景进行优化,提供高性价比的解决方案。
178
178
  - **[Minimax](https://lobechat.com/discover/provider/minimax)**: MiniMax 是 2021 年成立的通用人工智能科技公司,致力于与用户共创智能。MiniMax 自主研发了不同模态的通用大模型,其中包括万亿参数的 MoE 文本大模型、语音大模型以及图像大模型。并推出了海螺 AI 等应用。
179
179
  - **[360 AI](https://lobechat.com/discover/provider/ai360)**: 360 AI 是 360 公司推出的 AI 模型和服务平台,提供多种先进的自然语言处理模型,包括 360GPT2 Pro、360GPT Pro、360GPT Turbo 和 360GPT Turbo Responsibility 8K。这些模型结合了大规模参数和多模态能力,广泛应用于文本生成、语义理解、对话系统与代码生成等领域。通过灵活的定价策略,360 AI 满足多样化用户需求,支持开发者集成,推动智能化应用的革新和发展。
180
- - **[Taichu](https://lobechat.com/discover/provider/taichu)**: 中科院自动化研究所和武汉人工智能研究院推出新一代多模态大模型,支持多轮问答、文本创作、图像生成、3D 理解、信号分析等全面问答任务,拥有更强的认知、理解、创作能力,带来全新互动体验。
181
- - **[InternLM](https://lobechat.com/discover/provider/internlm)**: 致力于大模型研究与开发工具链的开源组织。为所有 AI 开发者提供高效、易用的开源平台,让最前沿的大模型与算法技术触手可及
182
180
  - **[SiliconCloud](https://lobechat.com/discover/provider/siliconcloud)**: SiliconCloud,基于优秀开源基础模型的高性价比 GenAI 云服务
181
+ - **[InternLM](https://lobechat.com/discover/provider/internlm)**: 致力于大模型研究与开发工具链的开源组织。为所有 AI 开发者提供高效、易用的开源平台,让最前沿的大模型与算法技术触手可及
183
182
  - **[Higress](https://lobechat.com/discover/provider/higress)**: Higress 是一款云原生 API 网关,在阿里内部为解决 Tengine reload 对长连接业务有损,以及 gRPC/Dubbo 负载均衡能力不足而诞生。
184
183
  - **[Gitee AI](https://lobechat.com/discover/provider/giteeai)**: Gitee AI 的 Serverless API 为 AI 开发者提供开箱即用的大模型推理 API 服务。
184
+ - **[Taichu](https://lobechat.com/discover/provider/taichu)**: 中科院自动化研究所和武汉人工智能研究院推出新一代多模态大模型,支持多轮问答、文本创作、图像生成、3D 理解、信号分析等全面问答任务,拥有更强的认知、理解、创作能力,带来全新互动体验。
185
185
 
186
186
  </details>
187
187
 
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Refactor Minimax with LobeOpenAICompatibleFactory."
6
+ ]
7
+ },
8
+ "date": "2025-01-15",
9
+ "version": "1.45.17"
10
+ },
11
+ {
12
+ "children": {
13
+ "improvements": [
14
+ "Improve ai provider code."
15
+ ]
16
+ },
17
+ "date": "2025-01-14",
18
+ "version": "1.45.16"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "fixes": [
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: Observability and Tracing for LobeChat
3
+ description: >-
4
+ Enhance your LobeChat applications with open-source observability and tracing
5
+ using Langfuse. Automatically capture detailed traces and metrics for every
6
+ request to optimize and debug your chats.
7
+ tags:
8
+ - Observability
9
+ - Tracing
10
+ - Langfuse
11
+ ---
12
+
13
+ # Monitor your LobeChat application with Langfuse
14
+
15
+ ## What is Langfuse?
16
+
17
+ [Langfuse](https://langfuse.com/) an **open-source LLM Observability platform**. By enabling the Langfuse integration, you can trace your application data to develop, monitor, and improve the use of LobeChat, including:
18
+
19
+ - Application [traces](https://langfuse.com/docs/tracing)
20
+ - Usage patterns
21
+ - Cost data by user and model
22
+ - [Evaluations](https://langfuse.com/docs/scores/overview)
23
+
24
+ ## Get Started
25
+
26
+ <Steps>
27
+
28
+ ### Set up Langfuse
29
+
30
+ Get your Langfuse API key by signing up for [Langfuse Cloud](https://cloud.langfuse.com) or [self-hosting](https://langfuse.com/docs/deployment/self-host) Langfuse.
31
+
32
+ ### Set up LobeChat
33
+
34
+ There are multiple ways to [self-host LobeChat](https://lobehub.com/docs/self-hosting/start). For this example, we will use the Docker Desktop deployment.
35
+
36
+ <Tabs items={["Environment Variables", "Example in Docker Desktop"]}>
37
+ <Tab>
38
+
39
+ Before deploying LobeChat, set the following four environment variables with the Langfuse API keys you created in the previous step.
40
+
41
+ ```sh
42
+ ENABLE_LANGFUSE = '1'
43
+ LANGFUSE_SECRET_KEY = 'sk-lf...'
44
+ LANGFUSE_PUBLIC_KEY = 'pk-lf...'
45
+ LANGFUSE_HOST = 'https://cloud.langfuse.com'
46
+ ```
47
+ </Tab>
48
+
49
+ <Tab>
50
+
51
+ Before running the Docker container, set the environment variables in the Docker Desktop with the Langfuse API keys you created in the previous step.
52
+
53
+ <Image
54
+ alt={'Environment Variables in Docker Desktop'}
55
+ src={'https://langfuse.com/images/docs/lobechat-docker-desktop-env.png'}
56
+ />
57
+
58
+ </Tab>
59
+
60
+ </Tabs>
61
+
62
+ ### Activate Analytics in Settings
63
+
64
+ Once you have LobeChat running, navigate to the **About** tab in the **Settings** and activate analytics. This is necessary for traces to be sent to Langfuse.
65
+
66
+ <Image
67
+ alt={'LobeChat Settings'}
68
+ src={'https://langfuse.com/images/docs/lobechat-settings.png'}
69
+ />
70
+
71
+ ### See Chat Traces in Langfuse
72
+
73
+ After setting your LLM model key, you can start interacting with your LobeChat application.
74
+
75
+ <Image
76
+ alt={'LobeChat Conversation'}
77
+ src={'https://langfuse.com/images/docs/lobechat-converstation.png'}
78
+ />
79
+
80
+ All conversations in the chat are automatically traced and sent to Langfuse. You can view the traces in the [Traces section](https://langfuse.com/docs/tracing) in the Langfuse UI.
81
+
82
+ <Image
83
+ alt={'LobeChat Example Trace'}
84
+ src={'https://langfuse.com/images/docs/lobechat-example-trace.png'}
85
+ />
86
+ _[Example trace in the Langfuse UI](https://cloud.langfuse.com/project/cloramnkj0002jz088vzn1ja4/traces/63e9246d-3f22-4e45-936d-b0c4ccf55a1e?timestamp=2024-11-26T17%3A00%3A02.028Z&observation=7ea75a0c-d9d1-425c-9b88-27561c63b413)_
87
+
88
+ </Steps>
89
+
90
+ ## Feedback
91
+
92
+ If you have any feedback or requests, please create a GitHub [Issue](https://langfuse.com/issue) or share your work with the Langfuse community on [Discord](https://discord.langfuse.com/).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.45.15",
3
+ "version": "1.45.17",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -27,11 +27,11 @@
27
27
  "sideEffects": false,
28
28
  "scripts": {
29
29
  "build": "next build",
30
+ "build:analyze": "ANALYZE=true next build",
31
+ "build:docker": "DOCKER=true next build && npm run build-sitemap",
30
32
  "postbuild": "npm run build-sitemap && npm run build-migrate-db",
31
33
  "build-migrate-db": "bun run db:migrate",
32
34
  "build-sitemap": "tsx ./scripts/buildSitemapIndex/index.ts",
33
- "build:analyze": "ANALYZE=true next build",
34
- "build:docker": "DOCKER=true next build && npm run build-sitemap",
35
35
  "db:generate": "drizzle-kit generate && npm run db:generate-client",
36
36
  "db:generate-client": "tsx ./scripts/migrateClientDB/compile-migrations.ts",
37
37
  "db:migrate": "MIGRATION_DB=1 tsx ./scripts/migrateServerDB/index.ts",
@@ -59,11 +59,11 @@
59
59
  "start": "next start -p 3210",
60
60
  "stylelint": "stylelint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
61
61
  "test": "npm run test-app && npm run test-server",
62
+ "test:update": "vitest -u",
62
63
  "test-app": "vitest run --config vitest.config.ts",
63
64
  "test-app:coverage": "vitest run --config vitest.config.ts --coverage",
64
65
  "test-server": "vitest run --config vitest.server.config.ts",
65
66
  "test-server:coverage": "vitest run --config vitest.server.config.ts --coverage",
66
- "test:update": "vitest -u",
67
67
  "type-check": "tsc --noEmit",
68
68
  "webhook:ngrok": "ngrok http http://localhost:3011",
69
69
  "workflow:cdn": "tsx ./scripts/cdnWorkflow/index.ts",
@@ -1,33 +1,6 @@
1
1
  import { redirect } from 'next/navigation';
2
2
 
3
- import Ai21Provider from '@/config/modelProviders/ai21';
4
- import Ai360Provider from '@/config/modelProviders/ai360';
5
- import AnthropicProvider from '@/config/modelProviders/anthropic';
6
- import BaichuanProvider from '@/config/modelProviders/baichuan';
7
- import DeepSeekProvider from '@/config/modelProviders/deepseek';
8
- import FireworksAIProvider from '@/config/modelProviders/fireworksai';
9
- import GiteeAIProvider from '@/config/modelProviders/giteeai';
10
- import GoogleProvider from '@/config/modelProviders/google';
11
- import GroqProvider from '@/config/modelProviders/groq';
12
- import HigressProvider from '@/config/modelProviders/higress';
13
- import HunyuanProvider from '@/config/modelProviders/hunyuan';
14
- import InternLMProvider from '@/config/modelProviders/internlm';
15
- import MinimaxProvider from '@/config/modelProviders/minimax';
16
- import MistralProvider from '@/config/modelProviders/mistral';
17
- import MoonshotProvider from '@/config/modelProviders/moonshot';
18
- import NovitaProvider from '@/config/modelProviders/novita';
19
- import OpenRouterProvider from '@/config/modelProviders/openrouter';
20
- import PerplexityProvider from '@/config/modelProviders/perplexity';
21
- import QwenProvider from '@/config/modelProviders/qwen';
22
- import SiliconCloudProvider from '@/config/modelProviders/siliconcloud';
23
- import SparkProvider from '@/config/modelProviders/spark';
24
- import StepfunProvider from '@/config/modelProviders/stepfun';
25
- import TaichuProvider from '@/config/modelProviders/taichu';
26
- import TogetherAIProvider from '@/config/modelProviders/togetherai';
27
- import UpstageProvider from '@/config/modelProviders/upstage';
28
- import XAIProvider from '@/config/modelProviders/xai';
29
- import ZeroOneProvider from '@/config/modelProviders/zeroone';
30
- import ZhiPuProvider from '@/config/modelProviders/zhipu';
3
+ import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
31
4
  import { isServerMode } from '@/const/version';
32
5
  import { serverDB } from '@/database/server';
33
6
  import { AiProviderModel } from '@/database/server/models/aiProvider';
@@ -37,43 +10,14 @@ import { getUserAuth } from '@/utils/server/auth';
37
10
 
38
11
  import ProviderDetail from './index';
39
12
 
40
- const DEFAULT_MODEL_PROVIDER_LIST = [
41
- AnthropicProvider,
42
- GoogleProvider,
43
- DeepSeekProvider,
44
- OpenRouterProvider,
45
- NovitaProvider,
46
- TogetherAIProvider,
47
- FireworksAIProvider,
48
- GroqProvider,
49
- PerplexityProvider,
50
- MistralProvider,
51
- Ai21Provider,
52
- UpstageProvider,
53
- XAIProvider,
54
- QwenProvider,
55
- HunyuanProvider,
56
- SparkProvider,
57
- ZhiPuProvider,
58
- ZeroOneProvider,
59
- StepfunProvider,
60
- MoonshotProvider,
61
- BaichuanProvider,
62
- MinimaxProvider,
63
- Ai360Provider,
64
- TaichuProvider,
65
- InternLMProvider,
66
- SiliconCloudProvider,
67
- HigressProvider,
68
- GiteeAIProvider,
69
- ];
70
-
71
13
  const Page = async (props: PagePropsWithId) => {
72
14
  const params = await props.params;
73
15
 
74
16
  const builtinProviderCard = DEFAULT_MODEL_PROVIDER_LIST.find((v) => v.id === params.id);
17
+ // if builtin provider
75
18
  if (!!builtinProviderCard) return <ProviderDetail source={'builtin'} {...builtinProviderCard} />;
76
19
 
20
+ // if user custom provider
77
21
  if (isServerMode) {
78
22
  const { userId } = await getUserAuth();
79
23
 
@@ -4,12 +4,38 @@ const minimaxChatModels: AIChatModelCard[] = [
4
4
  {
5
5
  abilities: {
6
6
  functionCall: true,
7
+ vision: true,
8
+ },
9
+ contextWindowTokens: 245_760,
10
+ description: '相对于abab6.5系列模型在长文、数学、写作等能力有大幅度提升。',
11
+ displayName: 'abab7-chat-preview',
12
+ enabled: true,
13
+ id: 'abab7-chat-preview',
14
+ maxOutput: 245_760,
15
+ pricing: {
16
+ currency: 'CNY',
17
+ input: 10,
18
+ output: 10,
19
+ },
20
+ releasedAt: '2024-11-06',
21
+ type: 'chat',
22
+ },
23
+ {
24
+ abilities: {
25
+ functionCall: true,
26
+ vision: true,
7
27
  },
8
28
  contextWindowTokens: 245_760,
9
29
  description: '适用于广泛的自然语言处理任务,包括文本生成、对话系统等。',
10
30
  displayName: 'abab6.5s',
11
31
  enabled: true,
12
32
  id: 'abab6.5s-chat',
33
+ maxOutput: 245_760,
34
+ pricing: {
35
+ currency: 'CNY',
36
+ input: 1,
37
+ output: 1,
38
+ },
13
39
  type: 'chat',
14
40
  },
15
41
  {
@@ -21,6 +47,12 @@ const minimaxChatModels: AIChatModelCard[] = [
21
47
  displayName: 'abab6.5g',
22
48
  enabled: true,
23
49
  id: 'abab6.5g-chat',
50
+ maxOutput: 8192,
51
+ pricing: {
52
+ currency: 'CNY',
53
+ input: 5,
54
+ output: 5,
55
+ },
24
56
  type: 'chat',
25
57
  },
26
58
  {
@@ -32,6 +64,12 @@ const minimaxChatModels: AIChatModelCard[] = [
32
64
  displayName: 'abab6.5t',
33
65
  enabled: true,
34
66
  id: 'abab6.5t-chat',
67
+ maxOutput: 8192,
68
+ pricing: {
69
+ currency: 'CNY',
70
+ input: 5,
71
+ output: 5,
72
+ },
35
73
  type: 'chat',
36
74
  },
37
75
  {
@@ -39,6 +77,12 @@ const minimaxChatModels: AIChatModelCard[] = [
39
77
  description: '面向生产力场景,支持复杂任务处理和高效文本生成,适用于专业领域应用。',
40
78
  displayName: 'abab5.5',
41
79
  id: 'abab5.5-chat',
80
+ maxOutput: 16_384,
81
+ pricing: {
82
+ currency: 'CNY',
83
+ input: 5,
84
+ output: 5,
85
+ },
42
86
  type: 'chat',
43
87
  },
44
88
  {
@@ -46,6 +90,12 @@ const minimaxChatModels: AIChatModelCard[] = [
46
90
  description: '专为中文人设对话场景设计,提供高质量的中文对话生成能力,适用于多种应用场景。',
47
91
  displayName: 'abab5.5s',
48
92
  id: 'abab5.5s-chat',
93
+ maxOutput: 8192,
94
+ pricing: {
95
+ currency: 'CNY',
96
+ input: 15,
97
+ output: 15,
98
+ },
49
99
  type: 'chat',
50
100
  },
51
101
  ];
@@ -113,11 +113,11 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [
113
113
  BaichuanProvider,
114
114
  MinimaxProvider,
115
115
  Ai360Provider,
116
- TaichuProvider,
117
- InternLMProvider,
118
116
  SiliconCloudProvider,
117
+ InternLMProvider,
119
118
  HigressProvider,
120
119
  GiteeAIProvider,
120
+ TaichuProvider,
121
121
  ];
122
122
 
123
123
  export const filterEnabledModels = (provider: ModelProviderCard) => {
@@ -1,184 +1,40 @@
1
- import { isEmpty } from 'lodash-es';
2
- import OpenAI from 'openai';
3
-
4
- import { LobeRuntimeAI } from '../BaseAI';
5
- import { AgentRuntimeErrorType } from '../error';
6
- import {
7
- ChatCompetitionOptions,
8
- ChatCompletionErrorPayload,
9
- ChatStreamPayload,
10
- ModelProvider,
11
- } from '../types';
12
- import { AgentRuntimeError } from '../utils/createError';
13
- import { debugStream } from '../utils/debugStream';
14
- import { StreamingResponse } from '../utils/response';
15
- import { MinimaxStream } from '../utils/streams';
16
-
17
- interface MinimaxBaseResponse {
18
- base_resp?: {
19
- status_code?: number;
20
- status_msg?: string;
21
- };
22
- }
23
-
24
- type MinimaxResponse = Partial<OpenAI.ChatCompletionChunk> & MinimaxBaseResponse;
25
-
26
- function throwIfErrorResponse(data: MinimaxResponse) {
27
- // error status code
28
- // https://www.minimaxi.com/document/guides/chat-model/pro/api?id=6569c85948bc7b684b30377e#3.1.3%20%E8%BF%94%E5%9B%9E(response)%E5%8F%82%E6%95%B0
29
- if (!data.base_resp?.status_code || data.base_resp?.status_code < 1000) {
30
- return;
31
- }
32
- if (data.base_resp?.status_code === 1004) {
33
- throw AgentRuntimeError.chat({
34
- error: {
35
- code: data.base_resp.status_code,
36
- message: data.base_resp.status_msg,
37
- },
38
- errorType: AgentRuntimeErrorType.InvalidProviderAPIKey,
39
- provider: ModelProvider.Minimax,
40
- });
41
- }
42
- throw AgentRuntimeError.chat({
43
- error: {
44
- code: data.base_resp.status_code,
45
- message: data.base_resp.status_msg,
46
- },
47
- errorType: AgentRuntimeErrorType.ProviderBizError,
48
- provider: ModelProvider.Minimax,
49
- });
50
- }
51
-
52
- function parseMinimaxResponse(chunk: string): MinimaxResponse | undefined {
53
- let body = chunk;
54
- if (body.startsWith('data:')) {
55
- body = body.slice(5).trim();
56
- }
57
- if (isEmpty(body)) {
58
- return;
59
- }
60
- return JSON.parse(body) as MinimaxResponse;
61
- }
62
-
63
- export class LobeMinimaxAI implements LobeRuntimeAI {
64
- apiKey: string;
65
-
66
- constructor({ apiKey }: { apiKey?: string } = {}) {
67
- if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey);
68
-
69
- this.apiKey = apiKey;
70
- }
71
-
72
- async chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions): Promise<Response> {
73
- try {
74
- const response = await fetch('https://api.minimax.chat/v1/text/chatcompletion_v2', {
75
- body: JSON.stringify(this.buildCompletionsParams(payload)),
76
- headers: {
77
- 'Authorization': `Bearer ${this.apiKey}`,
78
- 'Content-Type': 'application/json',
79
- },
80
- method: 'POST',
81
- });
82
- if (!response.body || !response.ok) {
83
- throw AgentRuntimeError.chat({
84
- error: {
85
- status: response.status,
86
- statusText: response.statusText,
1
+ import { ModelProvider } from '../types';
2
+ import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3
+
4
+ import Minimax from '@/config/modelProviders/minimax';
5
+
6
+ export const getMinimaxMaxOutputs = (modelId: string): number | undefined => {
7
+ const model = Minimax.chatModels.find(model => model.id === modelId);
8
+ return model ? model.maxOutput : undefined;
9
+ };
10
+
11
+ export const LobeMinimaxAI = LobeOpenAICompatibleFactory({
12
+ baseURL: 'https://api.minimax.chat/v1',
13
+ chatCompletion: {
14
+ handlePayload: (payload) => {
15
+ const { temperature, top_p, ...params } = payload;
16
+
17
+ return {
18
+ ...params,
19
+ frequency_penalty: undefined,
20
+ max_tokens: payload.max_tokens !== undefined ? payload.max_tokens : getMinimaxMaxOutputs(payload.model),
21
+ presence_penalty: undefined,
22
+ stream: true,
23
+ temperature: temperature === undefined || temperature <= 0 ? undefined : temperature / 2,
24
+ tools: params.tools?.map((tool) => ({
25
+ function: {
26
+ description: tool.function.description,
27
+ name: tool.function.name,
28
+ parameters: JSON.stringify(tool.function.parameters),
87
29
  },
88
- errorType: AgentRuntimeErrorType.ProviderBizError,
89
- provider: ModelProvider.Minimax,
90
- });
91
- }
92
-
93
- const [prod, body2] = response.body.tee();
94
- const [prod2, debug] = body2.tee();
95
-
96
- if (process.env.DEBUG_MINIMAX_CHAT_COMPLETION === '1') {
97
- debugStream(debug).catch(console.error);
98
- }
99
-
100
- // wait for the first response, and throw error if minix returns an error
101
- await this.parseFirstResponse(prod2.getReader());
102
-
103
- return StreamingResponse(MinimaxStream(prod), { headers: options?.headers });
104
- } catch (error) {
105
- console.log('error', error);
106
- const err = error as Error | ChatCompletionErrorPayload;
107
- if ('provider' in err) {
108
- throw error;
109
- }
110
- const errorResult = {
111
- cause: err.cause,
112
- message: err.message,
113
- name: err.name,
114
- stack: err.stack,
115
- };
116
- throw AgentRuntimeError.chat({
117
- error: errorResult,
118
- errorType: AgentRuntimeErrorType.ProviderBizError,
119
- provider: ModelProvider.Minimax,
120
- });
121
- }
122
- }
123
-
124
- // the document gives the default value of max tokens, but abab6.5 and abab6.5s
125
- // will meet length finished error, and output is truncationed
126
- // so here fill the max tokens number to fix it
127
- // https://www.minimaxi.com/document/guides/chat-model/V2
128
- private getMaxTokens(model: string): number | undefined {
129
- switch (model) {
130
- case 'abab6.5t-chat':
131
- case 'abab6.5g-chat':
132
- case 'abab5.5s-chat':
133
- case 'abab5.5-chat': {
134
- return 4096;
135
- }
136
- case 'abab6.5s-chat': {
137
- return 8192;
138
- }
139
- }
140
- }
141
-
142
- private buildCompletionsParams(payload: ChatStreamPayload) {
143
- const { temperature, top_p, ...params } = payload;
144
-
145
- return {
146
- ...params,
147
- frequency_penalty: undefined,
148
- max_tokens:
149
- payload.max_tokens !== undefined ? payload.max_tokens : this.getMaxTokens(payload.model),
150
- presence_penalty: undefined,
151
- stream: true,
152
- temperature: temperature === undefined || temperature <= 0 ? undefined : temperature / 2,
153
-
154
- tools: params.tools?.map((tool) => ({
155
- function: {
156
- description: tool.function.description,
157
- name: tool.function.name,
158
- parameters: JSON.stringify(tool.function.parameters),
159
- },
160
- type: 'function',
161
- })),
162
- top_p: top_p === 0 ? undefined : top_p,
163
- };
164
- }
165
-
166
- private async parseFirstResponse(reader: ReadableStreamDefaultReader<Uint8Array>) {
167
- const decoder = new TextDecoder();
168
-
169
- const { value } = await reader.read();
170
- const chunkValue = decoder.decode(value, { stream: true });
171
- let data;
172
- try {
173
- data = parseMinimaxResponse(chunkValue);
174
- } catch {
175
- // parse error, skip it
176
- return;
177
- }
178
- if (data) {
179
- throwIfErrorResponse(data);
180
- }
181
- }
182
- }
183
-
184
- export default LobeMinimaxAI;
30
+ type: 'function',
31
+ })),
32
+ top_p: top_p !== undefined && top_p > 0 && top_p <= 1 ? top_p : undefined,
33
+ } as any;
34
+ },
35
+ },
36
+ debug: {
37
+ chatCompletion: () => process.env.DEBUG_MINIMAX_CHAT_COMPLETION === '1',
38
+ },
39
+ provider: ModelProvider.Minimax,
40
+ });
@@ -2,7 +2,6 @@ export * from './anthropic';
2
2
  export * from './azureOpenai';
3
3
  export * from './bedrock';
4
4
  export * from './google-ai';
5
- export * from './minimax';
6
5
  export * from './ollama';
7
6
  export * from './openai';
8
7
  export * from './protocol';
@@ -1,26 +0,0 @@
1
- // @vitest-environment edge-runtime
2
- import { describe, expect, it, vi } from 'vitest';
3
-
4
- import { POST as UniverseRoute } from '../[provider]/route';
5
- import { POST, runtime } from './route';
6
-
7
- // 模拟 '../[provider]/route'
8
- vi.mock('../[provider]/route', () => ({
9
- POST: vi.fn().mockResolvedValue('mocked response'),
10
- }));
11
-
12
- describe('Configuration tests', () => {
13
- it('should have runtime set to "edge"', () => {
14
- expect(runtime).toBe('nodejs');
15
- });
16
- });
17
-
18
- describe('Minimax POST function tests', () => {
19
- it('should call UniverseRoute with correct parameters', async () => {
20
- const mockRequest = new Request('https://example.com', { method: 'POST' });
21
- await POST(mockRequest);
22
- expect(UniverseRoute).toHaveBeenCalledWith(mockRequest, {
23
- params: Promise.resolve({ provider: 'minimax' }),
24
- });
25
- });
26
- });
@@ -1,6 +0,0 @@
1
- import { POST as UniverseRoute } from '../[provider]/route';
2
-
3
- export const runtime = 'nodejs';
4
-
5
- export const POST = async (req: Request) =>
6
- UniverseRoute(req, { params: Promise.resolve({ provider: 'minimax' }) });
@@ -1,275 +0,0 @@
1
- // @vitest-environment edge-runtime
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- import { ChatStreamPayload, ModelProvider } from '@/libs/agent-runtime';
5
- import * as debugStreamModule from '@/libs/agent-runtime/utils/debugStream';
6
-
7
- import { LobeMinimaxAI } from './index';
8
-
9
- const provider = ModelProvider.Minimax;
10
- const bizErrorType = 'ProviderBizError';
11
- const invalidErrorType = 'InvalidProviderAPIKey';
12
-
13
- const encoder = new TextEncoder();
14
-
15
- // Mock the console.error to avoid polluting test output
16
- vi.spyOn(console, 'error').mockImplementation(() => {});
17
-
18
- let instance: LobeMinimaxAI;
19
-
20
- beforeEach(() => {
21
- instance = new LobeMinimaxAI({ apiKey: 'test' });
22
- });
23
-
24
- afterEach(() => {
25
- vi.clearAllMocks();
26
- });
27
-
28
- describe('LobeMinimaxAI', () => {
29
- describe('init', () => {
30
- it('should correctly initialize with an API key', async () => {
31
- const instance = new LobeMinimaxAI({ apiKey: 'test_api_key' });
32
- expect(instance).toBeInstanceOf(LobeMinimaxAI);
33
- });
34
-
35
- it('should throw AgentRuntimeError with InvalidMinimaxAPIKey if no apiKey is provided', async () => {
36
- try {
37
- new LobeMinimaxAI({});
38
- } catch (e) {
39
- expect(e).toEqual({ errorType: invalidErrorType });
40
- }
41
- });
42
- });
43
-
44
- describe('chat', () => {
45
- it('should return a StreamingTextResponse on successful API call', async () => {
46
- const mockResponseData = {
47
- choices: [{ delta: { content: 'Hello, world!' } }],
48
- };
49
- const mockResponse = new Response(
50
- new ReadableStream({
51
- start(controller) {
52
- controller.enqueue(encoder.encode(`data: ${JSON.stringify(mockResponseData)}`));
53
- controller.close();
54
- },
55
- }),
56
- );
57
- vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce(mockResponse);
58
-
59
- const result = await instance.chat({
60
- messages: [{ content: 'Hello', role: 'user' }],
61
- model: 'text-davinci-003',
62
- temperature: 0,
63
- });
64
-
65
- expect(result).toBeInstanceOf(Response);
66
- });
67
-
68
- it('should handle text messages correctly', async () => {
69
- const mockResponseData = {
70
- choices: [{ delta: { content: 'Hello, world!' } }],
71
- };
72
- const mockResponse = new Response(
73
- new ReadableStream({
74
- start(controller) {
75
- controller.enqueue(encoder.encode(`data: ${JSON.stringify(mockResponseData)}`));
76
- controller.close();
77
- },
78
- }),
79
- );
80
- vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce(mockResponse);
81
-
82
- const result = await instance.chat({
83
- messages: [{ content: 'Hello', role: 'user' }],
84
- model: 'text-davinci-003',
85
- temperature: 0,
86
- });
87
-
88
- expect(result).toBeInstanceOf(Response);
89
- });
90
-
91
- it('should call debugStream in DEBUG mode', async () => {
92
- process.env.DEBUG_MINIMAX_CHAT_COMPLETION = '1';
93
-
94
- vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce(
95
- new Response(
96
- new ReadableStream({
97
- start(controller) {
98
- controller.enqueue(encoder.encode(JSON.stringify('Hello, world!')));
99
- controller.close();
100
- },
101
- }),
102
- ),
103
- );
104
-
105
- vi.spyOn(debugStreamModule, 'debugStream').mockImplementation(() => Promise.resolve());
106
-
107
- await instance.chat({
108
- messages: [{ content: 'Hello', role: 'user' }],
109
- model: 'text-davinci-003',
110
- temperature: 0,
111
- });
112
-
113
- // Assert
114
- expect(debugStreamModule.debugStream).toHaveBeenCalled();
115
-
116
- delete process.env.DEBUG_MINIMAX_CHAT_COMPLETION;
117
- });
118
-
119
- describe('Error', () => {
120
- it('should throw InvalidMinimaxAPIKey error on API_KEY_INVALID error', async () => {
121
- const mockErrorResponse = {
122
- base_resp: {
123
- status_code: 1004,
124
- status_msg: 'API key not valid',
125
- },
126
- };
127
- vi.spyOn(globalThis, 'fetch').mockResolvedValue(
128
- new Response(
129
- new ReadableStream({
130
- start(controller) {
131
- controller.enqueue(encoder.encode(JSON.stringify(mockErrorResponse)));
132
- controller.close();
133
- },
134
- }),
135
- ),
136
- );
137
-
138
- try {
139
- await instance.chat({
140
- messages: [{ content: 'Hello', role: 'user' }],
141
- model: 'text-davinci-003',
142
- temperature: 0,
143
- });
144
- } catch (e) {
145
- expect(e).toEqual({
146
- errorType: invalidErrorType,
147
- error: {
148
- code: 1004,
149
- message: 'API key not valid',
150
- },
151
- provider,
152
- });
153
- }
154
- });
155
-
156
- it('should throw MinimaxBizError error on other error status codes', async () => {
157
- const mockErrorResponse = {
158
- base_resp: {
159
- status_code: 1001,
160
- status_msg: 'Some error occurred',
161
- },
162
- };
163
- vi.spyOn(globalThis, 'fetch').mockResolvedValue(
164
- new Response(
165
- new ReadableStream({
166
- start(controller) {
167
- controller.enqueue(encoder.encode(JSON.stringify(mockErrorResponse)));
168
- controller.close();
169
- },
170
- }),
171
- ),
172
- );
173
-
174
- try {
175
- await instance.chat({
176
- messages: [{ content: 'Hello', role: 'user' }],
177
- model: 'text-davinci-003',
178
- temperature: 0,
179
- });
180
- } catch (e) {
181
- expect(e).toEqual({
182
- errorType: bizErrorType,
183
- error: {
184
- code: 1001,
185
- message: 'Some error occurred',
186
- },
187
- provider,
188
- });
189
- }
190
- });
191
-
192
- it('should throw MinimaxBizError error on generic errors', async () => {
193
- const mockError = new Error('Something went wrong');
194
- vi.spyOn(globalThis, 'fetch').mockRejectedValueOnce(mockError);
195
-
196
- try {
197
- await instance.chat({
198
- messages: [{ content: 'Hello', role: 'user' }],
199
- model: 'text-davinci-003',
200
- temperature: 0,
201
- });
202
- } catch (e) {
203
- expect(e).toEqual({
204
- errorType: bizErrorType,
205
- error: {
206
- cause: undefined,
207
- message: 'Something went wrong',
208
- name: 'Error',
209
- stack: mockError.stack,
210
- },
211
- provider,
212
- });
213
- }
214
- });
215
- });
216
- });
217
-
218
- describe('private methods', () => {
219
- describe('buildCompletionsParams', () => {
220
- it('should build the correct parameters', () => {
221
- const payload: ChatStreamPayload = {
222
- messages: [{ content: 'Hello', role: 'user' }],
223
- model: 'text-davinci-003',
224
- temperature: 0.5,
225
- top_p: 0.8,
226
- };
227
-
228
- const result = instance['buildCompletionsParams'](payload);
229
-
230
- expect(result).toEqual({
231
- messages: [{ content: 'Hello', role: 'user' }],
232
- model: 'text-davinci-003',
233
- stream: true,
234
- temperature: 0.25,
235
- top_p: 0.8,
236
- });
237
- });
238
-
239
- it('should exclude temperature and top_p when they are 0', () => {
240
- const payload: ChatStreamPayload = {
241
- messages: [{ content: 'Hello', role: 'user' }],
242
- model: 'text-davinci-003',
243
- temperature: 0,
244
- top_p: 0,
245
- };
246
-
247
- const result = instance['buildCompletionsParams'](payload);
248
-
249
- expect(result).toEqual({
250
- messages: [{ content: 'Hello', role: 'user' }],
251
- model: 'text-davinci-003',
252
- stream: true,
253
- });
254
- });
255
-
256
- it('should include max tokens when model is abab6.5t-chat', () => {
257
- const payload: ChatStreamPayload = {
258
- messages: [{ content: 'Hello', role: 'user' }],
259
- model: 'abab6.5t-chat',
260
- temperature: 0,
261
- top_p: 0,
262
- };
263
-
264
- const result = instance['buildCompletionsParams'](payload);
265
-
266
- expect(result).toEqual({
267
- messages: [{ content: 'Hello', role: 'user' }],
268
- model: 'abab6.5t-chat',
269
- stream: true,
270
- max_tokens: 4096,
271
- });
272
- });
273
- });
274
- });
275
- });
@@ -1,27 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import { processDoubleData } from './minimax';
4
-
5
- // 假设文件名为 minimax.ts
6
-
7
- describe('processDoubleData', () => {
8
- it('should remove the second "data: {"id": and everything after it when matchCount is 2', () => {
9
- const chunkValue = `data: {"id":"first"} some other text
10
-
11
- data: {"id":"second"} more text`;
12
- const result = processDoubleData(chunkValue);
13
- expect(result).toBe('data: {"id":"first"} some other text');
14
- });
15
-
16
- it('should not modify chunkValue when matchCount is not 2', () => {
17
- const chunkValue = `data: {"id":"first"} some other text`;
18
- const result = processDoubleData(chunkValue);
19
- expect(result).toBe(chunkValue);
20
- });
21
-
22
- it('should not modify chunkValue when matchCount is more than 2', () => {
23
- const chunkValue = `data: {"id":"first"} some other text data: {"id":"second"} more text data: {"id":"third"} even more text`;
24
- const result = processDoubleData(chunkValue);
25
- expect(result).toBe(chunkValue);
26
- });
27
- });
@@ -1,57 +0,0 @@
1
- import OpenAI from 'openai';
2
-
3
- import { ChatStreamCallbacks } from '../../types';
4
- import { transformOpenAIStream } from './openai';
5
- import { createCallbacksTransformer, createSSEProtocolTransformer } from './protocol';
6
-
7
- export const processDoubleData = (chunkValue: string): string => {
8
- const dataPattern = /data: {"id":"/g;
9
- const matchCount = (chunkValue.match(dataPattern) || []).length;
10
- let modifiedChunkValue = chunkValue;
11
- if (matchCount === 2) {
12
- const secondDataIdIndex = chunkValue.indexOf(
13
- 'data: {"id":',
14
- chunkValue.indexOf('data: {"id":') + 1,
15
- );
16
- if (secondDataIdIndex !== -1) {
17
- modifiedChunkValue = chunkValue.slice(0, secondDataIdIndex).trim();
18
- }
19
- }
20
- return modifiedChunkValue;
21
- };
22
-
23
- const unit8ArrayToJSONChunk = (unit8Array: Uint8Array): OpenAI.ChatCompletionChunk => {
24
- const decoder = new TextDecoder();
25
-
26
- let chunkValue = decoder.decode(unit8Array, { stream: true });
27
-
28
- // chunkValue example:
29
- // data: {"id":"028a65377137d57aaceeffddf48ae99f","choices":[{"finish_reason":"tool_calls","index":0,"delta":{"role":"assistant","tool_calls":[{"id":"call_function_7371372822","type":"function","function":{"name":"realtime-weather____fetchCurrentWeather","arguments":"{\"city\": [\"杭州\", \"北京\"]}"}}]}}],"created":155511,"model":"abab6.5s-chat","object":"chat.completion.chunk"}
30
-
31
- chunkValue = processDoubleData(chunkValue);
32
-
33
- // so we need to remove `data:` prefix and then parse it as JSON
34
- if (chunkValue.startsWith('data:')) {
35
- chunkValue = chunkValue.slice(5).trim();
36
- }
37
-
38
- try {
39
- return JSON.parse(chunkValue);
40
- } catch (e) {
41
- console.error('minimax chunk parse error:', e);
42
-
43
- return { raw: chunkValue } as any;
44
- }
45
- };
46
-
47
- export const MinimaxStream = (stream: ReadableStream, callbacks?: ChatStreamCallbacks) => {
48
- return stream
49
- .pipeThrough(
50
- createSSEProtocolTransformer((buffer) => {
51
- const chunk = unit8ArrayToJSONChunk(buffer);
52
-
53
- return transformOpenAIStream(chunk);
54
- }),
55
- )
56
- .pipeThrough(createCallbacksTransformer(callbacks));
57
- };