Yhx888/dsh-free-egg-credits

dsh-free-egg-credits

在 DSH 侧边栏看 WorkBuddy / Qoder 账号积分、今日额度、签到状态与每轮消耗(WorkBuddy 已知单价时按输入 / 缓存 / 输出分类型折算);配置 new-api 后可一键切换优先消耗平台。需本机运行 WorkBuddy2API 或 Qoder 网关。

待分类checkincreditsdeepseek-harness

Free Egg Credits

中文 | English

一个 DSH(DeepSeek Harness)Web 界面插件:把本地反代网关 (WorkBuddy / Qoder)里各账号的可用积分、每日积分预算(已用 / 上限 / 剩余 / 满额)、 每日签到状态,以及每条对话折算消耗的积分直接显示在界面里——侧边栏、输入框下方、 每轮对话末尾和设置页各有一个落点。设置页还能一键切换优先消耗哪个平台的积分 (基于本机 new-api 渠道优先级,Qoder 拥堵时点一下切回 WorkBuddy)。

积分为折算值:WorkBuddy 优先按 input / cache / output 分类型实测单价折算(缓存命中单独计价,避免把 57M context 乘混合单价高估数倍),没有分类型单价的模型回落到账号 model_costs 台账;Qoder 用面板 /usage 台账(真实 credit ÷ total_tokens)。未实测的模型按各网关的模型目录倍率折算,界面统一带 ≈ 标记。

快速开始

不用再开三个面板:在 DSH 侧边栏一眼看清 WorkBuddy / Qoder 还剩多少积分、今天还能不能用、这轮烧了多少;配置了 new-api 时还能一键切换优先消耗平台。

一键安装

dsh plugin --profile web add github:Yhx888/dsh-free-egg-credits
  • 桌面端:侧栏 插件 → 添加插件,粘贴 https://github.com/Yhx888/dsh-free-egg-credits,点安装,然后重启 DSH。
  • Web / CLI:执行上面的命令;装好后按 配置 填入网关地址与密钥文件路径,再重启 DSH。
  • 已经装了 WorkBuddy2API / qoder2api-hub:通常只需要 gatewayBaseUrl + gatewayConfigPath(WorkBuddy)和 qoder.baseUrl + qoder.panelPasswordFile(Qoder);newApi 可选。
适合谁:本机已经跑 WorkBuddy2API / qoder2api-hub(可选 new-api)的用户。插件只读这些网关的本地接口,不提供账号、积分或网关;没有网关时不会显示数据。

它解决什么

  • 不用切面板:余额、今日已用 / 上限、签到状态、当前消耗账号,侧边栏一屏看完。
  • 知道花在哪:每个会话、每条对话的积分消耗自动折算,悬停可看 token 与模型。
  • 满额能救急:Qoder 拥堵或额度用完时,点一下 chip 切到 WorkBuddy 优先,不用改配置(需配置 newApi)。
已收录到社区 DSH 插件市场(索引每 2 小时刷新);搜索 Free Egg、dsh-free-egg-credits、WorkBuddy 或 Qoder 即可。

界面落点

  • 侧边栏底部(账户行上方):账号积分区块。每行统一为「状态点 · 账号名 · 来源徽标(WB/Qoder) · 今日消耗 · 余额」,

签到状态只由最左侧状态点表达(绿色 = 今日已签到;黄色 = 今日尚未签到 / 今日奖励待领取);限流 / 降权 / 连败以徽标透出恢复时间。侧边栏收起时不占位。 标题行右侧还有一个「消耗优先级」小 chip(如 WB 优先):点一下即可切到另一个平台,不用进设置页。 选中逻辑按前台会话固定:每个会话在首轮回复后固定一个承载账号,之后不再换号;切换前台会话只会切换 高亮行,不会跟着全局最近请求来回跳。正在消耗的账号行加灰色底框(选中态),不额外占一行。 每行还有一个「今日消耗」小框(向下小箭头 + 积分):WorkBuddy 按余额差值累计、Qoder 按用量台账精确累加(billable=false 的免费调用不扣积分,也不计入)。 网关启用每日积分预算后改为「已用/上限」(如 118/100),满额时用宿主警示色标出(悬停见 「今日已满额,已停用,明日 0 点恢复」);全部账号满额时区块底部多一行「今日额度已用完」提示。

  • 输入框下方:当前对话累计消耗(Free Egg · 本会话 ≈N 积分)。只要当前对话用的是 free-egg provider

