host 权限 port is_admin + 四个运行时管理命令 #87
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/80-admin-commands"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #80
新增 host 权限回调
is_admin(chat_id, user_id)作为地基,在其上建四个运行时管理命令。命令形状沿用两条同意命令已验证过的on_command(..., rule=to_me(), priority=1, block=True);那两条是用户级授权(ADR-0027 拒绝与管理权限混用),本次不碰。四个 grill 决策
/setmodel走 host 回调set_model(chat_id, name) -> bool。 core 压根不认识模型:LLMClient只有complete(),provider/model 由 host 构造 client 时私有持有,AnyLLMClient的client_kwargs(api_base/api_key)更是只有 host 知道 —— core 自己重造客户端会静默丢掉它们(ADR-0011 明说第三方兼容端点必需 api_base),而故障要等下一次真实对话才暴露。返回布尔而非 None,host 说不行就如实说不行;host 没接回调时说"不支持",不假装成功。也因此不在 core 里建模型注册表 —— ADR-0020 已把「Routing 层 + /setmodel 语义变更」整体搁置。/settool只覆盖 host 工具。 core 那批由能力位/config 门控,其中send_message承重 —— 能被 per-chat 关掉就等于给了条把机器人变哑的路。存"被关掉的集合"而不是"启用集合":后者会让 host 新注册的工具对所有既有 chat 静默不可见。/reloadprompt把ArisePorts.persona静态字段换成get_persona(chat_id)回调(ADR-0001 2026-07-11 更新拍过板、从未落地)。命令报 persona 指纹而不是"已重载":host 自己缓存却没失效是这条命令最常见的失败模式,指纹没变时如实说没变并把线索指回 host,比回"已生效"有用。/diagnose默认探数据库/向量库/embedding,主模型要diagnose model才探。 现在探模型是一笔游离在记账外的消耗(记账/熔断在 #81/#82),正撞 user story 6。DependencyVerdict因此有skipped这个独立取值 —— "没探"渲染成"通过"这条命令就在撒谎。顺带处理的越界问题
arise_llm_provider/arise_llm_model:全仓消费者为零,host 自己造 client 注入,谁改都不会生效、只会让部署者以为配好了。/settool补齐深挖委托路径:subagent原本用未过滤的get_tools("background"),而委托恰恰是 host 工具消耗最重的一条 —— 命令承诺了它在那条路上没兑现的事。两轴 review 后修掉的(第二个 commit)
两轴独立撞上同一个生产级 bug:
/前缀下三个命令直接坏掉。 第一版自己按命令名切event.get_plaintext(),而 NoneBot 不改写 event message、COMMAND_START默认只有"/"——head是"/"非空,于是把整串当参数返回:settool恒回用法说明、diagnose model永不探模型、setmodel把"/setmodel gpt-4o"整串当模型名递给 host。所有单测都直调处理函数、不带前缀,一条都没抓到。 改用CommandArg()DI,逻辑抽成_run_*保持可直测,并新增走真实派发的测试文件补上取参数那一层(变异验证确认能复现全部三个症状)。get_persona(chat_id)我读错了 ADR。 我以为 PRD 提的这个"既有回调"是笔误(代码里确实不存在),实际 ADR-0001 明文拍过板、只是从未落地,立论正是"host 内多用户可切换人设、每人设独立 model/provider 路由"。已按 ADR 补回chat_id,set_model同理。Delta 压缩与反思两个跨 chat cycle 改收回调而不是 persona 对象 —— 它们本来就按 chat 循环,传对象等于拿某一个 chat 的人设去判所有 chat 的候选。/diagnose把str(exc)原样回进群里,而数据库异常常带 DSN(主机/库名/用户名,有时口令),同群非管理员都读得到。改成只回异常类名 + "详情见日志",完整异常进logger.exception。/setmodel成功时提醒arise_llm_multimodal_kinds不会跟着变:那是绑在主模型身份上的静态声明,而 ADR-0028 明令拒绝运行时探测多模态能力 —— core 既不自动改也不许去问,不提醒就是两种方向的静默失真。to_conversation_input(async host 回调,可能做媒体解析 IO),新增同步的IngressPort.sender_id_of;bool | None三态换Literal(同GateVerdict惯例);手抄的 context 元组换get_args(RuntimeContext);消掉那个只被测试调用的死函数(改成生产共用的visible_host_tools)。验证
1232 测试全绿。11 处变异逐条验过(权限闸放行 / 闸放到写操作之后 / 工具名不校验 / 把 host 拒绝渲染成成功 / 没接回调也假装成功 / 一律报已生效 / 默认就探模型 / 第一个探针失败即中断 / 工具过滤失效 / 只摘 schema 不摘分派表 / persona 被缓存),各自只挂对应测试。
三处变异没杀掉测试、据此改强了测试:① persona 那条原本只跑一轮对话,而"core 缓存 persona"的实现第一轮读到的就已经是新值 —— 改成跑两轮;②
/reloadprompt的"第一次记录"那支因为模块级状态不重置而实质未测 —— 补 autouse 重置 + 真正锁它的断言;③ 建表覆盖那条(#79 加的)期望集合取自被测函数自身 —— 已在 #79 改成独立枚举。KumaAgent referenced this pull request2026-07-28 03:07:41 +00:00