diff --git a/.env.example b/.env.example index b7a7f4b7e6e88..782b3ba1c4fb0 100644 --- a/.env.example +++ b/.env.example @@ -127,6 +127,10 @@ OPENAI_API_KEY=sk-xxxxxxxxx # TENCENT_CLOUD_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +### PPIO #### + +# PPIO_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ######################################## ############ Market Service ############ ######################################## diff --git a/Dockerfile b/Dockerfile index 3f2eb3261e45d..c770b1c13ac87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -199,6 +199,8 @@ ENV \ OPENROUTER_API_KEY="" OPENROUTER_MODEL_LIST="" \ # Perplexity PERPLEXITY_API_KEY="" PERPLEXITY_MODEL_LIST="" PERPLEXITY_PROXY_URL="" \ + # PPIO + PPIO_API_KEY="" PPIO_MODEL_LIST="" \ # Qwen QWEN_API_KEY="" QWEN_MODEL_LIST="" QWEN_PROXY_URL="" \ # SenseNova diff --git a/Dockerfile.database b/Dockerfile.database index 307caf95443f4..8e0e6711d36d8 100644 --- a/Dockerfile.database +++ b/Dockerfile.database @@ -236,6 +236,8 @@ ENV \ OPENROUTER_API_KEY="" OPENROUTER_MODEL_LIST="" \ # Perplexity PERPLEXITY_API_KEY="" PERPLEXITY_MODEL_LIST="" PERPLEXITY_PROXY_URL="" \ + # PPIO + PPIO_API_KEY="" PPIO_MODEL_LIST="" \ # Qwen QWEN_API_KEY="" QWEN_MODEL_LIST="" QWEN_PROXY_URL="" \ # SenseNova diff --git a/README.ja-JP.md b/README.ja-JP.md index 919667cf8d5c9..70cc1dd454ef8 100644 --- a/README.ja-JP.md +++ b/README.ja-JP.md @@ -137,6 +137,7 @@ LobeChat の継続的な開発において、AI 会話サービスを提供す
See more providers (+26) +- **[PPIO](https://lobechat.com/discover/provider/PPIO)**: PPIO は、DeepSeek、Llama、Qwen などの安定した費用対効果の高いオープンソース LLM API をサポートしています。[詳細はこちら](https://ppinfra.com/llm-api?utm_source=github_lobe-chat&utm_medium=github_readme&utm_campaign=link) - **[Novita](https://lobechat.com/discover/provider/novita)**: Novita AI は、さまざまな大規模言語モデルと AI 画像生成の API サービスを提供するプラットフォームであり、柔軟で信頼性が高く、コスト効率に優れています。Llama3、Mistral などの最新のオープンソースモデルをサポートし、生成的 AI アプリケーションの開発に向けた包括的でユーザーフレンドリーかつ自動スケーリングの API ソリューションを提供し、AI スタートアップの急成長を支援します。 - **[Together AI](https://lobechat.com/discover/provider/togetherai)**: Together AI は、革新的な AI モデルを通じて先進的な性能を実現することに取り組んでおり、迅速なスケーリングサポートや直感的な展開プロセスを含む広範なカスタマイズ能力を提供し、企業のさまざまなニーズに応えています。 - **[Fireworks AI](https://lobechat.com/discover/provider/fireworksai)**: Fireworks AI は、先進的な言語モデルサービスのリーダーであり、機能呼び出しと多モーダル処理に特化しています。最新のモデル Firefunction V2 は Llama-3 に基づいており、関数呼び出し、対話、指示の遵守に最適化されています。視覚言語モデル FireLLaVA-13B は、画像とテキストの混合入力をサポートしています。他の注目すべきモデルには、Llama シリーズや Mixtral シリーズがあり、高効率の多言語指示遵守と生成サポートを提供しています。 diff --git a/README.md b/README.md index cf76abd79044f..0c352b4e40bef 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,7 @@ We have implemented support for the following model service providers:
See more providers (+26) +- **[PPIO](https://lobechat.com/discover/provider/ppio)**: PPIO supports stable and cost-efficient open-source LLM APIs, such as DeepSeek, Llama, Qwen etc. [Learn more](https://ppinfra.com/llm-api?utm_source=github_lobe-chat&utm_medium=github_readme&utm_campaign=link) - **[Novita](https://lobechat.com/discover/provider/novita)**: Novita AI is a platform providing a variety of large language models and AI image generation API services, flexible, reliable, and cost-effective. It supports the latest open-source models like Llama3 and Mistral, offering a comprehensive, user-friendly, and auto-scaling API solution for generative AI application development, suitable for the rapid growth of AI startups. - **[Together AI](https://lobechat.com/discover/provider/togetherai)**: Together AI is dedicated to achieving leading performance through innovative AI models, offering extensive customization capabilities, including rapid scaling support and intuitive deployment processes to meet various enterprise needs. - **[Fireworks AI](https://lobechat.com/discover/provider/fireworksai)**: Fireworks AI is a leading provider of advanced language model services, focusing on functional calling and multimodal processing. Its latest model, Firefunction V2, is based on Llama-3, optimized for function calling, conversation, and instruction following. The visual language model FireLLaVA-13B supports mixed input of images and text. Other notable models include the Llama series and Mixtral series, providing efficient multilingual instruction following and generation support. @@ -629,7 +630,7 @@ If you would like to learn more details, please feel free to look at our [📘 D ## 🤝 Contributing -Contributions of all types are more than welcome; if you are interested in contributing code, feel free to check out our GitHub [Issues][github-issues-link] and [Projects][github-project-link] to get stuck in to show us what you’re made of. +Contributions of all types are more than welcome; if you are interested in contributing code, feel free to check out our GitHub [Issues][github-issues-link] and [Projects][github-project-link] to get stuck in to show us what you're made of. > \[!TIP] > @@ -844,7 +845,7 @@ This project is [Apache 2.0](./LICENSE) licensed. [profile-link]: https://github.com/lobehub [share-linkedin-link]: https://linkedin.com/feed [share-linkedin-shield]: https://img.shields.io/badge/-share%20on%20linkedin-black?labelColor=black&logo=linkedin&logoColor=white&style=flat-square -[share-mastodon-link]: https://mastodon.social/share?text=Check%20this%20GitHub%20repository%20out%20%F0%9F%A4%AF%20LobeChat%20-%20An%20open-source,%20extensible%20(Function%20Calling),%20high-performance%20chatbot%20framework.%20It%20supports%20one-click%20free%20deployment%20of%20your%20private%20ChatGPT/LLM%20web%20application.%20https://github.com/lobehub/lobe-chat%20#chatbot%20#chatGPT%20#openAI +[share-mastodon-link]: https://mastodon.social/share?text=Check%20this%20GitHub%20repository%20out%20%F0%9F%A4%AF%20LobeChat%20-%20An%20open-source,%20extensible%20%28Function%20Calling%29,%20high-performance%20chatbot%20framework.%20It%20supports%20one-click%20free%20deployment%20of%20your%20private%20ChatGPT%2FLLM%20web%20application.%20https://github.com/lobehub/lobe-chat%20#chatbot%20#chatGPT%20#openAI [share-mastodon-shield]: https://img.shields.io/badge/-share%20on%20mastodon-black?labelColor=black&logo=mastodon&logoColor=white&style=flat-square [share-reddit-link]: https://www.reddit.com/submit?title=Check%20this%20GitHub%20repository%20out%20%F0%9F%A4%AF%20LobeChat%20-%20An%20open-source%2C%20extensible%20%28Function%20Calling%29%2C%20high-performance%20chatbot%20framework.%20It%20supports%20one-click%20free%20deployment%20of%20your%20private%20ChatGPT%2FLLM%20web%20application.%20%23chatbot%20%23chatGPT%20%23openAI&url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat [share-reddit-shield]: https://img.shields.io/badge/-share%20on%20reddit-black?labelColor=black&logo=reddit&logoColor=white&style=flat-square diff --git a/README.zh-CN.md b/README.zh-CN.md index e04d56c73ac96..48b3bb98cbe8d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -155,7 +155,7 @@ LobeChat 支持文件上传与知识库功能,你可以上传文件、图片 - **[GitHub](https://lobechat.com/discover/provider/github)**: 通过 GitHub 模型,开发人员可以成为 AI 工程师,并使用行业领先的 AI 模型进行构建。
See more providers (+26) - +- **[PPIO](https://lobechat.com/discover/provider/ppio)**: PPIO 派欧云提供稳定、高性价比的开源模型 API 服务,支持 DeepSeek 全系列、Llama、Qwen 等行业领先大模型。[了解更多](https://ppinfra.com/llm-api?utm_source=github_lobe-chat&utm_medium=github_readme&utm_campaign=link) - **[Novita](https://lobechat.com/discover/provider/novita)**: Novita AI 是一个提供多种大语言模型与 AI 图像生成的 API 服务的平台,灵活、可靠且具有成本效益。它支持 Llama3、Mistral 等最新的开源模型,并为生成式 AI 应用开发提供了全面、用户友好且自动扩展的 API 解决方案,适合 AI 初创公司的快速发展。 - **[Together AI](https://lobechat.com/discover/provider/togetherai)**: Together AI 致力于通过创新的 AI 模型实现领先的性能,提供广泛的自定义能力,包括快速扩展支持和直观的部署流程,满足企业的各种需求。 - **[Fireworks AI](https://lobechat.com/discover/provider/fireworksai)**: Fireworks AI 是一家领先的高级语言模型服务商,专注于功能调用和多模态处理。其最新模型 Firefunction V2 基于 Llama-3,优化用于函数调用、对话及指令跟随。视觉语言模型 FireLLaVA-13B 支持图像和文本混合输入。其他 notable 模型包括 Llama 系列和 Mixtral 系列,提供高效的多语言指令跟随与生成支持。 diff --git a/README.zh-TW.md b/README.zh-TW.md index f211a2bdd9e0f..c58ea21194ce4 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -161,6 +161,7 @@ LobeChat 支持文件上傳與知識庫功能,你可以上傳文件、圖片
瀏覽更多供應商 (+26) +- **[PPIO](https://lobechat.com/discover/provider/ppio)**: PPIO 派歐雲提供穩定、高性價比的開源模型 API 服務,支持 DeepSeek 全系列、Llama、Qwen 等行業領先大模型。[瞭解更多](https://ppinfra.com/llm-api?utm_source=github_lobe-chat&utm_medium=github_readme&utm_campaign=link) - **[Novita](https://lobechat.com/discover/provider/novita)**: Novita AI 是一個提供多種大語言模型與 AI 圖像生成的 API 服務的平台,靈活、可靠且具有成本效益。它支持 Llama3、Mistral 等最新的開源模型,並為生成式 AI 應用開發提供了全面、用戶友好且自動擴展的 API 解決方案,適合 AI 初創公司的快速發展。 - **[Together AI](https://lobechat.com/discover/provider/togetherai)**: Together AI 致力於通過創新的 AI 模型實現領先的性能,提供廣泛的自定義能力,包括快速擴展支持和直觀的部署流程,滿足企業的各種需求。 - **[Fireworks AI](https://lobechat.com/discover/provider/fireworksai)**: Fireworks AI 是一家領先的高級語言模型服務商,專注於功能調用和多模態處理。其最新模型 Firefunction V2 基於 Llama-3,優化用於函數調用、對話及指令跟隨。視覺語言模型 FireLLaVA-13B 支持圖像和文本混合輸入。其他 notable 模型包括 Llama 系列和 Mixtral 系列,提供高效的多語言指令跟隨與生成支持。 diff --git a/docs/self-hosting/environment-variables/model-provider.mdx b/docs/self-hosting/environment-variables/model-provider.mdx index e8921e911ac8a..4decbe5ec670b 100644 --- a/docs/self-hosting/environment-variables/model-provider.mdx +++ b/docs/self-hosting/environment-variables/model-provider.mdx @@ -199,6 +199,22 @@ If you need to use Azure OpenAI to provide model services, you can refer to the - Default: `-` - Example: `-all,+01-ai/yi-34b-chat,+huggingfaceh4/zephyr-7b-beta` +## PPIO + +### `PPIO_API_KEY` + +- Type: Required +- Description: This your PPIO API Key. +- Default: - +- Example: `sk_xxxxxxxxxx` + +### `PPIO_MODEL_LIST` + +- Type: Optional +- Description: Used to control the model list, use `+` to add a model, use `-` to hide a model, use `model_name=display_name` to customize the display name of a model, separated by commas. Definition syntax rules see [model-list][model-list] +- Default: `-` +- Example: `-all,+deepseek/deepseek-v3/community,+deepseek/deepseek-r1-distill-llama-70b` + ## Github ### `GITHUB_TOKEN` diff --git a/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx b/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx index cdc5224c9b6f4..e34371e2f0a3b 100644 --- a/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +++ b/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx @@ -197,6 +197,22 @@ LobeChat 在部署时提供了丰富的模型服务商相关的环境变量, - 默认值:`-` - 示例:`-all,+01-ai/yi-34b-chat,+huggingfaceh4/zephyr-7b-beta` +## PPIO + +### `PPIO_API_KEY` + +- 类型:必选 +- 描述:这是你在 PPIO 网站申请的 API 密钥 +- 默认值:- +- 示例:`sk_xxxxxxxxxxxx` + +### `PPIO_MODEL_LIST` + +- 类型:可选 +- 描述:用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名<扩展配置>` 来自定义模型的展示名,用英文逗号隔开。模型定义语法规则见 [模型列表][model-list] +- 默认值:`-` +- 示例:`-all,+deepseek/deepseek-v3/community,+deepseek/deepseek-r1-distill-llama-70b` + ## Github ### `GITHUB_TOKEN` diff --git a/locales/en-US/providers.json b/locales/en-US/providers.json index 2bbb88be813b5..4f427c29d518f 100644 --- a/locales/en-US/providers.json +++ b/locales/en-US/providers.json @@ -118,5 +118,8 @@ }, "zhipu": { "description": "Zhipu AI offers an open platform for multimodal and language models, supporting a wide range of AI application scenarios, including text processing, image understanding, and programming assistance." + }, + "ppio": { + "description": "PPIO supports stable and cost-efficient open-source LLM APIs, such as DeepSeek, Llama, Qwen etc." } } diff --git a/locales/zh-CN/providers.json b/locales/zh-CN/providers.json index fdb6f8557e09c..7aac47c926bf8 100644 --- a/locales/zh-CN/providers.json +++ b/locales/zh-CN/providers.json @@ -118,5 +118,8 @@ }, "doubao": { "description": "字节跳动推出的自研大模型。通过字节跳动内部50+业务场景实践验证,每日万亿级tokens大使用量持续打磨,提供多种模态能力,以优质模型效果为企业打造丰富的业务体验。" + }, + "ppio": { + "description": "PPIO 派欧云提供稳定、高性价比的开源模型 API 服务,支持 DeepSeek 全系列、Llama、Qwen 等行业领先大模型。" } } \ No newline at end of file diff --git a/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx b/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx index 333864ec7fc37..285640743f135 100644 --- a/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +++ b/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx @@ -19,6 +19,7 @@ import { NovitaProviderCard, OpenRouterProviderCard, PerplexityProviderCard, + PPIOProviderCard, QwenProviderCard, SenseNovaProviderCard, SiliconCloudProviderCard, @@ -90,6 +91,7 @@ export const useProviderList = (): ProviderItem[] => { SiliconCloudProviderCard, HigressProviderCard, GiteeAIProviderCard, + PPIOProviderCard, ], [ AzureProvider, diff --git a/src/config/aiModels/index.ts b/src/config/aiModels/index.ts index e0d9b9654daf0..c8b739b2fd3a1 100644 --- a/src/config/aiModels/index.ts +++ b/src/config/aiModels/index.ts @@ -27,6 +27,7 @@ import { default as ollama } from './ollama'; import { default as openai } from './openai'; import { default as openrouter } from './openrouter'; import { default as perplexity } from './perplexity'; +import { default as ppio } from './ppio'; import { default as qwen } from './qwen'; import { default as sensenova } from './sensenova'; import { default as siliconcloud } from './siliconcloud'; @@ -88,6 +89,7 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({ openai, openrouter, perplexity, + ppio, qwen, sensenova, siliconcloud, @@ -130,6 +132,7 @@ export { default as ollama } from './ollama'; export { default as openai } from './openai'; export { default as openrouter } from './openrouter'; export { default as perplexity } from './perplexity'; +export { default as ppio } from './ppio'; export { default as qwen } from './qwen'; export { default as sensenova } from './sensenova'; export { default as siliconcloud } from './siliconcloud'; diff --git a/src/config/aiModels/ppio.ts b/src/config/aiModels/ppio.ts new file mode 100644 index 0000000000000..3fae831596b01 --- /dev/null +++ b/src/config/aiModels/ppio.ts @@ -0,0 +1,255 @@ +import { AIChatModelCard } from '@/types/aiModel'; + +const ppioChatModels: AIChatModelCard[] = [ + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1是DeepSeek团队发布的最新开源模型,具备非常强悍的推理性能,尤其在数学、编程和推理任务上达到了与OpenAI的o1模型相当的水平。", + "displayName": "DeepSeek: DeepSeek R1(Community)", + "enabled": true, + "id": "deepseek/deepseek-r1/community", + "pricing": { + "currency": "CNY", + "input": 4, + "output": 16 + }, + "type": "chat" + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek-V3在推理速度方面实现了比之前模型的重大突破。在开源模型中排名第一,并可与全球最先进的闭源模型相媲美。DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些架构在 DeepSeek-V2 中得到了全面验证。此外,DeepSeek-V3 开创了一种用于负载均衡的辅助无损策略,并设定了多标记预测训练目标以获得更强的性能。", + "displayName": "DeepSeek: DeepSeek V3(Community)\t", + "enabled": true, + "id": "deepseek/deepseek-v3/community", + "pricing": { + "currency": "CNY", + "input": 1, + "output": 2 + }, + "type": "chat" + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1是DeepSeek团队发布的最新开源模型,具备非常强悍的推理性能,尤其在数学、编程和推理任务上达到了与OpenAI的o1模型相当的水平。", + "displayName": "DeepSeek R1", + "enabled": true, + "id": "deepseek/deepseek-r1", + "pricing": { + "currency": "CNY", + "input": 4, + "output": 16 + }, + "type": "chat" + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek-V3在推理速度方面实现了比之前模型的重大突破。在开源模型中排名第一,并可与全球最先进的闭源模型相媲美。DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些架构在 DeepSeek-V2 中得到了全面验证。此外,DeepSeek-V3 开创了一种用于负载均衡的辅助无损策略,并设定了多标记预测训练目标以获得更强的性能。", + "displayName": "DeepSeek V3", + "enabled": true, + "id": "deepseek/deepseek-v3", + "pricing": { + "currency": "CNY", + "input": 1, + "output": 2 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_000, + "description": "DeepSeek R1 Distill Llama 70B是基于Llama3.3 70B的大型语言模型,该模型利用DeepSeek R1输出的微调,实现了与大型前沿模型相当的竞争性能。", + "displayName": "DeepSeek R1 Distill Llama 70B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-llama-70b", + "pricing": { + "currency": "CNY", + "input": 5.8, + "output": 5.8 + }, + "type": "chat" + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1 Distill Qwen 32B 是一种基于 Qwen 2.5 32B 的蒸馏大语言模型,通过使用 DeepSeek R1 的输出进行训练而得。该模型在多个基准测试中超越了 OpenAI 的 o1-mini,取得了密集模型(dense models)的最新技术领先成果(state-of-the-art)。以下是一些基准测试的结果:\nAIME 2024 pass@1: 72.6\nMATH-500 pass@1: 94.3\nCodeForces Rating: 1691\n该模型通过从 DeepSeek R1 的输出中进行微调,展现了与更大规模的前沿模型相当的竞争性能。", + "displayName": "DeepSeek: DeepSeek R1 Distill Qwen 32B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-qwen-32b", + "pricing": { + "currency": "CNY", + "input": 2.18, + "output": 2.18 + }, + "type": "chat" + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1 Distill Qwen 14B 是一种基于 Qwen 2.5 14B 的蒸馏大语言模型,通过使用 DeepSeek R1 的输出进行训练而得。该模型在多个基准测试中超越了 OpenAI 的 o1-mini,取得了密集模型(dense models)的最新技术领先成果(state-of-the-art)。以下是一些基准测试的结果:\nAIME 2024 pass@1: 69.7\nMATH-500 pass@1: 93.9\nCodeForces Rating: 1481\n该模型通过从 DeepSeek R1 的输出中进行微调,展现了与更大规模的前沿模型相当的竞争性能。", + "displayName": "DeepSeek: DeepSeek R1 Distill Qwen 14B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-qwen-14b", + "pricing": { + "currency": "CNY", + "input": 1, + "output": 1 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_000, + "description": "DeepSeek R1 Distill Llama 8B 是一种基于 Llama-3.1-8B-Instruct 的蒸馏大语言模型,通过使用 DeepSeek R1 的输出进行训练而得。", + "displayName": "DeepSeek: DeepSeek R1 Distill Llama 8B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-llama-8b", + "pricing": { + "currency": "CNY", + "input": 0.3, + "output": 0.3 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "Qwen2.5-72B-Instruct 是阿里云发布的最新大语言模型系列之一。该 72B 模型在编码和数学等领域具有显著改进的能力。该模型还提供了多语言支持,覆盖超过 29 种语言,包括中文、英文等。模型在指令跟随、理解结构化数据以及生成结构化输出(尤其是 JSON)方面都有显著提升。", + "displayName": "qwen/qwen-2.5-72b-instruct", + "enabled": true, + "id": "qwen/qwen-2.5-72b-instruct", + "pricing": { + "currency": "CNY", + "input": 2.75, + "output": 2.88 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "Qwen2-VL 是 Qwen-VL 模型的最新迭代版本,在视觉理解基准测试中达到了最先进的性能,包括 MathVista、DocVQA、RealWorldQA 和 MTVQA 等。Qwen2-VL 能够理解超过 20 分钟的视频,用于高质量的基于视频的问答、对话和内容创作。它还具备复杂推理和决策能力,可以与移动设备、机器人等集成,基于视觉环境和文本指令进行自动操作。除了英语和中文,Qwen2-VL 现在还支持理解图像中不同语言的文本,包括大多数欧洲语言、日语、韩语、阿拉伯语和越南语等", + "displayName": "qwen/qwen-2-vl-72b-instruct", + "enabled": true, + "id": "qwen/qwen-2-vl-72b-instruct", + "pricing": { + "currency": "CNY", + "input": 4.5, + "output": 4.5 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "meta-llama/llama-3.2-3b-instruct", + "displayName": "meta-llama/llama-3.2-3b-instruct", + "enabled": true, + "id": "meta-llama/llama-3.2-3b-instruct", + "pricing": { + "currency": "CNY", + "input": 0.216, + "output": 0.36 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_000, + "description": "Qwen2.5-32B-Instruct 是阿里云发布的最新大语言模型系列之一。该 32B 模型在编码和数学等领域具有显著改进的能力。该模型提供了多语言支持,覆盖超过 29 种语言,包括中文、英文等。模型在指令跟随、理解结构化数据以及生成结构化输出(尤其是 JSON)方面都有显著提升。", + "displayName": "qwen/qwen2.5-32b-instruct", + "enabled": true, + "id": "qwen/qwen2.5-32b-instruct", + "pricing": { + "currency": "CNY", + "input": 1.26, + "output": 1.26 + }, + "type": "chat" + }, + { + "contextWindowTokens": 14_336, + "description": "Baichuan-13B 百川智能开发的包含 130 亿参数的开源可商用的大规模语言模型,在权威的中文和英文 benchmark 上均取得同尺寸最好的效果", + "displayName": "baichuan/baichuan2-13b-chat", + "enabled": true, + "id": "baichuan/baichuan2-13b-chat", + "pricing": { + "currency": "CNY", + "input": 1.75, + "output": 1.75 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "Meta最新一代的Llama 3.1模型系列,70B(700亿参数)的指令微调版本针对高质量对话场景进行了优化。在业界评估中,与领先的闭源模型相比,它展现出了强劲的性能。(仅针对企业实名认证通过主体开放)", + "displayName": "meta-llama/llama-3.1-70b-instruct", + "enabled": true, + "id": "meta-llama/llama-3.1-70b-instruct", + "pricing": { + "currency": "CNY", + "input": 2.45, + "output": 2.82 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "Meta最新一代的Llama 3.1模型系列,8B(80亿参数)的指令微调版本特别快速高效。在业界评估中,表现出强劲的性能,超越了很多领先的闭源模型。(仅针对企业实名认证通过主体开放)", + "displayName": "meta-llama/llama-3.1-8b-instruct", + "enabled": true, + "id": "meta-llama/llama-3.1-8b-instruct", + "pricing": { + "currency": "CNY", + "input": 0.4, + "output": 0.4 + }, + "type": "chat" + }, + { + "contextWindowTokens": 16_384, + "description": "零一万物,最新开源微调模型,340亿参数,微调支持多种对话场景,高质量训练数据,对齐人类偏好。", + "displayName": "01-ai/yi-1.5-34b-chat", + "enabled": true, + "id": "01-ai/yi-1.5-34b-chat", + "pricing": { + "currency": "CNY", + "input": 1.1, + "output": 1.1 + }, + "type": "chat" + }, + { + "contextWindowTokens": 16_384, + "description": "零一万物,最新开源微调模型,90亿参数,微调支持多种对话场景,高质量训练数据,对齐人类偏好。", + "displayName": "01-ai/yi-1.5-9b-chat", + "enabled": true, + "id": "01-ai/yi-1.5-9b-chat", + "pricing": { + "currency": "CNY", + "input": 0.4, + "output": 0.4 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "智谱AI发布的GLM-4系列最新一代预训练模型的开源版本。", + "displayName": "thudm/glm-4-9b-chat", + "enabled": true, + "id": "thudm/glm-4-9b-chat", + "pricing": { + "currency": "CNY", + "input": 0.5, + "output": 0.5 + }, + "type": "chat" + }, + { + "contextWindowTokens": 32_768, + "description": "Qwen2是全新的Qwen大型语言模型系列。Qwen2 7B是一个基于transformer的模型,在语言理解、多语言能力、编程、数学和推理方面表现出色。", + "displayName": "qwen/qwen-2-7b-instruct", + "enabled": true, + "id": "qwen/qwen-2-7b-instruct", + "pricing": { + "currency": "CNY", + "input": 0.32, + "output": 0.32 + }, + "type": "chat" + } +] + +export const allModels = [...ppioChatModels]; + +export default allModels; \ No newline at end of file diff --git a/src/config/llm.ts b/src/config/llm.ts index f5513ff1bf300..c9b86cc11dbb7 100644 --- a/src/config/llm.ts +++ b/src/config/llm.ts @@ -128,6 +128,9 @@ export const getLLMConfig = () => { ENABLED_TENCENT_CLOUD: z.boolean(), TENCENT_CLOUD_API_KEY: z.string().optional(), + + ENABLED_PPIO: z.boolean(), + PPIO_API_KEY: z.string().optional(), }, runtimeEnv: { API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE, @@ -254,6 +257,9 @@ export const getLLMConfig = () => { ENABLED_TENCENT_CLOUD: !!process.env.TENCENT_CLOUD_API_KEY, TENCENT_CLOUD_API_KEY: process.env.TENCENT_CLOUD_API_KEY, + + ENABLED_PPIO: !!process.env.PPIO_API_KEY, + PPIO_API_KEY: process.env.PPIO_API_KEY, }, }); }; diff --git a/src/config/modelProviders/index.ts b/src/config/modelProviders/index.ts index 8f869170fb9e0..2904bf55d11ce 100644 --- a/src/config/modelProviders/index.ts +++ b/src/config/modelProviders/index.ts @@ -27,6 +27,7 @@ import OllamaProvider from './ollama'; import OpenAIProvider from './openai'; import OpenRouterProvider from './openrouter'; import PerplexityProvider from './perplexity'; +import PPIOProvider from './ppio'; import QwenProvider from './qwen'; import SenseNovaProvider from './sensenova'; import SiliconCloudProvider from './siliconcloud'; @@ -124,7 +125,8 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [ TaichuProvider, Ai360Provider, DoubaoProvider, -]; + PPIOProvider, +] as const; export const filterEnabledModels = (provider: ModelProviderCard) => { return provider.chatModels.filter((v) => v.enabled).map((m) => m.id); @@ -162,6 +164,7 @@ export { default as OllamaProviderCard } from './ollama'; export { default as OpenAIProviderCard } from './openai'; export { default as OpenRouterProviderCard } from './openrouter'; export { default as PerplexityProviderCard } from './perplexity'; +export { default as PPIOProviderCard } from './ppio'; export { default as QwenProviderCard } from './qwen'; export { default as SenseNovaProviderCard } from './sensenova'; export { default as SiliconCloudProviderCard } from './siliconcloud'; diff --git a/src/config/modelProviders/ppio.ts b/src/config/modelProviders/ppio.ts new file mode 100644 index 0000000000000..dc0f2300020c6 --- /dev/null +++ b/src/config/modelProviders/ppio.ts @@ -0,0 +1,242 @@ +import { ModelProviderCard } from '@/types/llm'; + +const PPIO: ModelProviderCard = { + chatModels: [ + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1是DeepSeek团队发布的最新开源模型,具备非常强悍的推理性能,尤其在数学、编程和推理任务上达到了与OpenAI的o1模型相当的水平。", + "displayName": "DeepSeek: DeepSeek R1(Community)", + "enabled": true, + "id": "deepseek/deepseek-r1/community", + "pricing": { + "currency": "CNY", + "input": 4, + "output": 16 + } + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek-V3在推理速度方面实现了比之前模型的重大突破。在开源模型中排名第一,并可与全球最先进的闭源模型相媲美。DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些架构在 DeepSeek-V2 中得到了全面验证。此外,DeepSeek-V3 开创了一种用于负载均衡的辅助无损策略,并设定了多标记预测训练目标以获得更强的性能。", + "displayName": "DeepSeek: DeepSeek V3(Community)\t", + "enabled": true, + "id": "deepseek/deepseek-v3/community", + "pricing": { + "currency": "CNY", + "input": 1, + "output": 2 + } + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1是DeepSeek团队发布的最新开源模型,具备非常强悍的推理性能,尤其在数学、编程和推理任务上达到了与OpenAI的o1模型相当的水平。", + "displayName": "DeepSeek R1", + "enabled": true, + "id": "deepseek/deepseek-r1", + "pricing": { + "currency": "CNY", + "input": 4, + "output": 16 + } + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek-V3在推理速度方面实现了比之前模型的重大突破。在开源模型中排名第一,并可与全球最先进的闭源模型相媲美。DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些架构在 DeepSeek-V2 中得到了全面验证。此外,DeepSeek-V3 开创了一种用于负载均衡的辅助无损策略,并设定了多标记预测训练目标以获得更强的性能。", + "displayName": "DeepSeek V3", + "enabled": true, + "id": "deepseek/deepseek-v3", + "pricing": { + "currency": "CNY", + "input": 1, + "output": 2 + } + }, + { + "contextWindowTokens": 32_000, + "description": "DeepSeek R1 Distill Llama 70B是基于Llama3.3 70B的大型语言模型,该模型利用DeepSeek R1输出的微调,实现了与大型前沿模型相当的竞争性能。", + "displayName": "DeepSeek R1 Distill Llama 70B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-llama-70b", + "pricing": { + "currency": "CNY", + "input": 5.8, + "output": 5.8 + } + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1 Distill Qwen 32B 是一种基于 Qwen 2.5 32B 的蒸馏大语言模型,通过使用 DeepSeek R1 的输出进行训练而得。该模型在多个基准测试中超越了 OpenAI 的 o1-mini,取得了密集模型(dense models)的最新技术领先成果(state-of-the-art)。以下是一些基准测试的结果:\nAIME 2024 pass@1: 72.6\nMATH-500 pass@1: 94.3\nCodeForces Rating: 1691\n该模型通过从 DeepSeek R1 的输出中进行微调,展现了与更大规模的前沿模型相当的竞争性能。", + "displayName": "DeepSeek: DeepSeek R1 Distill Qwen 32B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-qwen-32b", + "pricing": { + "currency": "CNY", + "input": 2.18, + "output": 2.18 + } + }, + { + "contextWindowTokens": 64_000, + "description": "DeepSeek R1 Distill Qwen 14B 是一种基于 Qwen 2.5 14B 的蒸馏大语言模型,通过使用 DeepSeek R1 的输出进行训练而得。该模型在多个基准测试中超越了 OpenAI 的 o1-mini,取得了密集模型(dense models)的最新技术领先成果(state-of-the-art)。以下是一些基准测试的结果:\nAIME 2024 pass@1: 69.7\nMATH-500 pass@1: 93.9\nCodeForces Rating: 1481\n该模型通过从 DeepSeek R1 的输出中进行微调,展现了与更大规模的前沿模型相当的竞争性能。", + "displayName": "DeepSeek: DeepSeek R1 Distill Qwen 14B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-qwen-14b", + "pricing": { + "currency": "CNY", + "input": 1, + "output": 1 + } + }, + { + "contextWindowTokens": 32_000, + "description": "DeepSeek R1 Distill Llama 8B 是一种基于 Llama-3.1-8B-Instruct 的蒸馏大语言模型,通过使用 DeepSeek R1 的输出进行训练而得。", + "displayName": "DeepSeek: DeepSeek R1 Distill Llama 8B", + "enabled": true, + "id": "deepseek/deepseek-r1-distill-llama-8b", + "pricing": { + "currency": "CNY", + "input": 0.3, + "output": 0.3 + } + }, + { + "contextWindowTokens": 32_768, + "description": "Qwen2.5-72B-Instruct 是阿里云发布的最新大语言模型系列之一。该 72B 模型在编码和数学等领域具有显著改进的能力。该模型还提供了多语言支持,覆盖超过 29 种语言,包括中文、英文等。模型在指令跟随、理解结构化数据以及生成结构化输出(尤其是 JSON)方面都有显著提升。", + "displayName": "qwen/qwen-2.5-72b-instruct", + "enabled": true, + "id": "qwen/qwen-2.5-72b-instruct", + "pricing": { + "currency": "CNY", + "input": 2.75, + "output": 2.88 + } + }, + { + "contextWindowTokens": 32_768, + "description": "Qwen2-VL 是 Qwen-VL 模型的最新迭代版本,在视觉理解基准测试中达到了最先进的性能,包括 MathVista、DocVQA、RealWorldQA 和 MTVQA 等。Qwen2-VL 能够理解超过 20 分钟的视频,用于高质量的基于视频的问答、对话和内容创作。它还具备复杂推理和决策能力,可以与移动设备、机器人等集成,基于视觉环境和文本指令进行自动操作。除了英语和中文,Qwen2-VL 现在还支持理解图像中不同语言的文本,包括大多数欧洲语言、日语、韩语、阿拉伯语和越南语等", + "displayName": "qwen/qwen-2-vl-72b-instruct", + "enabled": true, + "id": "qwen/qwen-2-vl-72b-instruct", + "pricing": { + "currency": "CNY", + "input": 4.5, + "output": 4.5 + } + }, + { + "contextWindowTokens": 32_768, + "description": "meta-llama/llama-3.2-3b-instruct", + "displayName": "meta-llama/llama-3.2-3b-instruct", + "enabled": true, + "id": "meta-llama/llama-3.2-3b-instruct", + "pricing": { + "currency": "CNY", + "input": 0.216, + "output": 0.36 + } + }, + { + "contextWindowTokens": 32_000, + "description": "Qwen2.5-32B-Instruct 是阿里云发布的最新大语言模型系列之一。该 32B 模型在编码和数学等领域具有显著改进的能力。该模型提供了多语言支持,覆盖超过 29 种语言,包括中文、英文等。模型在指令跟随、理解结构化数据以及生成结构化输出(尤其是 JSON)方面都有显著提升。", + "displayName": "qwen/qwen2.5-32b-instruct", + "enabled": true, + "id": "qwen/qwen2.5-32b-instruct", + "pricing": { + "currency": "CNY", + "input": 1.26, + "output": 1.26 + } + }, + { + "contextWindowTokens": 14_336, + "description": "Baichuan-13B 百川智能开发的包含 130 亿参数的开源可商用的大规模语言模型,在权威的中文和英文 benchmark 上均取得同尺寸最好的效果", + "displayName": "baichuan/baichuan2-13b-chat", + "enabled": true, + "id": "baichuan/baichuan2-13b-chat", + "pricing": { + "currency": "CNY", + "input": 1.75, + "output": 1.75 + } + }, + { + "contextWindowTokens": 32_768, + "description": "Meta最新一代的Llama 3.1模型系列,70B(700亿参数)的指令微调版本针对高质量对话场景进行了优化。在业界评估中,与领先的闭源模型相比,它展现出了强劲的性能。(仅针对企业实名认证通过主体开放)", + "displayName": "meta-llama/llama-3.1-70b-instruct", + "enabled": true, + "id": "meta-llama/llama-3.1-70b-instruct", + "pricing": { + "currency": "CNY", + "input": 2.45, + "output": 2.82 + } + }, + { + "contextWindowTokens": 32_768, + "description": "Meta最新一代的Llama 3.1模型系列,8B(80亿参数)的指令微调版本特别快速高效。在业界评估中,表现出强劲的性能,超越了很多领先的闭源模型。(仅针对企业实名认证通过主体开放)", + "displayName": "meta-llama/llama-3.1-8b-instruct", + "enabled": true, + "id": "meta-llama/llama-3.1-8b-instruct", + "pricing": { + "currency": "CNY", + "input": 0.4, + "output": 0.4 + } + }, + { + "contextWindowTokens": 16_384, + "description": "零一万物,最新开源微调模型,340亿参数,微调支持多种对话场景,高质量训练数据,对齐人类偏好。", + "displayName": "01-ai/yi-1.5-34b-chat", + "enabled": true, + "id": "01-ai/yi-1.5-34b-chat", + "pricing": { + "currency": "CNY", + "input": 1.1, + "output": 1.1 + } + }, + { + "contextWindowTokens": 16_384, + "description": "零一万物,最新开源微调模型,90亿参数,微调支持多种对话场景,高质量训练数据,对齐人类偏好。", + "displayName": "01-ai/yi-1.5-9b-chat", + "enabled": true, + "id": "01-ai/yi-1.5-9b-chat", + "pricing": { + "currency": "CNY", + "input": 0.4, + "output": 0.4 + } + }, + { + "contextWindowTokens": 32_768, + "description": "智谱AI发布的GLM-4系列最新一代预训练模型的开源版本。", + "displayName": "thudm/glm-4-9b-chat", + "enabled": true, + "id": "thudm/glm-4-9b-chat", + "pricing": { + "currency": "CNY", + "input": 0.5, + "output": 0.5 + } + }, + { + "contextWindowTokens": 32_768, + "description": "Qwen2是全新的Qwen大型语言模型系列。Qwen2 7B是一个基于transformer的模型,在语言理解、多语言能力、编程、数学和推理方面表现出色。", + "displayName": "qwen/qwen-2-7b-instruct", + "enabled": true, + "id": "qwen/qwen-2-7b-instruct", + "pricing": { + "currency": "CNY", + "input": 0.32, + "output": 0.32 + } + } + ], // Will be updated with model list + disableBrowserRequest: true, + id: 'ppio', + modelList: { showModelFetcher: true }, + name: 'PPIO', + settings: {}, + url: 'https://ppinfra.com/?utm_source=github_lobe-chat&utm_medium=github_readme&utm_campaign=link', +}; + +export default PPIO; \ No newline at end of file diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index 7bef8a26f5f1c..53d21ac531d72 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -30,6 +30,7 @@ import { LobeOllamaAI } from './ollama'; import { LobeOpenAI } from './openai'; import { LobeOpenRouterAI } from './openrouter'; import { LobePerplexityAI } from './perplexity'; +import { LobePPIOAI } from './ppio'; import { LobeQwenAI } from './qwen'; import { LobeSenseNovaAI } from './sensenova'; import { LobeSiliconCloudAI } from './siliconcloud'; @@ -161,6 +162,7 @@ class AgentRuntime { openai: Partial; openrouter: Partial; perplexity: Partial; + ppio: Partial; qwen: Partial; sensenova: Partial; siliconcloud: Partial; @@ -384,6 +386,11 @@ class AgentRuntime { runtimeModel = new LobeWenxinAI(params.wenxin); break; } + + case ModelProvider.PPIO: { + runtimeModel = new LobePPIOAI(params.ppio ?? {}); + break; + } } return new AgentRuntime(runtimeModel); } diff --git a/src/libs/agent-runtime/ppio/__snapshots__/index.test.ts.snap b/src/libs/agent-runtime/ppio/__snapshots__/index.test.ts.snap new file mode 100644 index 0000000000000..40cbd426448a5 --- /dev/null +++ b/src/libs/agent-runtime/ppio/__snapshots__/index.test.ts.snap @@ -0,0 +1,26 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`PPIO > models > should get models 1`] = ` +[ + { + "contextWindowTokens": 64000, + "description": "DeepSeek R1是DeepSeek团队发布的最新开源模型,具备非常强悍的推理性能,尤其在数学、编程和推理任务上达到了与OpenAI的o1模型相当的水平。", + "displayName": "DeepSeek: DeepSeek R1(Community)", + "enabled": true, + "functionCall": false, + "id": "deepseek/deepseek-r1/community", + "reasoning": true, + "vision": false, + }, + { + "contextWindowTokens": 64000, + "description": "DeepSeek-V3在推理速度方面实现了比之前模型的重大突破。在开源模型中排名第一,并可与全球最先进的闭源模型相媲美。DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些架构在 DeepSeek-V2 中得到了全面验证。此外,DeepSeek-V3 开创了一种用于负载均衡的辅助无损策略,并设定了多标记预测训练目标以获得更强的性能。", + "displayName": "DeepSeek: DeepSeek V3(Community)", + "enabled": true, + "functionCall": false, + "id": "deepseek/deepseek-v3/community", + "reasoning": false, + "vision": false, + }, +] +`; diff --git a/src/libs/agent-runtime/ppio/fixtures/models.json b/src/libs/agent-runtime/ppio/fixtures/models.json new file mode 100644 index 0000000000000..964a70c3620a2 --- /dev/null +++ b/src/libs/agent-runtime/ppio/fixtures/models.json @@ -0,0 +1,42 @@ +[ + { + "created": 1738928740, + "id": "deepseek/deepseek-r1/community", + "object": "model", + "owned_by": "unknown", + "permission": null, + "root": "", + "parent": "", + "input_token_price_per_m": 40000, + "output_token_price_per_m": 160000, + "title": "deepseek/deepseek-r1/community", + "description": "DeepSeek R1是DeepSeek团队发布的最新开源模型,具备非常强悍的推理性能,尤其在数学、编程和推理任务上达到了与OpenAI的o1模型相当的水平。", + "tags": [ + "全参数", + "满血版" + ], + "context_size": 64000, + "status": 1, + "display_name": "DeepSeek: DeepSeek R1(Community)" + }, + { + "created": 1738928844, + "id": "deepseek/deepseek-v3/community", + "object": "model", + "owned_by": "unknown", + "permission": null, + "root": "", + "parent": "", + "input_token_price_per_m": 10000, + "output_token_price_per_m": 20000, + "title": "deepseek/deepseek-v3/community", + "description": "DeepSeek-V3在推理速度方面实现了比之前模型的重大突破。在开源模型中排名第一,并可与全球最先进的闭源模型相媲美。DeepSeek-V3 采用了多头潜在注意力 (MLA) 和 DeepSeekMoE 架构,这些架构在 DeepSeek-V2 中得到了全面验证。此外,DeepSeek-V3 开创了一种用于负载均衡的辅助无损策略,并设定了多标记预测训练目标以获得更强的性能。", + "tags": [ + "全参数", + "满血版" + ], + "context_size": 64000, + "status": 1, + "display_name": "DeepSeek: DeepSeek V3(Community)" + } +] \ No newline at end of file diff --git a/src/libs/agent-runtime/ppio/index.test.ts b/src/libs/agent-runtime/ppio/index.test.ts new file mode 100644 index 0000000000000..8e1233cb0195f --- /dev/null +++ b/src/libs/agent-runtime/ppio/index.test.ts @@ -0,0 +1,264 @@ + // @vitest-environment node +import OpenAI from 'openai'; +import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { LobeOpenAICompatibleRuntime } from '@/libs/agent-runtime'; +import { ModelProvider } from '@/libs/agent-runtime'; +import { AgentRuntimeErrorType } from '@/libs/agent-runtime'; + +import * as debugStreamModule from '../utils/debugStream'; +import models from './fixtures/models.json'; +import { LobePPIOAI } from './index'; + +const provider = ModelProvider.PPIO; +const defaultBaseURL = 'https://api.ppinfra.com/v3/openai'; +const bizErrorType = AgentRuntimeErrorType.ProviderBizError; +const invalidErrorType = AgentRuntimeErrorType.InvalidProviderAPIKey; + +// Mock the console.error to avoid polluting test output +vi.spyOn(console, 'error').mockImplementation(() => {}); + +let instance: LobeOpenAICompatibleRuntime; + +beforeEach(() => { + instance = new LobePPIOAI({ apiKey: 'test' }); + + // 使用 vi.spyOn 来模拟 chat.completions.create 方法 + vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue( + new ReadableStream() as any, + ); + vi.spyOn(instance['client'].models, 'list').mockResolvedValue({ data: [] } as any); +}); + +afterEach(() => { + vi.clearAllMocks(); +}); + +describe('PPIO', () => { + describe('init', () => { + it('should correctly initialize with an API key', async () => { + const instance = new LobePPIOAI({ apiKey: 'test_api_key' }); + expect(instance).toBeInstanceOf(LobePPIOAI); + expect(instance.baseURL).toEqual(defaultBaseURL); + }); + }); + + describe('chat', () => { + describe('Error', () => { + it('should return Error with an openai error response when OpenAI.APIError is thrown', async () => { + // Arrange + const apiError = new OpenAI.APIError( + 400, + { + status: 400, + error: { + message: 'Bad Request', + }, + }, + 'Error message', + {}, + ); + + vi.spyOn(instance['client'].chat.completions, 'create').mockRejectedValue(apiError); + + // Act + try { + await instance.chat({ + messages: [{ content: 'Hello', role: 'user' }], + model: 'meta-llama/llama-3-8b-instruct', + temperature: 0.999, + }); + } catch (e) { + expect(e).toEqual({ + endpoint: defaultBaseURL, + error: { + error: { message: 'Bad Request' }, + status: 400, + }, + errorType: bizErrorType, + provider, + }); + } + }); + + it('should throw AgentRuntimeError if no apiKey is provided', async () => { + try { + new LobePPIOAI({}); + } catch (e) { + expect(e).toEqual({ errorType: invalidErrorType }); + } + }); + + it('should return Error with the cause when OpenAI.APIError is thrown with cause', async () => { + // Arrange + const errorInfo = { + stack: 'abc', + cause: { + message: 'api is undefined', + }, + }; + const apiError = new OpenAI.APIError(400, errorInfo, 'module error', {}); + + vi.spyOn(instance['client'].chat.completions, 'create').mockRejectedValue(apiError); + + // Act + try { + await instance.chat({ + messages: [{ content: 'Hello', role: 'user' }], + model: 'meta-llama/llama-3-8b-instruct', + temperature: 0.999, + }); + } catch (e) { + expect(e).toEqual({ + endpoint: defaultBaseURL, + error: { + cause: { message: 'api is undefined' }, + stack: 'abc', + }, + errorType: bizErrorType, + provider, + }); + } + }); + + it('should return Error with an cause response with desensitize Url', async () => { + // Arrange + const errorInfo = { + stack: 'abc', + cause: { message: 'api is undefined' }, + }; + const apiError = new OpenAI.APIError(400, errorInfo, 'module error', {}); + + instance = new LobePPIOAI({ + apiKey: 'test', + + baseURL: 'https://api.abc.com/v1', + }); + + vi.spyOn(instance['client'].chat.completions, 'create').mockRejectedValue(apiError); + + // Act + try { + await instance.chat({ + messages: [{ content: 'Hello', role: 'user' }], + model: 'meta-llama/llama-3-8b-instruct', + temperature: 0.999, + }); + } catch (e) { + expect(e).toEqual({ + endpoint: 'https://api.***.com/v1', + error: { + cause: { message: 'api is undefined' }, + stack: 'abc', + }, + errorType: bizErrorType, + provider, + }); + } + }); + + it('should throw an error type on 401 status code', async () => { + // Mock the API call to simulate a 401 error + const error = new Error('InvalidApiKey') as any; + error.status = 401; + vi.mocked(instance['client'].chat.completions.create).mockRejectedValue(error); + + try { + await instance.chat({ + messages: [{ content: 'Hello', role: 'user' }], + model: 'meta-llama/llama-3-8b-instruct', + temperature: 0.999, + }); + } catch (e) { + expect(e).toEqual({ + endpoint: defaultBaseURL, + error: new Error('InvalidApiKey'), + errorType: invalidErrorType, + provider, + }); + } + }); + + it('should return AgentRuntimeError for non-OpenAI errors', async () => { + // Arrange + const genericError = new Error('Generic Error'); + + vi.spyOn(instance['client'].chat.completions, 'create').mockRejectedValue(genericError); + + // Act + try { + await instance.chat({ + messages: [{ content: 'Hello', role: 'user' }], + model: 'meta-llama/llama-3-8b-instruct', + temperature: 0.999, + }); + } catch (e) { + expect(e).toEqual({ + endpoint: defaultBaseURL, + errorType: 'AgentRuntimeError', + provider, + error: { + name: genericError.name, + cause: genericError.cause, + message: genericError.message, + stack: genericError.stack, + }, + }); + } + }); + }); + + describe('DEBUG', () => { + it('should call debugStream and return StreamingTextResponse when DEBUG_PPIO_CHAT_COMPLETION is 1', async () => { + // Arrange + const mockProdStream = new ReadableStream() as any; // 模拟的 prod 流 + const mockDebugStream = new ReadableStream({ + start(controller) { + controller.enqueue('Debug stream content'); + controller.close(); + }, + }) as any; + mockDebugStream.toReadableStream = () => mockDebugStream; // 添加 toReadableStream 方法 + + // 模拟 chat.completions.create 返回值,包括模拟的 tee 方法 + (instance['client'].chat.completions.create as Mock).mockResolvedValue({ + tee: () => [mockProdStream, { toReadableStream: () => mockDebugStream }], + }); + + // 保存原始环境变量值 + const originalDebugValue = process.env.DEBUG_PPIO_CHAT_COMPLETION; + + // 模拟环境变量 + process.env.DEBUG_PPIO_CHAT_COMPLETION = '1'; + vi.spyOn(debugStreamModule, 'debugStream').mockImplementation(() => Promise.resolve()); + + // 执行测试 + // 运行你的测试函数,确保它会在条件满足时调用 debugStream + // 假设的测试函数调用,你可能需要根据实际情况调整 + await instance.chat({ + messages: [{ content: 'Hello', role: 'user' }], + model: 'meta-llama/llama-3-8b-instruct', + stream: true, + temperature: 0.999, + }); + + // 验证 debugStream 被调用 + expect(debugStreamModule.debugStream).toHaveBeenCalled(); + + // 恢复原始环境变量值 + process.env.DEBUG_PPIO_CHAT_COMPLETION = originalDebugValue; + }); + }); + }); + + describe('models', () => { + it('should get models', async () => { + // mock the models.list method + (instance['client'].models.list as Mock).mockResolvedValue({ data: models }); + + const list = await instance.models(); + + expect(list).toMatchSnapshot(); + }); + }); +}); diff --git a/src/libs/agent-runtime/ppio/index.ts b/src/libs/agent-runtime/ppio/index.ts new file mode 100644 index 0000000000000..3e307a13b5929 --- /dev/null +++ b/src/libs/agent-runtime/ppio/index.ts @@ -0,0 +1,38 @@ +import { ModelProvider } from '../types'; +import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; +import { PPIOModelCard } from './type'; + +import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; + +export const LobePPIOAI = LobeOpenAICompatibleFactory({ + baseURL: 'https://api.ppinfra.com/v3/openai', + constructorOptions: { + defaultHeaders: { + 'X-API-Source': 'lobechat', + }, + }, + debug: { + chatCompletion: () => process.env.DEBUG_PPIO_CHAT_COMPLETION === '1', + }, + models: { + transformModel: (m) => { + const reasoningKeywords = [ + 'deepseek-r1', + ]; + + const model = m as unknown as PPIOModelCard; + + return { + contextWindowTokens: model.context_size, + description: model.description, + displayName: model.display_name || model.title || model.id, + enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, + functionCall: model.description.toLowerCase().includes('function calling'), + id: model.id, + reasoning: model.description.toLowerCase().includes('reasoning task') || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + vision: model.description.toLowerCase().includes('视觉'), + }; + }, + }, + provider: ModelProvider.PPIO, +}); diff --git a/src/libs/agent-runtime/ppio/type.ts b/src/libs/agent-runtime/ppio/type.ts new file mode 100644 index 0000000000000..c3704ac026473 --- /dev/null +++ b/src/libs/agent-runtime/ppio/type.ts @@ -0,0 +1,12 @@ +export interface PPIOModelCard { + context_size: number; + created: number; + description: string; + display_name: string; + id: string; + input_token_price_per_m: number; + output_token_price_per_m: number; + status: number; + tags: string[]; + title: string; +} diff --git a/src/libs/agent-runtime/types/type.ts b/src/libs/agent-runtime/types/type.ts index e772d2e16289a..b1717125094a6 100644 --- a/src/libs/agent-runtime/types/type.ts +++ b/src/libs/agent-runtime/types/type.ts @@ -48,6 +48,7 @@ export enum ModelProvider { Ollama = 'ollama', OpenAI = 'openai', OpenRouter = 'openrouter', + PPIO = 'ppio', Perplexity = 'perplexity', Qwen = 'qwen', SenseNova = 'sensenova', diff --git a/src/types/user/settings/keyVaults.ts b/src/types/user/settings/keyVaults.ts index 3fb2a200f260b..67c6c66c455c2 100644 --- a/src/types/user/settings/keyVaults.ts +++ b/src/types/user/settings/keyVaults.ts @@ -55,6 +55,7 @@ export interface UserKeyVaults { openrouter?: OpenAICompatibleKeyVault; password?: string; perplexity?: OpenAICompatibleKeyVault; + ppio?: OpenAICompatibleKeyVault; qwen?: OpenAICompatibleKeyVault; sensenova?: OpenAICompatibleKeyVault; siliconcloud?: OpenAICompatibleKeyVault;