(默认 free-egg / workbuddy / qoder / new-api)的模型,这条就常显——首轮回复前是 ≈0, 模型暂时没有单价时提示「等待单价」;换到其他 provider(如 DeepSeek 官方账号)的模型则不显示,避免误导。

  • 每条对话末尾:该轮折算消耗(本轮 ≈N 积分,悬停可看 token 与模型)。
  • 设置 → Free Egg 积分:账号卡(名称 / 来源徽标 / 余额 / 签到状态 / 已用占比 /

今日已用 ≈X / 上限(剩余 ≈Y) / 立即签到)、积分优先消耗(WorkBuddy / Qoder 优先切换)、 限流与降权明细、折算单价、最近对话与逐轮明细; 全部账号满额时页面顶部加一行提示。

WorkBuddy 与 Qoder 账号共用同一套行 / 卡片结构,只以来源徽标区分。

安装

插件本身零运行时依赖,只要一个能跑 DSH Web GUI 的环境。

方式一:从 GitHub 安装

dsh plugin --profile web add github:Yhx888/dsh-free-egg-credits

安装后按「配置」一节写配置,再重启 DSH 生效。

官方桌面端托管的 desktop profile 会被 CLI 拒绝(managed exclusively by the Electron application),
这类环境请用下面的手动 link 方式。

方式二:手动 link(桌面端 / 本地开发)

插件通过 link: 依赖装进 DSH profile,不进 node_modules 拷贝,改完源码重启 DSH 即生效:

// ~/.dsh/profiles/<profile>/package.json
"dependencies": {
  "dsh-free-egg-credits": "link:/absolute/path/to/dsh-free-egg-credits"
},
"dsh": { "profile": { "bundles": [ "...", "dsh-free-egg-credits" ] } }
# 建链接(junction 不需要管理员权限)
New-Item -ItemType Junction `
  -Path "$env:USERPROFILE\.dsh\profiles\<profile>\node_modules\dsh-free-egg-credits" `
  -Target "C:\absolute\path\to\dsh-free-egg-credits"

改完 Host 半(index.js)需重启 DSH;只改 Client 半(client.js)刷新页面即可。

外部依赖(可选,缺省则对应来源不显示)

依赖 · 用途 · 相关配置 WorkBuddy2API 网关(workbuddy2api) · WorkBuddy / CodeBuddy 账号积分与签到 · gatewayBaseUrl、gatewayConfigPath Qoder 反代网关(qoder2api-hub) · Qoder 账号积分与签到调度 · qoder.baseUrl、qoder.panelPasswordFile New API(new-api,:3001) · 「积分优先消耗」切换(改渠道优先级) · newApi.*

两个网关都不是本插件的组成部分;插件只读它们的 HTTP 接口。 网关密钥与面板密码只在 Host 侧读取、不下发浏览器。

配置

写在目标 profile 的 cordis.patch.yml(插件 id:free-egg-credits):

- id: free-egg-credits
  config:
    gatewayBaseUrl: 'http://127.0.0.1:7863'
    gatewayConfigPath: 'C:/path/to/workbuddy2api/config.json'
    realms: [cn]
    autoCheckin: true
    checkinAfterHour: 8
    checkinRetryMinutes: 10
    refreshSeconds: 30
    creditsPer1k: {}
    freeEggProviders: [free-egg, workbuddy, qoder, new-api]
    catalogBaseCreditsPer1k: 0
    qoder:
      baseUrl: 'http://127.0.0.1:8790'
      panelPasswordFile: 'C:/path/to/qoder2api/.panel-password'
    # 可选:「积分优先消耗」切换(改本机 new-api 两个渠道的优先级)。
    # 不配置则整块 UI 隐藏,其余行为不变。
    newApi:
      baseUrl: 'http://127.0.0.1:3001'
      userId: 1
      accessTokenFile: 'C:/path/to/new-api-access-token'   # 文件内容 = 管理员 access token
      # accessToken: '<内联兜底,二选一>'
      channels:
        workbuddy: 13
        qoder: 12
      priorities:
        preferred: 10
        fallback: 5
