npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

koishi-plugin-tibo-reset

v0.1.11

Published

Poll Tibo Codex reset announcements and notify whitelisted Koishi groups.

Readme

koishi-plugin-tibo-reset

参考 koishi-plugin-zssm 的 TypeScript 项目结构构建。轮询 https://codex-resets.com/api/v1/status,向白名单群推送 Tibo 的 Codex 重置预告。

安装与配置

需要 Node.js 20.19+、Koishi 4.18.8+,以及已启用的 HTTP 服务和机器人适配器。不依赖数据库插件。

npm install
npm test
npm run build
npm pack

将打包得到的 koishi-plugin-tibo-reset-*.tgz 安装到 Koishi 项目,在插件配置中启用 tibo-reset。

插件导出 Koishi Config Schema,控制台自动生成“轮询设置”“HTTP 请求”“通知内容”“群白名单”“AI 问答”“测试推送”分组表单,保存配置后由 Koishi 重载生效。

| 配置 | 默认值 | 说明 | | --- | --- | --- | | enabled | true | 启用插件 | | pollInterval | 300 | 轮询间隔,秒,范围 10–86400 | | requestTimeout | 15 | HTTP 超时,秒,范围 1–120 | | eventTypes | 两种类型 | direct_reset 全员重置;reset_credit 发放重置卡 | | notifyConfirmed | false | 是否同时推送确认完成/发放 | | groups | [] | channel ID 字符串白名单;空白名单不向任何群发送 | | testPushToken | "" | 测试批次,填写新值后模拟最新一条事件并实际推送 | | enableQuery | true | 启用白名单群的重置问答,未配置模型密钥时不启用 | | aiTextEndpoint | https://api.deepseek.com/v1 | 兼容 Chat Completions 的文本模型地址 | | aiTextToken | "" | 文本模型 API key,控制台以密码字段显示 | | aiTextModel | deepseek-chat | 必须支持 tool calling 的模型名称 | | aiRequestTimeout | 60 | 每次问答总超时,秒,范围 5–300 | | http400Retries | 2 | HTTP 400 的额外重试次数,范围 0–5;0 表示不重试 | | httpRetryDelay | 1 | 重试基础间隔,秒,范围 0–30;每次翻倍,单次等待不超过 30 秒 |

Koishi YAML 配置示例:

plugins:
  tibo-reset:
    pollInterval: 300
    requestTimeout: 15
    notifyConfirmed: false
    eventTypes:
      - direct_reset
      - reset_credit
    groups:
      - "987654321"
    enableQuery: true
    aiTextEndpoint: "https://api.deepseek.com/v1"
    aiTextToken: "填写你的模型 API key"
    aiTextModel: "deepseek-chat"
    aiRequestTimeout: 60
    http400Retries: 2
    httpRetryDelay: 1

每项只填写 channel ID(群号/频道 ID)字符串,不需要平台、机器人账号或 guild ID。使用 Koishi 中第一个在线机器人发送,不向其他机器人广播;没有在线机器人时保留队列,等下次轮询重试。适合单机器人环境,多机器人环境请确保第一个在线机器人可以访问所填频道。仅配置群聊目标,不要填私聊频道 ID。

从旧配置升级时,保留原有 eventTypes 和 notifyConfirmed 设置。旧 v1/v2 状态文件会迁移为 v3:保留待发送群的进度和测试批次,首次成功读取新接口时为当前记录建立基线,不补发当前快照中的旧消息。

数据结构与数据源

只请求 GET /api/v1/status,不请求旧接口、/resets 列表或其他端点。轮询与问答共用此接口。

| 字段 | 含义与用途 | | --- | --- | | data.latest_reset | 最新已执行重置;内部通知状态为 completed | | data.scheduled_reset | 上游保留的预告,包含 status: scheduled、可空的 scheduled_for;标签可能未随发放更新 | | data.active_watch | 无 ID 的 AI 预测,仅供问答参考,不主动推送,不作为官方承诺 | | data.stats | 接口提供的统计,保留给问答使用 | | meta.generated_at | 接口生成时间,不是重置完成时间 |

重置记录直接保留接口的 id、reset_type(regular / banked)、announced_at、英文 text 和 source(type、可选 author / url)。通知队列只额外标明记录所在状态,避免重建旧接口的标题、帖子数组、时间区间等字段。announced_at 是公告或首次观察时间,不能冒充执行完成时间。

现有配置 direct_reset 映射 regular,reset_credit 映射 banked。默认仍只推送新预告;需要接收新出现的 latest_reset,请开启 notifyConfirmed。相同 ID 已记录后,不因预告变为已执行而再次推送。

此接口是当前快照,最多包含最新执行记录和一个预告,不是完整历史。轮询间隔内被后续记录替换的事件无法通过此接口补齐。

重置问答

