diff --git a/CHANGELOG.md b/CHANGELOG.md index 637b5ba..105cc00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## beta 1.2.6.1019 - 2026-10-19 22:26:26 + +- 冷门知识问答新增少女乐团派对、韩流和原神题库,并支持 `/知识问答 主题` 定向开题。 +- Unknown trivia topics now return the supported topic list, while automatic + quiz broadcasts still draw from the full trivia bank. + ## beta 1.2.5.1019 - 2026-10-19 22:12:52 - 冷门知识问答题库改为中文展示:题干、选项和解释不再混用英文词。 diff --git a/README.md b/README.md index 41404ff..d8834d1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ JWeBot 是运行于 Linux 的单群微信自动回复系统。它通过本地 OC 观察选定的微信窗口,将消息写入持久化 Edge 账本,调用经过审核的命令插件, 并通过带视觉确认的 GUI 发送链路回复。 -当前版本:`beta 1.2.5.1019`,更新时间:2026-10-19 22:12:52。 +当前版本:`beta 1.2.6.1019`,更新时间:2026-10-19 22:26:26。 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.5.1019 +beta 1.2.6.1019 ``` -Updated: 2026-10-19 22:12:52. +Updated: 2026-10-19 22:26:26. 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 3dada0e..051a633 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -beta 1.2.5.1019 +beta 1.2.6.1019 diff --git a/docs/command-catalog.md b/docs/command-catalog.md index 7946329..1106c6a 100644 --- a/docs/command-catalog.md +++ b/docs/command-catalog.md @@ -1,6 +1,6 @@ # JWeBot Command Catalog -Current baseline: `beta 1.2.5.1019`. +Current baseline: `beta 1.2.6.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, unless one is already active. | +| `/知识问答 [主题]` | - | Start a five-minute cold-knowledge quiz immediately, optionally limited to one supported topic. Supported topics: 反恐精英, 顶点英雄, 守望先锋, 英雄联盟, 少女乐团派对, 韩流, 原神. | | `/回答 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 4c4a81b..4f3c9d8 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.5b1+1019" +version = "1.2.6b1+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 f502ffb..d734763 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.5b1+1019" +__version__ = "1.2.6b1+1019" diff --git a/packages/jwebot-extension-host/pyproject.toml b/packages/jwebot-extension-host/pyproject.toml index 6b7eb5d..e1d6d5b 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.5b1+1019" +version = "1.2.6b1+1019" description = "Single-release, single-invocation process host for JWeBot extensions" requires-python = ">=3.9" dependencies = [ - "jwebot-sdk==1.2.5b1+1019", - "jwebot-kernel==1.2.5b1+1019", + "jwebot-sdk==1.2.6b1+1019", + "jwebot-kernel==1.2.6b1+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 012c8da..fa35b81 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.5b1+1019" +__version__ = "1.2.6b1+1019" diff --git a/packages/jwebot-kernel/pyproject.toml b/packages/jwebot-kernel/pyproject.toml index 80f5a23..3794e14 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.5b1+1019" +version = "1.2.6b1+1019" description = "Stable routing and extension authority for JWeBot" requires-python = ">=3.9" dependencies = [ - "jwebot-config==1.2.5b1+1019", - "jwebot-sdk==1.2.5b1+1019", - "jwebot-official-extensions==1.2.5b1+1019", + "jwebot-config==1.2.6b1+1019", + "jwebot-sdk==1.2.6b1+1019", + "jwebot-official-extensions==1.2.6b1+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 6701f13..384bca8 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.5b1+1019" +__version__ = "1.2.6b1+1019" diff --git a/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py b/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py index 7c1be6f..34c7a18 100644 --- a/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py +++ b/packages/jwebot-kernel/src/jwebot_kernel/edge_runtime.py @@ -166,6 +166,44 @@ TRIVIA_HISTORY_KEY = "trivia_quiz_history" TRIVIA_ANSWER_WINDOW_MINUTES = 5 TRIVIA_QUIZ_PROBABILITY_PERCENT = 75 TRIVIA_RECENT_BASE_LIMIT = 24 +TRIVIA_TOPIC_NAMES = ( + "反恐精英", + "顶点英雄", + "守望先锋", + "英雄联盟", + "少女乐团派对", + "韩流", + "原神", +) +TRIVIA_TOPIC_ALIASES = { + "反恐精英": "反恐精英", + "反恐": "反恐精英", + "cs": "反恐精英", + "cs2": "反恐精英", + "csgo": "反恐精英", + "顶点英雄": "顶点英雄", + "顶点": "顶点英雄", + "apex": "顶点英雄", + "守望先锋": "守望先锋", + "守望": "守望先锋", + "ow": "守望先锋", + "overwatch": "守望先锋", + "英雄联盟": "英雄联盟", + "联盟": "英雄联盟", + "lol": "英雄联盟", + "leagueoflegends": "英雄联盟", + "少女乐团派对": "少女乐团派对", + "邦邦": "少女乐团派对", + "gbp": "少女乐团派对", + "girlsbandparty": "少女乐团派对", + "bangdream": "少女乐团派对", + "韩流": "韩流", + "韩国流行音乐": "韩流", + "kpop": "韩流", + "原神": "原神", + "genshin": "原神", + "genshinimpact": "原神", +} BEIJING_TIMEZONE = ZoneInfo("Asia/Shanghai") ACKNOWLEDGEMENT = "已收到,正在处理中喵" STEAM_ACKNOWLEDGEMENT = "Steam 查询 [■□□] 正在读取公开数据" @@ -360,6 +398,21 @@ TRIVIA_FACTS: tuple[tuple[str, str, str, str, tuple[str, str, str], str, int], . ("lol-zac", "英雄联盟", "扎克名字常被解释为什么缩写?", "祖安无定形战斗体", ("祖安奥术核心", "时间装置自动体", "祖安酸液生物"), "扎克的名字常被当作祖安无定形战斗体的缩写梗。", 4), ("lol-kindred", "英雄联盟", "永猎双子由哪两个化身组成?", "羊灵和狼灵", ("乌鸦和雄鹿", "狐狸和猫头鹰", "太阳和月亮"), "永猎双子是羊灵与狼灵两个死亡化身。", 2), ("lol-ryze", "英雄联盟", "瑞兹长期收集并封存的危险物是什么?", "世界符文", ("暗裔武器", "海克斯核心", "虚空碎片"), "瑞兹的主线目标是阻止世界符文失控。", 3), + ("gbp-random-star", "少女乐团派对", "户山香澄使用的星形吉他昵称是什么?", "随机星", ("流星号", "闪耀心", "星光鸟"), "户山香澄的标志性星形吉他昵称是随机星。", 4), + ("gbp-hikawa-sisters", "少女乐团派对", "冰川双子里姐姐是谁?", "冰川纱夜", ("冰川日菜", "丸山彩", "今井莉莎"), "冰川纱夜是姐姐,冰川日菜是妹妹。", 3), + ("gbp-aya-idol", "少女乐团派对", "丸山彩所在乐队最核心的组合定位是?", "偶像乐队", ("幼驯染摇滚", "哥特交响", "欢乐马戏"), "丸山彩所在组合以偶像乐队定位为核心。", 3), + ("gbp-yukina-father", "少女乐团派对", "凑友希那坚持音乐的家庭原因主要和谁有关?", "父亲", ("姐姐", "祖母", "老师"), "凑友希那对音乐的执着,很大一部分和父亲的经历有关。", 4), + ("gbp-tsugumi-cafe", "少女乐团派对", "羽泽鸫家里经营的店更接近什么?", "咖啡店", ("唱片店", "花店", "乐器店"), "羽泽鸫家经营咖啡店,她也经常帮忙。", 3), + ("kpop-snsd-debut", "韩流", "少女时代的出道曲是哪首?", "再次重逢的世界", ("说出你的愿望", "哦", "狮心"), "少女时代的出道曲是再次重逢的世界。", 4), + ("kpop-redvelvet-leader", "韩流", "红贝贝的队长是谁?", "裴柱现", ("姜涩琪", "孙胜完", "朴秀荣"), "红贝贝的队长是裴柱现。", 3), + ("kpop-newjeans-fandom", "韩流", "新牛仔的官方粉丝名中文常译为什么?", "兔子", ("星星", "花园", "钥匙"), "新牛仔的官方粉丝名常译作兔子。", 4), + ("kpop-first-win", "韩流", "歌谣节目里常说的“一位”通常指什么?", "当期第一名", ("出道舞台", "安可失败", "投票资格"), "一位通常指某个歌谣节目当期排名第一。", 2), + ("kpop-lightstick", "韩流", "韩流演唱会里粉丝常用来应援的发光道具叫什么?", "应援棒", ("舞台牌", "投票券", "签售卡"), "应援棒是韩流现场应援里很常见的发光道具。", 2), + ("genshin-barbatos", "原神", "蒙德风神的真实魔神名是?", "巴巴托斯", ("摩拉克斯", "巴尔泽布", "布耶尔"), "蒙德风神温迪对应的魔神名是巴巴托斯。", 3), + ("genshin-morax", "原神", "璃月岩王帝君的魔神名是?", "摩拉克斯", ("巴巴托斯", "厄歌莉娅", "布耶尔"), "岩王帝君钟离对应的魔神名是摩拉克斯。", 3), + ("genshin-ei", "原神", "稻妻一心净土里的真正主人是谁?", "雷电影", ("雷电真", "八重神子", "九条裟罗"), "一心净土里的真正主人是雷电影。", 4), + ("genshin-nahida-title", "原神", "纳西妲作为神明对应的称号是?", "小吉祥草王", ("大慈树王", "尘世闲游", "正义之神"), "纳西妲在须弥被称为小吉祥草王。", 3), + ("genshin-neuvillette", "原神", "枫丹最高审判官是谁?", "那维莱特", ("莱欧斯利", "芙宁娜", "克洛琳德"), "那维莱特是枫丹的最高审判官。", 3), ) TRIVIA_TEMPLATES = ( "【{domain} 冷知识】{prompt}", @@ -378,12 +431,32 @@ def trivia_reward(rarity: int) -> int: return 20 + max(1, min(5, int(rarity))) * 30 +def trivia_topic_key(value: object) -> str: + return re.sub( + r"[\s'’`·・_\-::.。!!??]+", + "", + str(value or "").casefold(), + ) + + +def canonical_trivia_topic(value: object) -> str | None: + topic = trivia_topic_key(value) + if not topic: + return None + return TRIVIA_TOPIC_ALIASES.get(topic) + + +def supported_trivia_topics_message() -> str: + return "支持主题:" + "、".join(TRIVIA_TOPIC_NAMES) + + @lru_cache(maxsize=1) def trivia_question_bank() -> tuple[dict[str, object], ...]: questions: list[dict[str, object]] = [ { **question, "base_id": str(question["id"]), + "topic": canonical_trivia_topic(question.get("domain")) or str(question["domain"]), "rarity": int(question.get("rarity", 4)), "reward": trivia_reward(int(question.get("rarity", 4))), } @@ -399,6 +472,7 @@ def trivia_question_bank() -> tuple[dict[str, object], ...]: "id": f"{base_id}-{variant + 1}", "base_id": base_id, "domain": domain, + "topic": canonical_trivia_topic(domain) or domain, "question": template.format(domain=domain, prompt=prompt), "options": rotated, "answer": answer_label, @@ -6764,10 +6838,20 @@ class HourlyBroadcastEngine: *, group: str, local_now: datetime, + topic: str | None = None, ) -> dict[str, object]: - bank = trivia_question_bank() + bank = tuple( + question + for question in trivia_question_bank() + if topic is None or str(question.get("topic")) == topic + ) + if not bank: + raise LocalCommandError("这个主题还没有题喵\n" + supported_trivia_topics_message()) recent = set(self.trivia_recent_base_ids(group)) - seed = f"{group}|{local_now.date().isoformat()}|{local_now.hour:02d}|trivia" + seed = ( + f"{group}|{local_now.date().isoformat()}|" + f"{local_now.hour:02d}|trivia|{topic or 'all'}" + ) start = deterministic_int(seed, 0, len(bank) - 1) for offset in range(len(bank)): candidate = bank[(start + offset) % len(bank)] @@ -6783,8 +6867,15 @@ class HourlyBroadcastEngine: raise LocalCommandError("冷门问答题库选项无效") rarity = max(1, min(5, int(question.get("rarity", 3)))) reward = max(1, min(500, int(question.get("reward", trivia_reward(rarity))))) + topic = normalize_text(question.get("topic") or question.get("domain")) + heading = f"冷门知识问答(冷门度 {rarity}/5,限时5分钟,答对 +{reward} 摩拉)" + if topic: + heading = ( + f"冷门知识问答(主题:{topic},冷门度 {rarity}/5," + f"限时5分钟,答对 +{reward} 摩拉)" + ) lines = [ - f"冷门知识问答(冷门度 {rarity}/5,限时5分钟,答对 +{reward} 摩拉)", + heading, str(question.get("question", "")), ] lines.extend( @@ -6799,8 +6890,13 @@ class HourlyBroadcastEngine: *, group: str, local_now: datetime, + topic: str | None = None, ) -> str: - question = self.select_trivia_question(group=group, local_now=local_now) + question = self.select_trivia_question( + group=group, + local_now=local_now, + topic=topic, + ) message = self.render_trivia_message(question) expires_at = ( local_now + timedelta(minutes=TRIVIA_ANSWER_WINDOW_MINUTES) @@ -6811,6 +6907,7 @@ class HourlyBroadcastEngine: { "question_id": str(question["id"]), "base_id": str(question.get("base_id") or question["id"]), + "topic": str(question.get("topic") or question.get("domain") or ""), "question": str(question["question"]), "options": list(question["options"]), "answer": str(question["answer"]), @@ -6828,9 +6925,13 @@ class HourlyBroadcastEngine: self, *, group: str, + topic_name: str = "", now: datetime | None = None, ) -> str: local_now = self.in_beijing_timezone(now) + topic = canonical_trivia_topic(topic_name) + if normalize_text(topic_name) and topic is None: + return supported_trivia_topics_message() active = self.ledger.local_game(group, TRIVIA_GAME_KEY) if active: try: @@ -6839,7 +6940,11 @@ class HourlyBroadcastEngine: except (TypeError, ValueError): return "冷门问答状态坏了喵" self.ledger.clear_local_game(group, TRIVIA_GAME_KEY) - return self.start_trivia_question(group=group, local_now=local_now) + return self.start_trivia_question( + group=group, + local_now=local_now, + topic=topic, + ) def due_trivia_broadcast( self, @@ -8107,10 +8212,11 @@ class EdgeApplication: } if decision.execution_path is ExecutionPath.LOCAL_COMMAND: try: - command_kind = local_command_kind(str(row["question"])) + command_kind, command_arguments = local_command_parts(str(row["question"])) reply = ( self.clock.force_trivia_message( - group=str(row["group_fingerprint"]) + group=str(row["group_fingerprint"]), + topic_name=command_arguments, ) if command_kind == "trivia_start" else diff --git a/packages/jwebot-official-extensions/pyproject.toml b/packages/jwebot-official-extensions/pyproject.toml index a352de8..27e3b42 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.5b1+1019" +version = "1.2.6b1+1019" description = "Reviewed local command adapters and broker implementation for JWeBot" requires-python = ">=3.9" dependencies = [ - "jwebot-sdk==1.2.5b1+1019", + "jwebot-sdk==1.2.6b1+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 10ac972..33ec2dc 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.5b1+1019" +__version__ = "1.2.6b1+1019" diff --git a/packages/jwebot-official-extensions/src/jwebot_official_extensions/descriptors.py b/packages/jwebot-official-extensions/src/jwebot_official_extensions/descriptors.py index dd58ea1..d43eda6 100644 --- a/packages/jwebot-official-extensions/src/jwebot_official_extensions/descriptors.py +++ b/packages/jwebot-official-extensions/src/jwebot_official_extensions/descriptors.py @@ -153,8 +153,8 @@ DIRECT_KERNEL_COMMANDS = ( command_kinds=("deepseek_balance",), ), KernelCommandDescriptor( - description="手动触发冷门知识问答", - help_entries=("/知识问答",), + description="冷门问答", + help_entries=("/知识问答 [主题]",), command_kinds=("trivia_start",), ), ) diff --git a/packages/jwebot-sdk/pyproject.toml b/packages/jwebot-sdk/pyproject.toml index daa8fbe..9f66001 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.5b1+1019" +version = "1.2.6b1+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 874d279..fcedba2 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.5b1+1019" +__version__ = "1.2.6b1+1019" diff --git a/pyproject.toml b/pyproject.toml index b0340b0..0062f30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.jwebot] -release = "beta 1.2.5.1019" +release = "beta 1.2.6.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 23cb225..0b9face 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.5.1019", version["text"]) - self.assertIn("更新时间:2026-10-19 22:12:52", version["text"]) - self.assertIn("更新摘要:冷门知识问答题库改为中文展示", 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.assertEqual(debug["route"], "local") self.assertIn("调试埋点", debug["text"]) self.assertEqual(balance["route"], "local") @@ -1398,28 +1398,37 @@ class LedgerAndApplicationTests(unittest.TestCase): def test_trivia_quiz_can_be_started_by_local_command(self): self.application.deepseek.complete = mock.Mock(side_effect=AssertionError) + unknown = self.application.accept( + event("trivia-force-unknown", "@JWeBot /知识问答 星际") + ) first = self.application.accept( - event("trivia-force", "@JWeBot /知识问答") + event("trivia-force", "@JWeBot /知识问答 原神") ) second = self.application.accept( - event("trivia-force-existing", "@JWeBot /知识问答") + event("trivia-force-existing", "@JWeBot /知识问答 K-pop") ) + 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("回答格式:/回答 A", first["text"]) self.assertIn("已经有一题在进行中", second["text"]) + self.assertIn("原神", second["text"]) self.assertEqual( self.application.ledger.row("trivia-force")["status"], "local_completed", ) - self.assertIsNotNone( - self.application.ledger.local_game( - "group-a", - MODULE.TRIVIA_GAME_KEY, - ) + state = self.application.ledger.local_game( + "group-a", + MODULE.TRIVIA_GAME_KEY, ) + self.assertIsNotNone(state) + assert state is not None + 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 15f6c1a..eb8a653 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.5.1019" + release = "beta 1.2.6.1019" def setUp(self): self.temporary = tempfile.TemporaryDirectory()