这一层的 config 是整体替换 bundle 层配置,不是深合并:一旦写了 qoder,
qoder 下的字段要一起写全(baseUrl 必填,panelPasswordFile / panelPassword / enabled 可选);
newApi 同理,baseUrl 必填,其余可省略。

字段 · 默认 · 说明 gatewayBaseUrl · http://127.0.0.1:7863 · WorkBuddy 网关地址 gatewayConfigPath · 包目录上两级 config.json · 从网关配置读取 api_key。默认值只对「插件放在网关仓库内」的开发期布局有效;独立目录安装时必须显式指向网关 config.json,否则读不到密钥、网关判离线、侧边栏只剩标题没有账号行 apiKey · 空 · 直接给密钥(优先于配置文件) realms · [cn] · 统计哪些域;国内账号即 cn autoCheckin · true · 是否自动补签 / 探测签到状态 checkinAfterHour · 8 · 几点后才自动探测(避免凌晨误触发) checkinRetryMinutes · 10 · 失败重试间隔 refreshSeconds · 30 · 网关快照缓存 creditsPer1k · {} · 混合单价覆盖(模型名 → 积分/千 token),优先级最高;会忽略缓存折扣,仅建议对没有分类型单价的模型使用 tokenRates · 内置 deepseek-v4.1-flash · WorkBuddy 逐 token 类型单价(模型名 → { input, cache, output },积分/千 token)。缓存命中单独计价,避免高估;上游调价后可在此覆盖 freeEggProviders · ['free-egg','workbuddy','qoder','new-api'] · 哪些 DSH provider 视为「free-egg 模型」:这些 provider 的对话底栏常显积分预估,且只有它们计积分 catalogBaseCreditsPer1k · 0 · 目录倍率折算的兜底基线(积分/千 token/倍率单位);0 = 只用网关实测台账自动校准 qoder · 无 · Qoder 网关子配置:baseUrl、panelPasswordFile(面板密码文件)、panelPassword(内联兜底)、enabled。不配置则不启用 Qoder 来源 newApi · 无 · new-api 管理接口子配置(「积分优先消耗」切换用):baseUrl、userId、accessToken / accessTokenFile、channels.workbuddy / channels.qoder、priorities.preferred / priorities.fallback。不配置则功能隐藏

每日积分预算(网关层强制)

每日预算与选号都由网关强制,插件只负责读字段展示(不参与限流、不参与换号)。本机参考配置:

  • WorkBuddy(workbuddy2api 的 config.json → pool):daily_credit_limit = 100(0 = 关闭)
  • prefer_credits = true(健康候选按余额从高到低优先)。
  • Qoder(qoder2api-hub 面板「设置 → 每日积分限额」):按域的 daily_credit_limit = 100(cn)。

生效后的行为:

  • 账号当天累计消耗达到上限(WorkBuddy daily_credit_spent >= daily_credit_limit;Qoder

creditLimitReached = true)后,网关不再把新请求分给该账号(粘性会话路径也会拒绝并让上层重新选号);

  • 同一网关内优先使用余额最高的账号,直到它达上限被跳过;
  • 四个账号(WorkBuddy 2 + Qoder 2)都满额后,new-api 的 qwen-fallback 渠道会把 DeepSeek 请求

自动降级到 Qwen3.8-Flash(免费)继续跑;WB/Qoder 恢复额度后自动回到 DeepSeek。

插件侧的展示:

  • 侧边栏账号行的小框在启用预算时显示「已用/上限」(如 118/100),满额时用宿主警示色标出,

tooltip 明确「今日已满额,已停用,明日 0 点恢复」;未启用预算时仍是原来的「≈N 积分」。

  • 设置页账号卡显示「今日已用 ≈X / 100(剩余 ≈Y)」,满额时多一行提示。
  • 一次快照里所有账号(WorkBuddy + Qoder 合计,至少一个)都满额时,设置页顶部与侧边栏

各给一行提示:「今日额度已用完:DeepSeek 已自动降级到 Qwen3.8-Flash(免费)」。

旧网关没有每日预算字段,或 Qoder 面板 /accounts 读取失败时,插件自动回落到旧的「今日消耗」
展示(Qoder 会沿用上一次成功拿到的预算值),不会让整次刷新失败。

积分优先消耗(平台级)