沿用 zssm 的 aiTextEndpoint、aiTextToken、aiTextModel 配置方式,但不自动读取 zssm 的密钥。模型必须支持 Chat Completions 的 tools、tool_choice 和 tool_calls;endpoint 可以填写基础地址,也可以直接填写完整的 /chat/completions 地址。

填写模型密钥并保存后,在白名单群消息开头 @ 当前机器人再提问,无须命令:

  • tibo 是否重置?
  • codex 重置了吗?
  • 什么时候重置?
  • 重置卡发了吗?和全员重置是同一回事吗?

自动分析仅在 Koishi 的 session.stripped.atSelf 为真时触发。未 @、仅 @ 他人或全体成员、仅呼叫机器人昵称时,不调用模型或查询接口,直接交给后续中间件。此限制不影响定时轮询、群通知和本地命令行联调。

处理流程:关键词初筛 → 模型判断是否调用 query_codex_resets → 实时读取重置接口 → 模型依据英文 text 复核事件类型后生成回答。复核在工具调用后的回答阶段完成,仍是两轮模型请求。模型直接输出、没有工具调用时,一律不发送。对于明确询问密码、数据库、游戏等其他对象的重置,提示模型不调用工具;只是提到 Tibo/Codex、普通聊天或翻译任务也应保持静默。语义判断依赖所配置模型,不是精确的规则分类器。

工具无参数,每次问答只接受一次 query_codex_resets({}) 调用,不按上游类型筛选证据。返回值仅包含 checked_at、latest_reset、scheduled_reset、history、history_is_complete、active_watch 和 stats。历史中与当前记录完全相同的证据不重复发送给模型;同 ID 但状态、原文、类型、时间或来源不同的记录仍保留。原文保持完整,本地历史文件不因输出去重而删除记录。判断规则集中在 system prompt,工具描述只说明用途,返回值只携带数据。分类仅作为提示,以英文 text 为证据;指代不清或证据不足时明确表示类型不确定。复核不回写接口分类或改变通知订阅。

预告的 scheduled 标签可能滞后,并不证明尚未发放。AI 会联合当前 scheduled_reset、latest_reset 与本地历史中的英文原文,判断预告与后续执行是否属于同一批次;不同帖子 ID 或上游类型不同都不会直接否定关联。有依据时可判断已兑现或已开始发放;仅时间接近、时间已过或模糊措辞不视为完成证据。预测不代表官方承诺,过期预测会标记 expired。轮询和问答会将观察到的两类记录保存到 data/tibo-reset/history.json,按 ID 和所在字段保存,最多保留最近观察的 100 条;接口移除或替换的记录仍可作为后续判断依据。同一 ID 的预告和执行记录分别保留,重启后继续使用。首次升级前未保存的证据无法自动恢复。本地读写失败时保留原文件,降级使用实时证据并记录日志。问答不能提供完整历史或查询个人账户额度,也不会修改通知去重记录和测试批次。回答包含原帖和 Codex Resets 来源链接。

仅处理白名单群当前消息,不处理私聊、机器人消息、引用或转发内容。候选消息正文会发送到你配置的模型服务,不携带聊天历史;工具结果也会发送给该服务。普通无关键词消息不请求模型。每个用户在同一群同一时间只处理一条问题,插件总并发上限为 4,繁忙时跳过新问题。

无关问题、模型/API 失败或超时不发送占位消息、错误提示或猜测答案。未回复时交给后续 Koishi 中间件,其他插件仍可自行回复。关闭 enableQuery 或清空 aiTextToken 只停用问答,不影响轮询;关闭 enabled 则同时停用整个插件。卸载或重载会取消尚未完成的查询。

HTTP 重试与日志

重置接口(轮询、测试推送、主动问答)和模型接口(判断工具调用、生成回答)均通过统一请求层。HTTP 400 默认额外重试 2 次,即最多请求 3 次,分别等待 1 秒、2 秒。每次重试沿用原地址与请求参数,不切换代理、地区或密钥。持续的参数或服务限制错误仍会失败;401、403、429、5xx、网络错误和解析错误不在这次立即重试范围内。

问答的 aiRequestTimeout 是包含两轮模型、工具查询和重试等待的总时限,超时或卸载会立即取消等待,不再发起新请求。requestTimeout 是重置接口每次尝试的超时。轮询最终失败仍沿用原有定时检查和通知队列策略;模型请求重试不会重复执行查询工具或重复发送群回复。

所有上述 API 尝试都写入 Koishi 的 tibo-reset 日志,包括本地联调脚本。正常请求与成功记录为 info,失败、取消和重试记录为 warn。每条日志以 [api] 开头,包含请求编号、操作、方法、脱敏后的地址、尝试次数和耗时。同一次请求的重试共用 requestId,便于关联:

  • reset.poll:轮询及测试推送读取接口。
  • reset.query:问答工具读取接口。
  • reset.check:本地 check:api 检查。
  • model.route:模型判断是否调用工具。
  • model.answer:模型复核原文并回答。

