diff --git a/CHANGELOG.md b/CHANGELOG.md index 105cc00..579fbe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## beta 1.2.7.1019 - 2026-10-19 22:37:40 + +- 冷门知识问答新增缪斯学园偶像和我的世界题库,并支持 LoveLive 与 Minecraft 主题别名。 +- LoveLive trivia is limited to μ's-only facts, while displayed trivia content + remains localized in Chinese. + ## beta 1.2.6.1019 - 2026-10-19 22:26:26 - 冷门知识问答新增少女乐团派对、韩流和原神题库,并支持 `/知识问答 主题` 定向开题。 diff --git a/README.md b/README.md index d8834d1..468e4b7 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ JWeBot 是运行于 Linux 的单群微信自动回复系统。它通过本地 OC 观察选定的微信窗口,将消息写入持久化 Edge 账本,调用经过审核的命令插件, 并通过带视觉确认的 GUI 发送链路回复。 -当前版本:`beta 1.2.6.1019`,更新时间:2026-10-19 22:26:26。 +当前版本:`beta 1.2.7.1019`,更新时间:2026-10-19 22:37:40。 1.0 Beta 收口了当前稳定功能:本地命令插件、人物与上下文索引、 Steam 状态与时长查询、虚拟摩拉游戏、多人彩票、21 点、CS Major @@ -90,7 +90,7 @@ PATH="$PWD/.venv/bin:$PATH" ./tools/check-local.sh /21点 开始 [1~500];开局后 /21点 要牌|停牌|状态|结束 /21点 多人 启动;/21点 加入;/21点 多人 开始;/21点 放200 /摩拉(兼 /原石);/原石祈愿;/原石榜;/扫码加权 人名(24小时+5);/Taffy发话 内容 -/知识问答 [主题];支持主题:反恐精英、顶点英雄、守望先锋、英雄联盟、少女乐团派对、韩流、原神;/回答 A +/知识问答 [主题];支持主题:反恐精英、顶点英雄、守望先锋、英雄联盟、少女乐团派对、韩流、原神、缪斯学园偶像、我的世界;/回答 A /游戏记录 [页码](/gamehistory) /游戏记录 [页码](/gamehistory) /游戏帮助(/games) @@ -270,10 +270,10 @@ visually confirmed GUI bridge. Current version: ```text -beta 1.2.6.1019 +beta 1.2.7.1019 ``` -Updated: 2026-10-19 22:26:26. +Updated: 2026-10-19 22:37:40. The 1.0 Beta baseline consolidates the stable local command set, person and context indexes, Steam presence/playtime queries, virtual coin games, diff --git a/VERSION b/VERSION index 051a633..19a1444 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -beta 1.2.6.1019 +beta 1.2.7.1019 diff --git a/docs/command-catalog.md b/docs/command-catalog.md index 1106c6a..dbeb46a 100644 --- a/docs/command-catalog.md +++ b/docs/command-catalog.md @@ -1,6 +1,6 @@ # JWeBot Command Catalog -Current baseline: `beta 1.2.6.1019`. +Current baseline: `beta 1.2.7.1019`. This catalog records the reviewed commands shipped with the built-in local extensions. Runtime ownership is frozen at startup from the generated @@ -51,7 +51,7 @@ descriptor inventory; plugin code delegates to reviewed service profiles. | `/扫码加权 人名` | `/扫码概率 人名` | Spend a scan-boost ticket or 1 primogem to give that person +5 hourly scan weight for 24 hours. | | `/Taffy发话 内容` | `/taffysay content` | Spend Taffy speech credit; 1 primogem converts to 2 credits when needed. | | `/Taffy发话 定时 HH:MM 内容` | - | Schedule a Taffy speech through the guarded clock delivery queue. | -| `/知识问答 [主题]` | - | Start a five-minute cold-knowledge quiz immediately, optionally limited to one supported topic. Supported topics: 反恐精英, 顶点英雄, 守望先锋, 英雄联盟, 少女乐团派对, 韩流, 原神. | +| `/知识问答 [主题]` | - | Start a five-minute cold-knowledge quiz immediately, optionally limited to one supported topic. Supported topics: 反恐精英, 顶点英雄, 守望先锋, 英雄联盟, 少女乐团派对, 韩流, 原神, 缪斯学园偶像, 我的世界. English aliases like `LoveLive` and `Minecraft` are accepted as input. | | `/回答 A` | `/answer A` | Answer the active five-minute cold-knowledge quiz for a rarity-based Mora reward. | | `/抽奖 [金额]` | `/draw` | Play a single-player prize draw. | | `/彩票 开始` | `/lottery start` | Open a multiplayer lottery round. | diff --git a/packages/jwebot-config/pyproject.toml b/packages/jwebot-config/pyproject.toml index 4f3c9d8..0274ea2 100644 --- a/packages/jwebot-config/pyproject.toml +++ b/packages/jwebot-config/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-config" -version = "1.2.6b1+1019" +version = "1.2.7b1+1019" description = "Profile-based configuration compiler for JWeBot" requires-python = ">=3.9" dependencies = [ diff --git a/packages/jwebot-config/src/jwebot_config/__init__.py b/packages/jwebot-config/src/jwebot_config/__init__.py index d734763..2cc32b4 100644 --- a/packages/jwebot-config/src/jwebot_config/__init__.py +++ b/packages/jwebot-config/src/jwebot_config/__init__.py @@ -36,4 +36,4 @@ __all__ = [ "write_default_profile", ] -__version__ = "1.2.6b1+1019" +__version__ = "1.2.7b1+1019" diff --git a/packages/jwebot-extension-host/pyproject.toml b/packages/jwebot-extension-host/pyproject.toml index e1d6d5b..e21a4bc 100644 --- a/packages/jwebot-extension-host/pyproject.toml +++ b/packages/jwebot-extension-host/pyproject.toml @@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-extension-host" -version = "1.2.6b1+1019" +version = "1.2.7b1+1019" description = "Single-release, single-invocation process host for JWeBot extensions" requires-python = ">=3.9" dependencies = [ - "jwebot-sdk==1.2.6b1+1019", - "jwebot-kernel==1.2.6b1+1019", + "jwebot-sdk==1.2.7b1+1019", + "jwebot-kernel==1.2.7b1+1019", ] [project.scripts] diff --git a/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py b/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py index fa35b81..b5962b3 100644 --- a/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py +++ b/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py @@ -16,4 +16,4 @@ __all__ = [ "process_request", ] -__version__ = "1.2.6b1+1019" +__version__ = "1.2.7b1+1019" diff --git a/packages/jwebot-kernel/pyproject.toml b/packages/jwebot-kernel/pyproject.toml index 3794e14..e30ff15 100644 --- a/packages/jwebot-kernel/pyproject.toml +++ b/packages/jwebot-kernel/pyproject.toml @@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-kernel" -version = "1.2.6b1+1019" +version = "1.2.7b1+1019" description = "Stable routing and extension authority for JWeBot" requires-python = ">=3.9" dependencies = [ - "jwebot-config==1.2.6b1+1019", - "jwebot-sdk==1.2.6b1+1019", - "jwebot-official-extensions==1.2.6b1+1019", + "jwebot-config==1.2.7b1+1019", + "jwebot-sdk==1.2.7b1+1019", + "jwebot-official-extensions==1.2.7b1+1019", "tomli>=2; python_version < '3.11'", ] diff --git a/packages/jwebot-kernel/src/jwebot_kernel/__init__.py b/packages/jwebot-kernel/src/jwebot_kernel/__init__.py index 384bca8..6b04f75 100644 --- a/packages/jwebot-kernel/src/jwebot_kernel/__init__.py +++ b/packages/jwebot-kernel/src/jwebot_kernel/__init__.py @@ -107,4 +107,4 @@ __all__ = [ "verify_installed_release_signature", ] -__version__ = "1.2.6b1+1019" +__version__ = "1.2.7b1+1019" diff --git a/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py b/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py index 34c7a18..32b3a7a 100644 --- a/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py +++ b/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py @@ -174,6 +174,8 @@ TRIVIA_TOPIC_NAMES = ( "少女乐团派对", "韩流", "原神", + "缪斯学园偶像", + "我的世界", ) TRIVIA_TOPIC_ALIASES = { "反恐精英": "反恐精英", @@ -203,6 +205,15 @@ TRIVIA_TOPIC_ALIASES = { "原神": "原神", "genshin": "原神", "genshinimpact": "原神", + "缪斯学园偶像": "缪斯学园偶像", + "缪斯": "缪斯学园偶像", + "μs": "缪斯学园偶像", + "muse": "缪斯学园偶像", + "lovelive": "缪斯学园偶像", + "lovelive!": "缪斯学园偶像", + "我的世界": "我的世界", + "mc": "我的世界", + "minecraft": "我的世界", } BEIJING_TIMEZONE = ZoneInfo("Asia/Shanghai") ACKNOWLEDGEMENT = "已收到,正在处理中喵" @@ -413,6 +424,22 @@ TRIVIA_FACTS: tuple[tuple[str, str, str, str, tuple[str, str, str], str, int], . ("genshin-ei", "原神", "稻妻一心净土里的真正主人是谁?", "雷电影", ("雷电真", "八重神子", "九条裟罗"), "一心净土里的真正主人是雷电影。", 4), ("genshin-nahida-title", "原神", "纳西妲作为神明对应的称号是?", "小吉祥草王", ("大慈树王", "尘世闲游", "正义之神"), "纳西妲在须弥被称为小吉祥草王。", 3), ("genshin-neuvillette", "原神", "枫丹最高审判官是谁?", "那维莱特", ("莱欧斯利", "芙宁娜", "克洛琳德"), "那维莱特是枫丹的最高审判官。", 3), + ("lovelive-homura", "缪斯学园偶像", "高坂穗乃果家里经营的店主要卖什么?", "和果子", ("拉面", "唱片", "可丽饼"), "高坂穗乃果家经营和果子店,店名是穗村。", 3), + ("lovelive-nico-catchphrase", "缪斯学园偶像", "矢泽妮可最有代表性的招呼语是哪一句?", "妮可妮可妮", ("哈拉秀", "加油露比", "全力前进"), "矢泽妮可的标志性口号是妮可妮可妮。", 2), + ("lovelive-kotori-mother", "缪斯学园偶像", "南小鸟的母亲在学校里是什么身份?", "理事长", ("学生会长", "音乐老师", "校医"), "南小鸟的母亲是音乃木坂学院理事长。", 4), + ("lovelive-eli-roots", "缪斯学园偶像", "绚濑绘里常被提到的血统和哪个国家有关?", "俄罗斯", ("芬兰", "德国", "法国"), "绚濑绘里有俄罗斯血统,这也是角色设定里常被提到的点。", 4), + ("lovelive-maki-family", "缪斯学园偶像", "西木野真姬家的家庭背景最接近哪一种?", "医生家庭", ("神社家庭", "点心店家庭", "花店家庭"), "西木野真姬出身医生家庭。", 3), + ("lovelive-umi-role", "缪斯学园偶像", "园田海未在组合创作里经常负责哪一项?", "作词", ("编舞", "服装设计", "摄影"), "园田海未经常负责歌词创作。", 3), + ("lovelive-hanayo-rice", "缪斯学园偶像", "小泉花阳特别喜欢哪种食物?", "白米饭", ("鲷鱼烧", "番茄", "可乐饼"), "小泉花阳对白米饭有很强的热爱。", 2), + ("lovelive-nozomi-council", "缪斯学园偶像", "东条希在学生会里的职位是什么?", "副会长", ("会长", "书记", "风纪委员"), "东条希在学生会担任副会长。", 3), + ("minecraft-creeper-origin", "我的世界", "苦力怕最初的造型来源和哪种生物建模失误有关?", "猪", ("鸡", "牛", "羊"), "苦力怕的经典造型源自早期猪模型尺寸写错。", 5), + ("minecraft-repeater-delay", "我的世界", "红石中继器单个最多能设为几红石刻延迟?", "四红石刻", ("二红石刻", "六红石刻", "八红石刻"), "红石中继器单个最多四红石刻延迟。", 3), + ("minecraft-dragon-xp", "我的世界", "末影龙首次被击败时会掉落多少经验?", "一万二千", ("五千", "八千", "两万"), "末影龙首次死亡会掉落一万二千经验。", 4), + ("minecraft-netherite-ingot", "我的世界", "下界合金锭需要下界合金碎片再加哪种材料合成?", "金锭", ("铁锭", "钻石", "远古残骸"), "下界合金锭由下界合金碎片和金锭合成。", 3), + ("minecraft-shulker", "我的世界", "潜影贝主要自然生成在哪里?", "末地城", ("远古城市", "林地府邸", "海底神殿"), "潜影贝主要自然生成在末地城。", 3), + ("minecraft-wither-summon", "我的世界", "召唤凋灵需要摆放哪种头颅?", "凋灵骷髅头颅", ("骷髅头颅", "僵尸头颅", "龙首"), "召唤凋灵需要灵魂类方块和凋灵骷髅头颅。", 3), + ("minecraft-allay-vote", "我的世界", "悦灵是通过哪类官方活动胜出的生物?", "生物投票", ("愚人节快照", "节日活动", "地图竞赛"), "悦灵来自官方生物投票。", 4), + ("minecraft-warden-biome", "我的世界", "监守者机制主要关联哪个地下区域?", "深暗之域", ("繁茂洞穴", "滴水石洞穴", "下界荒地"), "监守者机制主要关联深暗之域和幽匿尖啸体。", 4), ) TRIVIA_TEMPLATES = ( "【{domain} 冷知识】{prompt}", diff --git a/packages/jwebot-official-extensions/pyproject.toml b/packages/jwebot-official-extensions/pyproject.toml index 27e3b42..f8e6bed 100644 --- a/packages/jwebot-official-extensions/pyproject.toml +++ b/packages/jwebot-official-extensions/pyproject.toml @@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-official-extensions" -version = "1.2.6b1+1019" +version = "1.2.7b1+1019" description = "Reviewed local command adapters and broker implementation for JWeBot" requires-python = ">=3.9" dependencies = [ - "jwebot-sdk==1.2.6b1+1019", + "jwebot-sdk==1.2.7b1+1019", ] [tool.setuptools.packages.find] diff --git a/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py b/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py index 33ec2dc..5134a0b 100644 --- a/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py +++ b/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py @@ -90,4 +90,4 @@ __all__ = [ "render_feature_list", ] -__version__ = "1.2.6b1+1019" +__version__ = "1.2.7b1+1019" diff --git a/packages/jwebot-sdk/pyproject.toml b/packages/jwebot-sdk/pyproject.toml index 9f66001..72a9fec 100644 --- a/packages/jwebot-sdk/pyproject.toml +++ b/packages/jwebot-sdk/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-sdk" -version = "1.2.6b1+1019" +version = "1.2.7b1+1019" description = "Typed, capability-limited extension API for JWeBot plugins" requires-python = ">=3.9" dependencies = [] diff --git a/packages/jwebot-sdk/src/jwebot_sdk/__init__.py b/packages/jwebot-sdk/src/jwebot_sdk/__init__.py index fcedba2..1460c3c 100644 --- a/packages/jwebot-sdk/src/jwebot_sdk/__init__.py +++ b/packages/jwebot-sdk/src/jwebot_sdk/__init__.py @@ -38,4 +38,4 @@ __all__ = [ "SingleGroupContext", ] -__version__ = "1.2.6b1+1019" +__version__ = "1.2.7b1+1019" diff --git a/pyproject.toml b/pyproject.toml index 0062f30..beab4cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.jwebot] -release = "beta 1.2.6.1019" +release = "beta 1.2.7.1019" production_deployments_enabled_by_default = false [tool.jwebot.workspace] diff --git a/tests/test_jwebot_edge.py b/tests/test_jwebot_edge.py index 0b9face..0dc500a 100644 --- a/tests/test_jwebot_edge.py +++ b/tests/test_jwebot_edge.py @@ -1035,9 +1035,9 @@ class LedgerAndApplicationTests(unittest.TestCase): self.assertEqual(version["route"], "local") self.assertIn("JWeBot 版本", version["text"]) self.assertIn("kernel", version["text"]) - self.assertIn("最新版本:beta 1.2.6.1019", version["text"]) - self.assertIn("更新时间:2026-10-19 22:26:26", version["text"]) - self.assertIn("更新摘要:冷门知识问答新增少女乐团派对、韩流和原神题库", version["text"]) + self.assertIn("最新版本:beta 1.2.7.1019", version["text"]) + self.assertIn("更新时间:2026-10-19 22:37:40", version["text"]) + self.assertIn("更新摘要:冷门知识问答新增缪斯学园偶像和我的世界题库", version["text"]) self.assertEqual(debug["route"], "local") self.assertIn("调试埋点", debug["text"]) self.assertEqual(balance["route"], "local") @@ -1332,6 +1332,17 @@ class LedgerAndApplicationTests(unittest.TestCase): ) self.assertFalse(any("A" <= character <= "Z" for character in display_text)) self.assertFalse(any("a" <= character <= "z" for character in display_text)) + topics = {str(question["topic"]) for question in bank} + self.assertIn("缪斯学园偶像", topics) + self.assertIn("我的世界", topics) + self.assertEqual( + MODULE.canonical_trivia_topic("LoveLive!"), + "缪斯学园偶像", + ) + self.assertEqual( + MODULE.canonical_trivia_topic("Minecraft"), + "我的世界", + ) ledger = self.application.ledger observed_at = MODULE.datetime( 2026, @@ -1402,22 +1413,24 @@ class LedgerAndApplicationTests(unittest.TestCase): event("trivia-force-unknown", "@JWeBot /知识问答 星际") ) first = self.application.accept( - event("trivia-force", "@JWeBot /知识问答 原神") + event("trivia-force", "@JWeBot /知识问答 LoveLive!") ) second = self.application.accept( - event("trivia-force-existing", "@JWeBot /知识问答 K-pop") + event("trivia-force-existing", "@JWeBot /知识问答 Minecraft") ) self.assertIn("支持主题:", unknown["text"]) self.assertIn("原神", unknown["text"]) self.assertIn("少女乐团派对", unknown["text"]) + self.assertIn("缪斯学园偶像", unknown["text"]) + self.assertIn("我的世界", unknown["text"]) self.assertEqual(first["route"], "local") self.assertEqual(first["execution_path"], "local-command") self.assertIn("冷门知识问答", first["text"]) - self.assertIn("原神", first["text"]) + self.assertIn("缪斯学园偶像", first["text"]) self.assertIn("回答格式:/回答 A", first["text"]) self.assertIn("已经有一题在进行中", second["text"]) - self.assertIn("原神", second["text"]) + self.assertIn("缪斯学园偶像", second["text"]) self.assertEqual( self.application.ledger.row("trivia-force")["status"], "local_completed", @@ -1428,7 +1441,7 @@ class LedgerAndApplicationTests(unittest.TestCase): ) self.assertIsNotNone(state) assert state is not None - self.assertEqual(state["topic"], "原神") + self.assertEqual(state["topic"], "缪斯学园偶像") self.application.deepseek.complete.assert_not_called() def test_ambient_chat_cooldown_keeps_next_hour_scan_broadcast(self): diff --git a/tests/test_release_update.py b/tests/test_release_update.py index eb8a653..c8a3cda 100644 --- a/tests/test_release_update.py +++ b/tests/test_release_update.py @@ -20,7 +20,7 @@ SPEC.loader.exec_module(MODULE) class ReleaseUpdateTests(unittest.TestCase): - release = "beta 1.2.6.1019" + release = "beta 1.2.7.1019" def setUp(self): self.temporary = tempfile.TemporaryDirectory()