DeepSeek 请求由本机 new-api(默认 http://127.0.0.1:3001)在 WorkBuddy 与 Qoder 两个渠道之间选路。 插件把它做成一个可切换的选项:设置页「积分优先消耗」两个互斥按钮,或侧边栏标题行的 WB 优先 / Qoder 优先 chip,点一下即改 new-api 两个渠道的优先级(本机默认 WorkBuddy 渠道 id 13、Qoder 渠道 id 12):

选择 · WorkBuddy 渠道 · Qoder 渠道 · 效果 WorkBuddy 优先(默认原状) · 10 · 5 · DeepSeek 先消耗 WorkBuddy 积分,失败 / 满额才落 Qoder Qoder 优先 · 5 · 10 · DeepSeek 先消耗 Qoder 积分,拥堵 / 失败 / 满额自动回退 WorkBuddy

  • 切换即时生效(new-api 更新后立即重建渠道缓存),只影响新请求;正在进行的对话不受影响。
  • 只改渠道优先级,不动两个网关内部的账号池选号(账号仍按余额 / 每日预算由网关自己挑)。
  • 选择持久化在插件状态文件 /free-egg-credits/routing.json;真实生效状态按 30 秒缓存从

new-api 回读(设置页点刷新会强制重读),若在 new-api 控制台手工改过优先级,设置页会提示 「选择与实际不一致」。

  • 需要 new-api 管理凭据(管理员用户的 access token):插件只从配置 / token 文件读取,不下发浏览器。

未配置 newApi 时整块 UI 隐藏,插件其余行为不变。

获取 access token:登录 new-api 控制台 → 个人设置 → 系统访问令牌(重新生成会轮换并让旧值立即失效, 本机可通过 GET /api/user/token 触发并拿到新值)。把令牌写进 accessTokenFile 指向的文件(推荐, 文件权限按本机用户最小化)或用 accessToken 内联;不要提交进仓库。

数据来源

数据 · 来源 WorkBuddy 账号积分 · 网关面板 GET /panel/api/overview(realm=cn 的账号) WorkBuddy 签到状态 · 当天首次打开界面时调用一次单号签到接口(POST /panel/api/accounts/{uid}/checkin)。上游对重复签到返回 10001 今天已签到,幂等无副作用;未签到时顺带完成当天签到 Qoder 账号积分 · Qoder 网关 GET /credits/summary(registered 口径:credits_remain / credits_size) Qoder 签到状态 · Qoder 面板 GET /accounts 每个账号的 lastCheckin(今天已签到 / 尚未签到 / 今日奖励待领取,含签到时刻);面板不可用或该账号行缺失时回落 GET /scheduler 的 last_run_time。签到本身由网关调度器后台完成 平台优先消耗 · new-api 管理接口 GET /api/channel/{id}(读 priority)与 PUT /api/channel/(写 priority):WorkBuddy 渠道 13 / Qoder 渠道 12;切换后回读校验 会话消耗账号 · WorkBuddy 面板 token_usage.last_used_at / last_model;Qoder 面板 GET /usage/recent(account / model / at,3 秒缓存)。每轮回复结束后 Host 侧延迟 1.5 秒刷新两侧网关,按事件时刻就近匹配到该会话;首次匹配后固定,不再换号 账号当日消耗 · WorkBuddy:累加两次快照之间的余额下降量(网关按上游 credit 扣减账号余额),账本落盘 /free-egg-credits/daily.json,重启 DSH 继续算;Qoder:当天 /usage/recent 台账中 billable !== false 的 credit 逐条累加(免费模型行 billable=false 不计;缺该字段的旧网关按计费处理) 每日积分预算 / 今日已用 · WorkBuddy:面板 GET /panel/api/overview 账号行的 daily_credit_spent / daily_credit_limit / daily_credit_capped;Qoder:面板 GET /accounts(面板 token 已封装)的 dailyCreditsToday / dailyCreditLimit / creditLimitReached,与 /credits/summary 并进同一次刷新(保留 60 秒缓存)。Qoder 的 dailyCreditsToday 是名义口径(免费调用也累计 credit),展示侧改用按 billable 过滤后的本地台账;字段缺失(旧网关)时保持 undefined/0/false,界面回落旧的「今日消耗」样式;/accounts 失败只让预算字段缺省,不影响 Qoder 积分刷新 每轮 token · DSH Session 事件里的 assistant/message.usage(Host 侧折叠,不落盘);同时保留 inputTokens / cacheReadTokens / outputTokens 三类,用于分类型折算 积分单价(WorkBuddy 分类型) · 内置 tokenRates(2026-10-22 实测):deepseek-v4.1-flash 输入 0.014444、缓存 0.0001962、输出 0.059415 积分/千 token;上游调价或换模型时可用 tokenRates 覆盖 积分单价(WorkBuddy 混合兜底) · 没有分类型单价的模型:网关账号状态里的 model_costs[].cost_per_1k;会话已固定账号时优先该账号自己的台账,不再拿全池加权平均值 积分单价(Qoder 实测) · Qoder 面板 GET /usage 的 by_model 台账:真实 credit ÷ total_tokens(含缓存命中折扣),5 分钟缓存 积分单价(未实测) · 模型目录倍率:WorkBuddy GET /v1/models 的 credits(如 x0.11)、Qoder GET /models 的 price_factor;两台网关各自用本网关实测数据校准基线;倍率为 0 视为免费模型(0 积分) free-egg 聚合别名 · 如 deepseek-v4.1-flash 实际由 Qoder DeepSeek-Flash 承载时,用「去版本号归一 + 实测单价」兜底匹配;歧义时可用 creditsPer1k 覆盖 模型来源 · DSH Session 事件里 assistant/message.message.source.provider / model,以及 model/selection、request/header 事件的当前 provider / model(据此判断算不算 free-egg 模型) 限流状态 · 网关账号状态里的 rate_limited_models[](6004 模型级限流台账:model / until / reset_at)与 degrade_until(连败降权截止),到期自动消失。重置时间取上游 reset_at(真正恢复可用的时刻,缺省回落 until),侧边栏徽标标成「限流 HH:mm(多模型取最晚)」;设置页把 until 单列为「本地冷却到」

工作原理

插件分 Host / Client 两半:

  • Host 半(`index.js`):inject: ['webServer'],在 DSH Web 同源路由 /__dsh-wb-credits

下注册 6 个接口(GET /snapshot、GET /sessions、POST /refresh、POST /checkin、 POST /qoder/checkin、POST /preference)。负责:读网关面板与模型目录、判定签到、用 session/event 与会话日志折叠每轮 token 用量、按 provider 判断是否 free-egg 模型、按「实测单价 → 目录倍率折算 → 配置覆盖」折算积分; 并在每轮回复结束后刷新 WorkBuddy token_usage 与 Qoder /usage/recent,按事件时刻把这次消耗 归属并固定在对应会话(会话 → 账号不再来回切);同时维护每个账号的「今日消耗」账本 (WorkBuddy 余额差值 + 落盘续算,Qoder 台账精确累加),并映射网关侧的每日积分预算字段 (WB /panel/api/overview;Qoder /accounts,best-effort 且失败保留上次值),供侧边栏展示。 「积分优先消耗」切换会通过 new-api 管理接口读写渠道优先级(access token 只在 Host 内使用), 选择落盘、真实状态每次快照回读。密钥、面板密码、token 全部只在这个进程内使用。

  • Client 半(`client.js`):手写 window.__ModuleLoader__ bundle,向 sidebar.footer.action、

conversation.composer.dock、conversation.chat.turnTail、settings.section 四个席位注入 React 组件, 只从上面的同源路由取数据。界面沿用宿主 CSS 变量(--dsw-alias-*),不引入独立样式体系。

签到是「网关后台自动 + 插件兜底」两层:

  • WorkBuddy / Qoder 网关各自带后台调度器,不依赖 DSH 是否打开:WorkBuddy 按

schedule.checkin_hours(默认 09:00 / 21:00)自动签到;Qoder 调度器按 09:00 / 10:15 / 10:45 / 21:00 自动巡检签到并领取活动积分(next_run_time 可在快照里看到; 10:15 与 10:45 是针对「当天活动 10:00 刷新后上游下发延迟」的两次重试窗口)。

  • 插件的 autoCheckin 只做打开界面时的幂等补签与状态核对:WorkBuddy 对未签到的账号调用一次

单号签到接口(上游对「今天已签到」返回 10001,无副作用);Qoder 侧不自动触发签到,只读面板 lastCheckin 展示状态,需要补签时点设置页「立即签到」。

  • Qoder 的「签到」= 领取每日活动(每日 10:00(UTC+8)开新一轮)。如果 lastCheckin 早于当天