phase 为 request、success、failure、retry 或 cancelled;失败时记录可取得的 HTTP 状态码,重试时记录等待毫秒数。Koishi 的 get/post 只返回解码后的正文,因此成功记录不伪造具体的 HTTP 200 状态码。地区限制等已识别错误提供安全类别(例如 location_not_supported),不原样打印可能包含密钥或聊天内容的错误正文。

日志不输出 Authorization、API key、完整请求/响应正文、群消息或模型思考内容;URL 去掉凭据、查询参数及片段,已知密钥在路径中也会脱敏。不会为记录日志而拦截其他插件或适配器内部的请求。群消息投递继续使用原有队列重试,不增加立即 HTTP 400 重发,避免重复通知。

通知与重试规则

  • 首次成功读取接口只建立历史基线,不补发接口内已有预告。建立基线失败时不会发送。
  • 默认同时订阅全员重置和重置卡,只通知新 ID 的 scheduled 记录;开启 notifyConfirmed 后,也通知新 ID 的 completed 记录。
  • 仅用接口自带 id 去重并持久化。相同 ID 的文案、类型、来源 URL、预计时间或状态变化不会重复通知;同一 ID 同时出现在两个字段时优先采用已执行记录。
  • 白名单为空期间仍建立基线并记录事件;后来加群不补发历史。修改类型和确认开关也不补发已记录 ID。
  • 重复白名单行会去重。离线机器人、发送异常或未返回消息 ID 时,下一轮重试;成功的群不会因其他群失败而重复收到。
  • 待发送队列会持久化,API 暂时不可用时仍尝试发送。移出白名单、关闭对应通知类型后,待发送通知也会取消。
  • 状态文件位于 Koishi baseDir 下的 data/tibo-reset/state.json,采用临时文件加原子重命名保存。损坏文件不会被自动覆盖,修复前暂停通知。请保留数据目录。
  • 同一 Koishi 数据目录只运行一个此插件实例。卸载时取消 HTTP 请求并停止后续发送;正在进行的适配器发送会等待结束。
  • 群平台发送与本地保存无法形成同一事务:若发送成功后进程崩溃、保存失败后重启,或适配器接收消息却返回错误,重试可能产生重复通知;不承诺严格恰好一次。
  • 预告只是来源方的计划,不表示已到账。插件不根据预计时间自动判定确认。

消息排版

消息头按状态显示 [Tibo / Codex 重置预告] 或 [Tibo / Codex 重置确认]。消息头、英文时间、正文之间用空行分段,正文前后使用分隔线,来源链接独立显示:

[Tibo / Codex 重置预告]

Expected time: Sep 23, 2026, 14:59 (UTC+8)

──── Tibo ────

Ladies and gentlemen... start... your... ENGINES. We are almost Tuesday and I promised a reset for Tuesday.
────────────────

原文:https://x.com/thsottiaux/status/2102254445082116335

预告使用 scheduled_for 转换为北京时间,缺失时显示 Expected time: Not specified。重置确认显示 Reset type: regular (Usage reset) 或 Reset type: banked (Reset credit),并将 announced_at 转换为 UTC+8 显示为 Announced at,不伪造实际完成时间。所有消息时间均按 UTC+8 展示,包含跨日转换。正文直接使用接口英文 text,保留原有换行、段落和完整内容,正文前显示 ──── Tibo ────,正文后显示 ────────────────;观察记录使用 ──── Observed ────,不冒充 Tibo 原帖。没有有效来源链接时省略原文链接行。

手动测试推送

  1. 配置好群白名单并启用插件。
  2. 在配置页的“测试推送”分组,将 testPushToken 填为 1,保存配置。
  3. 插件加载后立即请求接口,选取 announced_at 最新的一条事件,向白名单群实际发送一次,消息开头增加独立的 [测试通知] 模拟推送,非新动态。 段落。
  4. 再次测试时,将批次改成 2、3 等不同的非空值并保存。也可直接修改 YAML:testPushToken: "2"。

测试忽略正式通知的事件类型和确认开关,即使该事件已经通知过或插件首次建立基线,也可以测试。原始事件的内容、时间、状态不做伪造,正式去重记录不会为测试而删除或重置。正常轮询仍同时运行,新事件可能另有一条不带测试标记的正式通知。

测试批次及待发送队列会持久化。同一批次不会因后续轮询、修改其他配置或重启而再次触发;失败的群按轮询间隔重试,已成功的群不重复发送。接口失败、无事件或白名单为空时,批次暂不消耗,条件满足后再触发。清空批次会取消剩余测试重试,改为新批次会替换旧的待重试测试。修改后请保存配置。插件关闭时不测试。测试沿用普通消息发送的事务限制,异常崩溃窗口仍可能重复。

