Skip to content

Commit ab1c790

Browse files
committed
feat: add APIMart integration
Add APIMart as an OpenAI-compatible LLM provider with WebUI guidance and tests. Add the sponsor entry and remove unused sponsor logo assets.
1 parent 96800e2 commit ab1c790

13 files changed

Lines changed: 98 additions & 2 deletions

File tree

README-en.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ Thanks to [Kimi](https://platform.kimi.ai?track_id=track-f6b0a640d35c41deb03b247
6060
Thanks to <a href="https://www.ccsub.net/register?ref=VCVDAWWY">CCSub</a> for sponsoring this project! CCSub is a stable, affordable AI API relay platform — your drop-in replacement for a Claude.ai subscription. One API key gives you access to Claude Opus 4.8, Sonnet, Haiku, GPT-5, and Gemini at roughly 30% of direct API cost, with no VPN required from anywhere in the world. Compatible with Claude Code, Codex, Cursor, Cline, Continue, Windsurf, and all major AI coding tools. Register at <a href="https://www.ccsub.net/register?ref=VCVDAWWY">www.ccsub.net</a> and get $5 free credit on sign-up.
6161
</td>
6262
</tr>
63+
<tr>
64+
<td align="center" width="120">
65+
<a href="https://go.apimart.ai/gh-moneyprinterturbo"><img src="docs/sponsors/apimart-logo.png" alt="APIMart" width="100"></a>
66+
</td>
67+
<td align="left">
68+
Thanks to <a href="https://go.apimart.ai/gh-moneyprinterturbo">APIMart</a> for sponsoring this project! APIMart is a low-cost API platform for AI image &amp; video generation — <strong>GPT-Image-2 from &#36;0.006/image, 160+ images per dollar</strong>. <strong>One async API covers both image and video—switch models without changing code.</strong> Submit a task, get an ID, and fetch results via polling or callback. Batch tens of thousands of images without timeouts. Pay-as-you-go with no monthly fee — <a href="https://go.apimart.ai/gh-moneyprinterturbo">sign up here</a> to get started.
69+
</td>
70+
</tr>
6371
<tr>
6472
<td align="center" width="120">
6573
<a href="https://infistar.cc/register?aff=6T4EYXP2&amp;ref_source=link"><img src="docs/sponsors/infistar-logo.svg" alt="Infistar.ai" height="56"></a><br>

README-ja.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@
6060
本プロジェクトをスポンサードしてくださっている <a href="https://www.ccsub.net/register?ref=VCVDAWWY">CCSub</a> に感謝します! CCSub は安定的で手頃な AI API 中継プラットフォームであり、Claude.ai のサブスクリプションをそのまま置き換えられます。API キー 1 つで Claude Opus 4.8、Sonnet、Haiku、GPT-5、Gemini を直接 API のおよそ 30% のコストで利用でき、世界中どこからでも VPN は不要です。Claude Code、Codex、Cursor、Cline、Continue、Windsurf をはじめとする主要な AI コーディングツールに対応しています。<a href="https://www.ccsub.net/register?ref=VCVDAWWY">www.ccsub.net</a> から登録すると、初回登録時に 5 ドル分の無料クレジットがもらえます。
6161
</td>
6262
</tr>
63+
<tr>
64+
<td align="center" width="120">
65+
<a href="https://go.apimart.ai/gh-moneyprinterturbo"><img src="docs/sponsors/apimart-logo.png" alt="APIMart" width="100"></a>
66+
</td>
67+
<td align="left">
68+
本プロジェクトをスポンサードしてくださっている <a href="https://go.apimart.ai/gh-moneyprinterturbo">APIMart</a> に感謝します! APIMart は、AI 画像・動画生成に特化した低価格 API プラットフォームです。<strong>GPT-Image-2 は 1 枚あたり 0.006 米ドルから利用でき、1 米ドルで 160 枚以上の画像を生成できます</strong>。<strong>画像と動画を 1 つの非同期 API で扱い、コードを変更せずにモデルを切り替えられます</strong>。タスクを送信して ID を受け取った後、ポーリングまたはコールバックで結果を取得でき、数万枚規模のバッチ処理にも対応します。月額料金のない従量課金制で、<a href="https://go.apimart.ai/gh-moneyprinterturbo">こちらの登録リンク</a>からすぐに利用を開始できます。
69+
</td>
70+
</tr>
6371
<tr>
6472
<td align="center" width="120">
6573
<a href="https://infistar.cc/register?aff=6T4EYXP2&amp;ref_source=link"><img src="docs/sponsors/infistar-logo.svg" alt="Infistar.ai" height="56"></a><br>

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@
6060
感谢 <a href="https://www.ccsub.net/register?ref=VCVDAWWY">CCSub</a> 赞助本项目!<strong>CCSub 是稳定、实惠的 AI API 中转平台,是 Claude Code 官方订阅的超强平替。</strong>一个 API Key 即可调用 Claude Opus 4.8、Sonnet 4.6、Haiku 4.5、GPT-5、Gemini 等模型,价格约为官方直连的 1/3,全球直连无需梯子。兼容 Claude Code、Codex、Cursor、Cline、Continue、Windsurf 等所有主流 AI 编程工具。前往 <a href="https://www.ccsub.net/register?ref=VCVDAWWY">www.ccsub.net</a> 注册即送 $5 体验额度。
6161
</td>
6262
</tr>
63+
<tr>
64+
<td align="center" width="120">
65+
<a href="https://go.apimart.ai/gh-moneyprinterturbo"><img src="docs/sponsors/apimart-logo.png" alt="APIMart" width="100"></a>
66+
</td>
67+
<td align="left">
68+
感谢 <a href="https://go.apimart.ai/gh-moneyprinterturbo">APIMart</a> 赞助了本项目!APIMart 是专注 AI 图片/视频生成的低价 API 平台,<strong>GPT-Image-2 低至 &#36;0.006/张,1 美元可出图 160+ 张</strong>。<strong>图片、视频一套异步 API 通吃,换模型不改代码</strong>;提交任务拿 ID,通过轮询或回调获取结果,支持万张级批量生成。按量付费、无月费,通过<a href="https://go.apimart.ai/gh-moneyprinterturbo">此注册链接</a>注册即可开用。
69+
</td>
70+
</tr>
6371
<tr>
6472
<td align="center" width="120">
6573
<a href="https://infistar.cc/register?aff=6T4EYXP2&amp;ref_source=link"><img src="docs/sponsors/infistar-logo.svg" alt="Infistar.ai 无限星河" height="56"></a><br>

app/models/llm_provider.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,16 @@ def select_service_endpoint(
318318
default_model="deepseek/deepseek-v4-flash",
319319
default_base_url="https://router.shengsuanyun.com/api/v1",
320320
),
321+
# APIMart 同时提供 `/api/v1` 业务接口和 `/v1` OpenAI 兼容接口。
322+
# 当前 LLM 服务层依赖 OpenAI SDK 直接读取 choices,因此必须使用不带
323+
# code/data 外层包装的 `/v1` 入口,不能照搬异步业务接口的地址。
324+
LLMProviderSpec(
325+
"apimart",
326+
"APIMart",
327+
api_key_url="https://go.apimart.ai/gh-moneyprinterturbo",
328+
default_model="gpt-5.6-terra",
329+
default_base_url="https://api.apimart.ai/v1",
330+
),
321331
LLMProviderSpec(
322332
"cloudflare",
323333
"Cloudflare AI Gateway",

config.example.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ shengsuanyun_api_key = ""
140140
shengsuanyun_base_url = ""
141141
shengsuanyun_model_name = ""
142142

143+
# APIMart, OpenAI-compatible multi-model API.
144+
# Sign up: https://go.apimart.ai/gh-moneyprinterturbo
145+
# API docs: https://docs.apimart.ai/cn
146+
apimart_api_key = ""
147+
apimart_base_url = ""
148+
apimart_model_name = ""
149+
143150
# OpenAI or another OpenAI Chat Completions-compatible provider.
144151
# API key: https://platform.openai.com/api-keys
145152
openai_api_key = ""

docs/sponsors/0029-logo.jpg

-16 KB
Binary file not shown.

docs/sponsors/apimart-logo.png

71.8 KB
Loading

docs/sponsors/compshare-logo.png

-15.5 KB
Binary file not shown.

docs/sponsors/ergou-api-logo.png

-120 KB
Binary file not shown.

test/services/test_llm.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ def test_provider_registry_preserves_product_group_order(self):
326326
"minimax",
327327
"mimo",
328328
"shengsuanyun",
329+
"apimart",
329330
"cloudflare",
330331
"modelscope",
331332
"aihubmix",
@@ -355,6 +356,13 @@ def test_provider_registry_preserves_product_group_order(self):
355356
shengsuanyun.default_model,
356357
"deepseek/deepseek-v4-flash",
357358
)
359+
apimart = get_llm_provider("apimart")
360+
self.assertEqual(
361+
apimart.api_key_url,
362+
"https://go.apimart.ai/gh-moneyprinterturbo",
363+
)
364+
self.assertEqual(apimart.default_model, "gpt-5.6-terra")
365+
self.assertEqual(apimart.default_base_url, "https://api.apimart.ai/v1")
358366

359367
def test_provider_registry_uses_conventional_locale_and_config_keys(self):
360368
"""统一命名规则可避免 WebUI 为每个 Provider 增加硬编码映射。"""
@@ -1069,6 +1077,48 @@ def test_qwen_provider_reports_empty_choices(self):
10691077
self.assertIn("returned empty choices", result)
10701078
self.assertNotIn("NoneType", result)
10711079

1080+
def test_apimart_provider_uses_unwrapped_openai_compatible_endpoint(self):
1081+
"""
1082+
APIMart 文档同时展示 `/api/v1` 和 `/v1` 两组入口。前者的示例响应
1083+
带有 code/data 外层包装,OpenAI SDK 无法直接从顶层读取 choices;
1084+
LLM Provider 必须使用标准 `/v1` 地址,才能复用现有响应解析链路。
1085+
"""
1086+
config.app["llm_provider"] = "apimart"
1087+
config.app["apimart_api_key"] = "apimart-key"
1088+
config.app["apimart_base_url"] = ""
1089+
config.app["apimart_model_name"] = ""
1090+
1091+
class FakeCompletions:
1092+
def create(self, **kwargs):
1093+
self.kwargs = kwargs
1094+
message = types.SimpleNamespace(content="hello\napimart")
1095+
choice = types.SimpleNamespace(message=message)
1096+
return types.SimpleNamespace(choices=[choice])
1097+
1098+
fake_completions = FakeCompletions()
1099+
fake_client = types.SimpleNamespace(
1100+
chat=types.SimpleNamespace(completions=fake_completions)
1101+
)
1102+
1103+
with (
1104+
patch.object(llm, "OpenAI", return_value=fake_client) as openai_client,
1105+
patch.object(llm, "ChatCompletion", types.SimpleNamespace),
1106+
):
1107+
result = llm._generate_response("Say hello")
1108+
1109+
openai_client.assert_called_once_with(
1110+
api_key="apimart-key",
1111+
base_url="https://api.apimart.ai/v1",
1112+
)
1113+
self.assertEqual(
1114+
fake_completions.kwargs,
1115+
{
1116+
"model": "gpt-5.6-terra",
1117+
"messages": [{"role": "user", "content": "Say hello"}],
1118+
},
1119+
)
1120+
self.assertEqual(result, "hello\napimart")
1121+
10721122
def test_aihubmix_provider_uses_openai_compatible_client(self):
10731123
"""
10741124
AIHubMix 是 OpenAI-compatible 网关。这里用 fake OpenAI client

0 commit comments

Comments
 (0)