feat: add FennoAI and Qiniu Cloud AI provider presets

- Add both gateways as featured presets pointing at their Anthropic-compatible
  roots (https://api.fenno.ai, https://api.qnaigc.com) with auth_token strategy
- Ship no default model ids: the available catalog depends on the plan the user
  bought, so they fetch the live list and pick one instead
- Keep modelContextWindows, which stays useful per picked model id and covers
  ids the built-in table cannot resolve (claude-opus-5, namespaced 七牛云 ids)
- Add both as sponsors in the English and Chinese READMEs, and list them in the
  preset docs
This commit is contained in:
程序员阿江(Relakkes)
2026-08-04 16:46:30 +08:00
parent 62f648cb24
commit 0a9789a73c
9 changed files with 170 additions and 2 deletions
+20
View File
@@ -83,6 +83,26 @@ This project is maintained in the author's spare time. Corporate or individual s
Thanks to <a href="https://www.xuanshuapi.com/register?aff=CC-HAHA&promo=CC-HAHA">XuanShu API</a> for sponsoring this project. XuanShu API is an all-in-one, enterprise-grade AI gateway that gives you access to leading global models through a single unified API, and works out of the box with popular AI coding tools such as Claude Code, Codex, and Gemini CLI. Stability comes first: multi-account pool scheduling and automatic failover smooth out upstream account fluctuations. Model calls are priced as low as 25% of official rates, and balance top-ups get roughly a 20% bonus with no expiry. New users who register through <a href="https://www.xuanshuapi.com/register?aff=CC-HAHA&promo=CC-HAHA">this link</a> receive a $5 credit.
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://api.fenno.ai/s/WD8c">
<img src="docs/images/sponsors/fennoai-logo.svg" width="180" alt="FennoAI">
</a>
</td>
<td valign="middle">
Thanks to <a href="https://api.fenno.ai/s/WD8c">FennoAI</a> for sponsoring this project. FennoAI is a high-stability, high-performance API relay service for enterprise engineering teams and individual developers. It speaks both the OpenAI and Anthropic protocols, so it drops straight into Codex, Claude Code, OpenCode, and other mainstream AI coding tools. The platform is built for enterprise-grade stability at hundreds of billions of tokens per day, and supports corporate settlement and invoicing for both domestic and overseas entities. As a cc-haha user perk, buying a subscription through <a href="https://api.fenno.ai/s/WD8c">this link</a> gets you $50 of Coding Plan credit for $1.99. Referrals earn up to 20% commission — the more you invite, the more you get.
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://s.qiniu.com/IZbyya">
<img src="docs/images/sponsors/qiniuai-logo.svg" width="180" alt="Qiniu Cloud AI">
</a>
</td>
<td valign="middle">
Thanks to <a href="https://s.qiniu.com/IZbyya">Qiniu Cloud AI</a> for sponsoring this project. Qiniu Cloud AI is the enterprise-grade LLM MaaS platform from Qiniu Cloud (02567.HK): one entry point to 150+ leading models worldwide, compatible with the major vendors' protocols, covering text, image, audio, video, and file processing across every modality, and serving more than 1.69 million enterprises and developers. As a cc-haha user perk, registering through <a href="https://s.qiniu.com/IZbyya">this link</a> gets enterprise users 12M free tokens and developers 3M free tokens.
</td>
</tr>
</tbody>
</table>
+20
View File
@@ -83,6 +83,26 @@ Claude Code Haha 是一个**桌面端 Claude Code 工作台**:把会话、多
感谢 <a href="https://www.xuanshuapi.com/register?aff=CC-HAHA&promo=CC-HAHA">玄枢API</a> 赞助本项目!玄枢API 是一站式企业级 AI 网关,通过一个统一 API 即可接入 Claude Code、Codex、Gemini CLI 等热门 AI 编程工具,调用全球顶尖模型。平台以稳定为前提,通过多账号池调度与自动故障切换屏蔽上游账号波动;模型调用低至官方定价 2.5 折,余额充值再享约 8 折优惠且不设有效期。新用户通过 <a href="https://www.xuanshuapi.com/register?aff=CC-HAHA&promo=CC-HAHA">专属链接</a> 注册即赠 5 美元额度。
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://api.fenno.ai/s/WD8c">
<img src="docs/images/sponsors/fennoai-logo.svg" width="180" alt="FennoAI">
</a>
</td>
<td valign="middle">
感谢 <a href="https://api.fenno.ai/s/WD8c">FennoAI</a> 赞助本项目!FennoAI 是一家面向企业研发团队和开发者的高稳定、高性能 API 中转服务商,兼容 OpenAI 与 Anthropic 协议,可无缝接入 Codex、Claude Code、OpenCode 等主流 AI 编程工具。平台具备企业级稳定性,可支撑千亿 Token/日的调用规模,并支持境内外主体公对公结算及开票,满足企业级研发与采购需求。作为 cc-haha 用户专属福利,通过 <a href="https://api.fenno.ai/s/WD8c">专属链接</a> 购买订阅,仅需 1.99 美元即可获得价值 50 美元的 Coding Plan 额度;同时支持邀请奖励,邀请好友购买最高可获得 20% 返佣,邀请越多,奖励越高。
</td>
</tr>
<tr>
<td align="center" valign="middle">
<a href="https://s.qiniu.com/IZbyya">
<img src="docs/images/sponsors/qiniuai-logo.svg" width="180" alt="七牛云 AI">
</a>
</td>
<td valign="middle">
感谢 <a href="https://s.qiniu.com/IZbyya">七牛云 AI</a> 赞助本项目!七牛云 AI 是七牛云(02567.HK)旗下企业级大模型 MaaS 平台,一站式调用全球 150+ 主流模型,兼容全球主流模型厂商协议,覆盖文本、图像、音频、视频、文件处理等全模态处理能力,服务超过 169 万企业及开发者用户。作为 cc-haha 用户专属福利,通过 <a href="https://s.qiniu.com/IZbyya">专属链接</a> 注册,企业用户免费领 1200 万 Token,开发者免费领 300 万 Token。
</td>
</tr>
</tbody>
</table>
@@ -90,9 +90,32 @@ describe('bundled provider presets', () => {
expect(selectableIds).not.toContain('shengsuanyun')
expect(selectableIds).toContain('teamorouter')
expect(selectableIds).toContain('xuanshuapi')
expect(selectableIds).toContain('fennoai')
expect(selectableIds).toContain('qiniuai')
expect(selectableIds).toContain('custom')
})
// Both gateways mount the Anthropic protocol on the bare host; a /v1 or
// /anthropic suffix here would double up with the path Claude Code appends.
it('points the sponsored gateways at their Anthropic-compatible roots', () => {
const fennoai = BUNDLED_PROVIDER_PRESETS.find((preset) => preset.id === 'fennoai')
const qiniuai = BUNDLED_PROVIDER_PRESETS.find((preset) => preset.id === 'qiniuai')
expect(fennoai?.baseUrl).toBe('https://api.fenno.ai')
expect(fennoai && presetMatchesBaseUrl(fennoai, ' HTTPS://API.Fenno.AI/ ')).toBe(true)
expect(qiniuai?.baseUrl).toBe('https://api.qnaigc.com')
expect(qiniuai && presetMatchesBaseUrl(qiniuai, ' HTTPS://API.QNAIGC.COM/ ')).toBe(true)
})
// The picker groups featured presets into their own row; losing the flag would
// silently demote the sponsors into the generic list.
it('keeps the sponsored gateways in the featured row', () => {
const featuredIds = BUNDLED_PROVIDER_PRESETS.filter((preset) => preset.featured).map((p) => p.id)
expect(featuredIds).toContain('fennoai')
expect(featuredIds).toContain('qiniuai')
})
it('keeps the retired 接口AI preset resolvable but not selectable', () => {
const jiekouai = BUNDLED_PROVIDER_PRESETS.find((preset) => preset.id === 'jiekouai')
+4 -1
View File
@@ -44,10 +44,13 @@ With an API key in hand, this is the fastest route. Click "Add Provider", pick s
The built-in presets, as they appear in the dialog:
- **DeepSeek** · **Zhipu GLM** · **Kimi** · **MiniMax** — major Chinese model vendors; the base URLs point at each one's Anthropic-compatible endpoint.
- **TeamoRouter** · **XuanShu API** — routing services that give you access to official Claude models through their own gateways.
- **TeamoRouter** · **XuanShu API** · **FennoAI** — routing services that give you access to official Claude models through their own gateways.
- **Qiniu Cloud AI** — an aggregator MaaS platform: one key for DeepSeek, GLM, Kimi, Qwen, and more.
- **LM Studio** · **Ollama** — local models; see the next section.
- **Custom** — anything not listed above.
Which models FennoAI and Qiniu Cloud AI give you depends on the plan you bought, so those two presets fill in the base URL only and pin no models: paste your key, hit "Fetch models", and pick one from the live list.
When a preset has a signup page for API keys, a "Get API Key" button appears under the key field.
## Local models
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

+4 -1
View File
@@ -44,10 +44,13 @@ Claude Code Haha 自己不带模型,它只是那个替你干活的壳。装完
内置预设(按弹窗里的排列):
- **DeepSeek** · **Zhipu GLM** · **Kimi** · **MiniMax** — 国内主流模型厂商,接口地址是各家的 Anthropic 兼容端点。
- **TeamoRouter** · **玄枢API** — 中转类服务商,用它们的通道调 Claude 官方模型。
- **TeamoRouter** · **玄枢API** · **FennoAI** — 中转类服务商,用它们的通道调 Claude 官方模型。
- **七牛云 AI** — 聚合类 MaaS 平台,一个密钥调 DeepSeek、GLM、Kimi、通义等多家模型。
- **LM Studio** · **Ollama** — 本地模型,见下一节。
- **Custom** — 上面都没有,自己填。
FennoAI 和七牛云 AI 能用哪些模型取决于你买的套餐,所以这两个预设只填接口地址、不预填模型:粘好密钥后点「拉取模型」,从实时列表里挑一个即可。
选中预设后,如果这家服务商有申请密钥的页面,密钥输入框下面会出现一颗「获取 API Key」按钮,点开就是注册/取密钥的地址。
## 本地模型
@@ -70,6 +70,8 @@ describe('provider presets API', () => {
const shengsuanyun = PROVIDER_PRESETS.find((preset) => preset.id === 'shengsuanyun')
const teamorouter = PROVIDER_PRESETS.find((preset) => preset.id === 'teamorouter')
const xuanshuapi = PROVIDER_PRESETS.find((preset) => preset.id === 'xuanshuapi')
const fennoai = PROVIDER_PRESETS.find((preset) => preset.id === 'fennoai')
const qiniuai = PROVIDER_PRESETS.find((preset) => preset.id === 'qiniuai')
expect(lmstudio?.baseUrl).toBe('http://localhost:1234')
expect(lmstudio?.apiFormat).toBe('anthropic')
@@ -138,6 +140,27 @@ describe('provider presets API', () => {
expect(xuanshuapi?.defaultModels.sonnet).toBe('claude-sonnet-5')
expect(xuanshuapi?.defaultModels.opus).toBe('claude-opus-5')
expect(xuanshuapi?.modelContextWindows?.['claude-opus-5']).toBe(1000000)
// Both endpoints below are the Anthropic-compatible root: Claude Code appends
// /v1/messages itself, so a /v1 or /anthropic suffix here would 404.
expect(fennoai?.baseUrl).toBe('https://api.fenno.ai')
expect(fennoai?.apiFormat).toBe('anthropic')
expect(fennoai?.authStrategy).toBe('auth_token')
expect(qiniuai?.baseUrl).toBe('https://api.qnaigc.com')
expect(qiniuai?.apiFormat).toBe('anthropic')
expect(qiniuai?.authStrategy).toBe('auth_token')
// Both gateways front a catalog that shifts on their side, so the preset ships
// no model ids: the user fetches the live list and picks. Pinning a default
// here would hand out a model their plan may not even carry.
for (const preset of [fennoai, qiniuai]) {
expect(preset?.defaultModels).toEqual({ main: '', haiku: '', sonnet: '', opus: '' })
// A pinned subagent model would reintroduce exactly that guess.
expect(preset?.defaultEnv).toEqual({})
}
// The window table stays: it is keyed by model id, so it keeps paying off
// once the user picks one — including ids the built-in table cannot resolve
// (claude-opus-5, and every namespaced 七牛云 id).
expect(fennoai?.modelContextWindows?.['claude-opus-5']).toBe(1000000)
expect(qiniuai?.modelContextWindows?.['deepseek/deepseek-v4-pro']).toBe(1000000)
})
test('configured presets can expose optional API key and promo metadata', () => {
@@ -150,6 +173,8 @@ describe('provider presets API', () => {
const shengsuanyun = PROVIDER_PRESETS.find((preset) => preset.id === 'shengsuanyun')
const teamorouter = PROVIDER_PRESETS.find((preset) => preset.id === 'teamorouter')
const xuanshuapi = PROVIDER_PRESETS.find((preset) => preset.id === 'xuanshuapi')
const fennoai = PROVIDER_PRESETS.find((preset) => preset.id === 'fennoai')
const qiniuai = PROVIDER_PRESETS.find((preset) => preset.id === 'qiniuai')
const custom = PROVIDER_PRESETS.find((preset) => preset.id === 'custom')
expect(lmstudio?.needsApiKey).toBe(false)
@@ -204,6 +229,17 @@ describe('provider presets API', () => {
CLAUDE_CODE_SUBAGENT_MODEL: 'claude-sonnet-5',
})
expect(xuanshuapi?.modelContextWindows?.['claude-sonnet-5']).toBe(1000000)
expect(fennoai?.apiKeyUrl).toBe('https://api.fenno.ai/s/WD8c')
expect(fennoai?.promoText).toContain('1.99 美元')
expect(fennoai?.featured).toBe(true)
expect(fennoai?.modelContextWindows?.['claude-sonnet-5']).toBe(1000000)
expect(fennoai?.modelContextWindows?.['claude-haiku-4-5']).toBe(200000)
expect(qiniuai?.apiKeyUrl).toBe('https://s.qiniu.com/IZbyya')
expect(qiniuai?.promoText).toContain('Token')
expect(qiniuai?.featured).toBe(true)
expect(qiniuai?.modelContextWindows?.['deepseek/deepseek-v4-flash']).toBe(1000000)
expect(qiniuai?.modelContextWindows?.['z-ai/glm-5.2']).toBe(1000000)
expect(qiniuai?.modelContextWindows?.['moonshotai/kimi-k3']).toBe(262144)
expect(custom?.promoText).toBeUndefined()
expect(custom?.authStrategy).toBe('auth_token')
expect(custom?.defaultEnv).toBeUndefined()
+55
View File
@@ -236,6 +236,61 @@
"claude-haiku-4-5-20251001": 200000
}
},
{
"id": "fennoai",
"name": "FennoAI",
"baseUrl": "https://api.fenno.ai",
"apiFormat": "anthropic",
"defaultModels": {
"main": "",
"haiku": "",
"sonnet": "",
"opus": ""
},
"needsApiKey": true,
"websiteUrl": "https://api.fenno.ai",
"apiKeyUrl": "https://api.fenno.ai/s/WD8c",
"promoText": "FennoAI 为 cc-haha 的用户提供了专属福利,通过此链接购买订阅,仅需 1.99 美元即可获得价值 50 美元的 Coding Plan 额度!",
"featured": true,
"authStrategy": "auth_token",
"defaultEnv": {},
"modelContextWindows": {
"claude-opus-5": 1000000,
"claude-opus-4-8": 1000000,
"claude-sonnet-5": 1000000,
"claude-sonnet-4-6": 200000,
"claude-haiku-4-5": 200000,
"claude-haiku-4-5-20251001": 200000
}
},
{
"id": "qiniuai",
"name": "七牛云 AI",
"baseUrl": "https://api.qnaigc.com",
"apiFormat": "anthropic",
"defaultModels": {
"main": "",
"haiku": "",
"sonnet": "",
"opus": ""
},
"needsApiKey": true,
"websiteUrl": "https://www.qiniu.com/ai/models",
"apiKeyUrl": "https://s.qiniu.com/IZbyya",
"promoText": "七牛云 AI 为 cc-haha 的用户提供了专属福利,通过此链接注册,企业用户免费领 1200 万 Token,开发者免费领 300 万 Token!",
"featured": true,
"authStrategy": "auth_token",
"defaultEnv": {},
"modelContextWindows": {
"deepseek/deepseek-v4-pro": 1000000,
"deepseek/deepseek-v4-flash": 1000000,
"z-ai/glm-5.2": 1000000,
"z-ai/glm-5.1": 200000,
"moonshotai/kimi-k3": 262144,
"moonshotai/kimi-k2.7-code": 262144,
"minimax/minimax-m3": 1000000
}
},
{
"id": "lmstudio",
"name": "LM Studio",