release: public alpha 0.6.0 baseline
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
"""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",
|
||||
}
|
||||
|
||||
|
||||
@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="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.author}/{descriptor.extension_id}] "
|
||||
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()
|
||||
Reference in New Issue
Block a user