本地验证

npm test
npm run build
npm run check:api

check:api 只读取真实接口、校验结构,打印一条预告样例及只读查询工具的记录摘要;不连接机器人、不调用模型、不发送群消息、不修改通知状态。

问答自动化测试使用模拟模型响应,覆盖两轮 tool calling、参数校验、静默分支、白名单、并发和取消。npm test 不会使用真实 API key、产生模型费用或发送群消息。模型的语义判断仍需通过真实调用检查。

本地模型联调

本地联调完全独立于 zssm,配置和测试集都放在本项目:

  • .env:保存 TIBO_AI_TEXT_ENDPOINT、TIBO_AI_TEXT_TOKEN、TIBO_AI_TEXT_MODEL。已被 Git 忽略且不进入安装包。
  • .env.example:不含密钥的配置模板。
  • test/local-questions.json:可自行修改、添加或删除问题的测试集。

脚本默认读取项目根目录的 .env,不依赖启动命令时的工作目录,也不会读取其他项目的配置。进程中已有的 TIBO_* 同名变量优先;需要其他本地配置时可以显式指定 --env-file。正式插件仍通过 Koishi 配置页配置模型,这些环境变量仅供本地脚本使用。

本地 .env 也可设置 TIBO_HTTP_400_RETRIES 和 TIBO_HTTP_RETRY_DELAY 来调整重试次数与基础间隔(秒),省略时默认分别为 2 和 1。

# 默认预览,不调用模型或重置接口
npm run test:local -- --suite

# 真实调用指定模型及只读重置接口,测试一个问题
npm run test:local -- --real "tibo 是否重置?"

# 真实运行 test/local-questions.json 中的全部问题
npm run test:local -- --real --suite

修改测试集后直接重跑即可。每项的 question 是问题;expectReply: true 表示预期回复,false 表示预期静默;只想观察实际回复时可以省略 expectReply:

[
  { "question": "什么时候重置?", "expectReply": true },
  { "question": "今天吃什么?", "expectReply": false },
  { "question": "我自己的新问题" }
]

不传问题也不加 --suite 时运行测试集的第一条。直接在命令末尾指定问题时,不要同时加 --suite。

真实测试需要显式加 --real,会消耗所配置模型的额度,重试也可能产生额外费用。脚本使用插件本身的模型客户端和查询逻辑,不连接机器人,不发送群消息,不创建或修改通知状态。输出问题、工具调用次数、查询次数、耗时和最终回答,并通过 Koishi 日志记录每次 HTTP 尝试,不输出 Authorization 或密钥。重试耗尽或遇到不重试的错误时停止剩余用例,避免连续无效请求。

内置用例包括 Tibo/Codex 是否重置、什么时候重置、重置卡是否发放,以及普通聊天、数据库密码重置、Codex 概念问答和翻译。相关问题应查询后回复,无关问题应不调用工具且不回复。路由 PASS 不代表回答内容绝对正确,仍应检查时间、批次、来源确认与模型措辞是否匹配。

使用 Gemini 兼容接口时,Koishi 的“AI 问答”配置为:

aiTextEndpoint: "https://generativelanguage.googleapis.com/v1beta/openai/"
aiTextToken: "在控制台填写你的密钥"
aiTextModel: "gemini-3.8-flash"

思考强度测速

插件和本地模型联调的两轮请求(工具选择、最终回答)均默认发送 reasoning_effort: "low"。

运行 npm run bench:thinking -- --real --repeats 2,使用本项目 .env 和测试集,对比未传 reasoning_effort 的默认模式与 low。脚本先探测 none;若接口接受,也会加入对比,但接受参数不等于已证明关闭思考。会产生真实模型调用费用,不发送群消息、不修改插件默认配置。

测速中的 default 指接口默认行为,会主动移除该参数,不是插件默认的 low。

各组使用相同问题、冻结的接口快照和当前时间,按问题交替运行,减少顺序影响;另行记录 HTTP 重试、失败和思考 token,缺失的 usage 字段记为未知而不是 0。reports/thinking-*.json 保存完整回答和统计,普通闲聊被本地预筛跳过的耗时不计入模型速度。小样本结果不代表长期延迟或全面的回答质量。

安装时 npm audit 报告 Koishi 的 file-type 传递依赖存在中等级别漏洞,关联框架依赖共 10 项。本插件只读取 JSON,不调用该媒体格式解析功能;未强制覆盖 Koishi 的依赖版本,部署方仍需跟进上游修复。

开发时核对了 Koishi 官方的配置构型、计时器及机器人文档:

  • https://koishi.chat/guide/plugin/schema
  • https://koishi.chat/api/service/timer
  • https://koishi.chat/api/core/bot