Skip to content

Feature request: 自定义 OpenAI 兼容 LLM Provider 与多厂商 TTS(BYO API Key 直接玩) #60

Description

@Aafff623

Feature request: 自定义 OpenAI 兼容 LLM Provider 与多厂商 TTS(BYO API Key 直接玩)

Context(背景)

Wolfcha 目前内置三个固定 LLM 供应商(ZenMux / DashScope / TokenDance),玩家想自带 API Key 玩时只能选这三家。很多用户有自己购买的第三方 OpenAI 兼容端点(如 DeepSeek、Kimi、智谱、MiniMax、StepFun、OpenRouter、硅基流动等),或者自己的中转/自建网关——他们希望用自己的 key + 自己的 Base URL 玩游戏,不依赖项目内建的赞助额度。

当前代码在"自定义 Key 模式"下仍有一处与需求相悖的机制:游戏开局时会以"项目积分模式"校验并扣除赞助额度(/api/credits/consume 只识别 ZenMux/DashScope/TokenDance 三个 header 作为"自带 Key"信号),导致自定义端点玩家即使已配置好 key,开局仍被要求充值/扣积分。这违背了 "BYO key 直接玩" 的初衷。

Problem(问题)

  1. 无法接入任意 OpenAI 兼容端点(Base URL + API Key + 任意模型名),只有三家内定。
  2. 语音(TTS)被绑定 MiniMax 一家,用户没有 MiniMax 订阅就无法开启 AI 语音播报。
  3. 自定义 Key 玩家开局被强制走项目积分扣费;若余额不足则不能开始游戏。
  4. 部分推理模型(如 StepFun 3.5/3.7 flash 系列)的 reasoning 输出会耗尽 max_tokens,导致返回的 content 为空、角色生成失败。

Proposal(方案)

1. 自定义 OpenAI 兼容 LLM Provider

  • 新增 provider: "custom" 类型:玩家在设置里填任意 OpenAI 兼容端点的 Base URL + API Key,保存在本地浏览器(localStorage)。
  • /api/chat 支持 custom 分支(流式 + 批量),凭据通过 X-Custom-Base-Url / X-Custom-Api-Key 转发,服务端不落盘。
  • 新增 /api/llm-models:连通性测试(优先 GET /models,零 token 消耗;失败回退 max_tokens=1 最小对话请求)+ 拉取模型列表,填充模型选择下拉框。
  • 设置 UI:厂商预设(DeepSeek / Kimi / 智谱 / MiniMax / StepFun / Grok / Gemini / Claude / OpenRouter / 硅基流动 / 自定义);保存后自动激活为"使用中"。
  • 模型分工:人物生成 / 每日总结 / 复盘报告各可指定模型;AI 玩家候选从所选模型池抽取。

2. 多厂商 TTS

  • 将 /api/tts 从 MiniMax 硬编码重构成适配器注册表:minimax / openai-compatible(OpenAI 官方、硅基流动、Fish Audio 等)/ stepfun / volcengine / elevenlabs。
  • 支持连通性测试(合成一句话)与音色试听;错误兜底:音色无效自动回退默认音色。
  • 音色表按性别/年龄稳定映射(跨厂商切换不换声)。

3. 自定义 Key 开局免扣积分(修复)

  • /api/credits/consume:当请求携带 X-Custom-* 头或任何自带 key 时,视为 external-source 游戏,直接将 used_custom_key=true 并跳过项目积分扣费(与现有 ZenMux/DashScope/TokenDance 的 external 分支一致)。
  • 前端:开局请求发送自定义 Provider 凭据;hasActiveExternalModelSource() 纳入自定义 Provider,避免低积分弹窗拦截。
  • remove the forced top-up gate for BYO players.

4. 推理模型兼容(修复)

  • /api/chat custom 分支:对推理模型(StepFun flash 系列)自动放大 max_tokens(×3,上限 16384)并默认 reasoning_effort: "low",防止 reasoning 耗尽预算导致 content 为空。
  • 观测事件:record_game_session_ai_attempt 的 provider 白名单放行 custom;部分流式响应无 usage 时 token 归零。

5. 角色进场加速

  • 新增 src/lib/template-profiles.ts:角色基础档案(姓名 / 性别 / 年龄 / MBTI / 一句话背景)从本地模板库确定性生成(不再消耗一次 LLM 调用),人物进场时间显著缩短;角色个性化(persona / playerMind)仍由 LLM 生成。

Acceptance Criteria(验收标准)

  • 在「用我自己的 key 玩」添加任意 OpenAI 兼容端点:测试连通 → 保存 → 自动激活,无需手动点"设为使用中"。
  • 拉取到模型列表,可按角色选择模型;custom 模式下无内置 key 也能开局。
  • 自定义 Key(余额为 0)开局不弹充值、不扣赞助额度,能正常进入游戏。
  • 选择 TTS 供应商(如 StepFun / OpenAI 兼容),测试连通成功,音色试听可播放。
  • 使用 StepFun 3.5 flash / 3.7 flash 等推理模型时,角色生成返回完整 JSON,不因 content 为空失败。
  • 角色进场:本地模板生成基础档案,persona 生成并发执行,10 人场约 1-1.5 分钟内进场完毕。
  • 现有测试通过(包含新增 21 个契约测试,pnpm test:custom-providers)。

Verification(验证方式)

  • 本地 pnpm dev + Supabase 项目(schema 由 supabase/local-setup-full.sql 初始化)。
  • 用自定义 StepFun / DeepSeek 端点实际开局:登录 → 自定义 Provider → 测试连通 → 保存 → 开局 → 夜晚行动 → 天亮发言(TTS 播报)。
  • 新增契约测试:server/custom-provider-contracts.test.ts、src/lib/custom-providers.test.ts、src/lib/tts-client.test.ts。

Notes

  • 所有 API Key 仅保存在用户浏览器的 localStorage,服务端只做转发,不落盘。
  • 建议 PR 中附上:DB 迁移(provider=custom 放行)、UI 截图、角色进场对比数据。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions