Files
JWeBot/packages/jwebot-official-extensions/src/jwebot_official_extensions/descriptors.py
T
2026-10-15 15:17:32 +08:00

351 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Ownership map for Kernel commands and reviewed local extensions."""
from __future__ import annotations
from dataclasses import dataclass
LOCAL_COMMAND_ALIASES = {
"功能列表": "feature_list",
"帮助": "feature_list",
"help": "feature_list",
"丢骰子": "dice",
"骰子": "dice",
"丢骰子挑战": "dice_challenge",
"骰子挑战": "dice_challenge",
"翻硬币": "coin",
"随机数": "random_number",
"抽签": "draw_lot",
"今日运势": "daily_fortune",
"猜数字": "guess_number",
"猜": "guess_number",
"石头剪刀布": "rps",
"记住": "remember",
"我的记忆": "my_memory",
"忘记": "forget_memory",
"人物记忆": "person_memory",
"记忆帮助": "memory_help",
"扫码排行": "scan_ranking",
"扫码榜": "scan_ranking",
"今日扫码": "scan_ranking",
"复读榜": "repeat_ranking",
"复读": "repeat_ranking",
"查记录": "history_search",
"历史搜索": "history_search",
"状态": "local_status",
"status": "server_status",
"version": "jwebot_version",
"debug": "telemetry_debug",
"余额": "deepseek_balance",
"steam": "steam_friends",
"上下文": "context_summary",
"context": "context_summary",
"金币": "wallet",
"wallet": "wallet",
"抽奖": "prize_draw",
"draw": "prize_draw",
"彩票": "lottery",
"买彩票": "lottery",
"lottery": "lottery",
"21点": "blackjack",
"二十一点": "blackjack",
"blackjack": "blackjack",
"游戏记录": "game_history",
"个人记录": "game_history",
"gamehistory": "game_history",
"游戏帮助": "game_rules",
"games": "game_rules",
"人物列表": "person_directory",
"别名列表": "person_directory",
"people": "person_directory",
"人物": "person_info",
"个人属性": "person_info",
"person": "person_info",
"自走棋": "cs_autochess",
"cs自走棋": "cs_autochess",
"autochess": "cs_autochess",
"选": "cs_autochess",
"刷新": "cs_autochess",
"锁定": "cs_autochess",
"战术": "cs_autochess",
"升级教练": "cs_autochess",
"上阵": "cs_autochess",
"下阵": "cs_autochess",
"出售": "cs_autochess",
"阵容": "cs_autochess",
"赛程": "cs_autochess",
"结束回合": "cs_autochess",
}
@dataclass(frozen=True)
class LocalExtensionDescriptor:
extension_id: str
author: str
description: str
help_entries: tuple[str, ...]
command_kinds: tuple[str, ...]
@property
def directory(self) -> str:
return self.author.casefold()
@property
def commands(self) -> tuple[str, ...]:
owned = set(self.command_kinds)
return tuple(
f"/{alias}"
for alias, kind in LOCAL_COMMAND_ALIASES.items()
if kind in owned
)
@dataclass(frozen=True)
class KernelCommandDescriptor:
description: str
help_entries: tuple[str, ...]
command_kinds: tuple[str, ...]
OFFICIAL_AUTHOR = "official"
JWEBOT_AUTHOR = "jwebot"
DIRECT_KERNEL_COMMANDS = (
KernelCommandDescriptor(
description="查看由插件元数据自动生成的功能列表",
help_entries=("/功能列表(别名 /帮助、/help)",),
command_kinds=("feature_list",),
),
KernelCommandDescriptor(
description="查看 DeepSeek 账户余额",
help_entries=("/余额",),
command_kinds=("deepseek_balance",),
),
)
DIRECT_KERNEL_COMMAND_KINDS = frozenset(
kind
for descriptor in DIRECT_KERNEL_COMMANDS
for kind in descriptor.command_kinds
)
LOCAL_EXTENSIONS = (
LocalExtensionDescriptor(
extension_id="context-summary",
author=OFFICIAL_AUTHOR,
description="提取当前群最近100、200或300条本地文字的上下文",
help_entries=("/上下文 [100|200|300];/context [100|200|300]",),
command_kinds=("context_summary",),
),
LocalExtensionDescriptor(
extension_id="single-player-games",
author=JWEBOT_AUTHOR,
description="虚拟金币账户、抽奖、群内多人彩票和单人21点",
help_entries=(
"/金币 /wallet;/抽奖 [金额] /draw;/游戏记录 /gamehistory",
"/彩票 开始|报名|当前状态|开奖|取消;/lottery",
"/21点 开始 [1~500](金额=本局下注,默认50,空格可省略)",
"/21点 要牌|停牌|状态|结束;/blackjack hit|stand|status|end",
"/游戏帮助;/games",
),
command_kinds=(
"wallet",
"prize_draw",
"lottery",
"blackjack",
"game_history",
"game_rules",
),
),
LocalExtensionDescriptor(
extension_id="cs-major-autochess",
author=JWEBOT_AUTHOR,
description="CS自走棋",
help_entries=("/自走棋开始|报名",),
command_kinds=("cs_autochess",),
),
LocalExtensionDescriptor(
extension_id="person-directory",
author=OFFICIAL_AUTHOR,
description="查询当前群已配置人物、基本属性和别名",
help_entries=("/人物列表 [页码] /people;/人物 [名称或别名] /person",),
command_kinds=("person_directory", "person_info"),
),
LocalExtensionDescriptor(
extension_id="person-memory",
author=OFFICIAL_AUTHOR,
description="管理个人和同群人物记忆",
help_entries=(
"/记住 内容;/我的记忆;/忘记 关键词或全部;"
"/人物记忆 [显示名]",
),
command_kinds=(
"remember",
"my_memory",
"forget_memory",
"person_memory",
"memory_help",
),
),
LocalExtensionDescriptor(
extension_id="server-status",
author=OFFICIAL_AUTHOR,
description="服务器状态",
help_entries=("/状态;/status",),
command_kinds=("local_status", "server_status"),
),
LocalExtensionDescriptor(
extension_id="jwebot-version",
author=OFFICIAL_AUTHOR,
description="JWeBot 版本",
help_entries=("/version",),
command_kinds=("jwebot_version",),
),
LocalExtensionDescriptor(
extension_id="debug-telemetry",
author=OFFICIAL_AUTHOR,
description="埋点 p50/p95",
help_entries=("/debug",),
command_kinds=("telemetry_debug",),
),
LocalExtensionDescriptor(
extension_id="dice",
author=JWEBOT_AUTHOR,
description="骰子和多人骰子挑战",
help_entries=(
"/丢骰子 [NdM]",
"/丢骰子挑战 [5d6|5d20|状态|结算|战绩|结束]",
),
command_kinds=("dice", "dice_challenge"),
),
LocalExtensionDescriptor(
extension_id="coin",
author=JWEBOT_AUTHOR,
description="抛一枚硬币",
help_entries=("/翻硬币",),
command_kinds=("coin",),
),
LocalExtensionDescriptor(
extension_id="random-number",
author=JWEBOT_AUTHOR,
description="在指定整数范围内取随机数",
help_entries=("/随机数 最小值 最大值",),
command_kinds=("random_number",),
),
LocalExtensionDescriptor(
extension_id="draw-lot",
author=JWEBOT_AUTHOR,
description="抽取一条本地签文",
help_entries=("/抽签",),
command_kinds=("draw_lot",),
),
LocalExtensionDescriptor(
extension_id="daily-fortune",
author=JWEBOT_AUTHOR,
description="生成当天稳定一致的运势",
help_entries=("/今日运势",),
command_kinds=("daily_fortune",),
),
LocalExtensionDescriptor(
extension_id="guess-number",
author=JWEBOT_AUTHOR,
description="群内持久化猜数字游戏",
help_entries=(
"/猜数字 开始 [上限];/猜 数字;/猜数字 [状态|结束]",
),
command_kinds=("guess_number",),
),
LocalExtensionDescriptor(
extension_id="rock-paper-scissors",
author=JWEBOT_AUTHOR,
description="多人石头剪刀布游戏",
help_entries=(
"/石头剪刀布 [开始|加入|出 选择|状态|结算|结束]",
),
command_kinds=("rps",),
),
LocalExtensionDescriptor(
extension_id="scan-ranking",
author=JWEBOT_AUTHOR,
description="查看北京时间今日扫码排行",
help_entries=("/扫码排行",),
command_kinds=("scan_ranking",),
),
LocalExtensionDescriptor(
extension_id="repeat-ranking",
author=JWEBOT_AUTHOR,
description="查看北京时间今日复读排行",
help_entries=("/复读榜",),
command_kinds=("repeat_ranking",),
),
LocalExtensionDescriptor(
extension_id="history-search",
author=JWEBOT_AUTHOR,
description="搜索本地群聊文字记录",
help_entries=("/查记录 关键词",),
command_kinds=("history_search",),
),
LocalExtensionDescriptor(
extension_id="steam-presence",
author=JWEBOT_AUTHOR,
description="Steam 状态与时长",
help_entries=(
"/steam;/steam时长 游戏[、玩家]",
),
command_kinds=("steam_friends",),
),
)
def extension_for_kind(kind: str) -> LocalExtensionDescriptor | None:
return next(
(
extension
for extension in LOCAL_EXTENSIONS
if kind in extension.command_kinds
),
None,
)
def render_feature_list() -> str:
lines = ["功能列表(由内核和插件描述自动生成)"]
for descriptor in DIRECT_KERNEL_COMMANDS:
lines.append(
f"[内核] {descriptor.description}:"
+ ";".join(descriptor.help_entries)
)
for descriptor in LOCAL_EXTENSIONS:
lines.append(
f"{descriptor.description}:"
+ ";".join(descriptor.help_entries)
)
lines.extend(
(
"[DeepSeek] 普通 @JWeBot 消息走本地直连 DeepSeek",
"[OpenClaw] @JWeBot #任务进入 OpenClaw",
)
)
return "\n".join(lines)
def _validate_inventory() -> None:
extension_kinds = [
kind
for extension in LOCAL_EXTENSIONS
for kind in extension.command_kinds
]
if len(extension_kinds) != len(set(extension_kinds)):
raise RuntimeError("local extension command ownership overlaps")
known_kinds = set(LOCAL_COMMAND_ALIASES.values())
if set(extension_kinds) | DIRECT_KERNEL_COMMAND_KINDS != known_kinds:
raise RuntimeError("local command inventory is incomplete")
if set(extension_kinds) & DIRECT_KERNEL_COMMAND_KINDS:
raise RuntimeError("Kernel commands cannot be extension-owned")
if any(
not extension.description or not extension.help_entries
for extension in LOCAL_EXTENSIONS
):
raise RuntimeError("local extensions must provide help metadata")
_validate_inventory()