能力声明地基 + 自撤回门控修复 + typing 指示器(Slice 1/5 of #19) #20

Closed
opened 2026-07-09 03:14:43 +00:00 by KumaAgent · 0 comments
KumaAgent commented 2026-07-09 03:14:43 +00:00 (Migrated from codeberg.org)

Parent

#19(Phase 3 PRD:能力与多模态)

What to build

新增 CapabilitySet(frozen dataclass):typing/recall/self_recall/edit/at_all/sticker/
voice/poke/poke_send/reaction_receive/reaction_send/quote/profile_like 共 13 个能力位,
全部默认 False。本片只消费其中 typing/self_recall/edit 三个,其余字段先占位供后续切片
(Slice 2/3/4)使用,不需要现在就实现对应行为。

ArisePorts 新增 capabilities: CapabilitySet 字段,host 在插件加载时随其它 port 一起声明,静态、
进程生命周期内不变(不做运行时探测)。移除 Config.arise_edit_capable,其行为完全迁移为
capabilities.editRuntimeLoop.__init__edit_capable: bool 参数改为
capabilities: CapabilitySet_handle_edit 改用 capabilities.edit

顺带修复一个既有 bug_handle_self_recall 对"已发送(非 pending)"的句柄目前无条件调用
egress.recall(),在不支持撤回的平台上会直接抛异常。本片补上 capabilities.self_recall 门控——
无该能力时 fail-closed,不产生任何平台调用,直接返回错误结果(同 handle not found 的处理方式);
pre-send(句柄仍在 state.pending)分支不变,纯 core 操作,不受影响。

新增 typing 能力:EgressPort 新增 send_typing_indicator(chat_id) -> None_flush 在长回复
实际发送前,若 capabilities.typing 为真则调用之。既有的 sleep pacing 逻辑(_typing_delay)不受
影响,那部分纯 core、一直生效,不需要任何能力。

Acceptance criteria

  • CapabilitySet frozen dataclass 声明全部 13 个能力位,全部默认 False
  • ArisePorts 新增 capabilities: CapabilitySet 字段,configure()/get_ports() 正常透传
  • Config.arise_edit_capable 已移除,代码库中无任何引用;capabilities.edit 完全取代其行为
  • RuntimeLoop.__init__edit_capable: bool 参数替换为 capabilities: CapabilitySet
    _handle_edit 改用 capabilities.edit
  • _handle_self_recall 对已发送句柄在 capabilities.self_recall=False 时不调用
    egress.recall(),返回明确的错误结果;有专门的回归测试覆盖这一行为(防止未来改动删掉这条
    门控,重新引入无条件调用的 bug)
  • EgressPort 新增 send_typing_indicator(chat_id) -> None 方法;_flush
    capabilities.typing=True 时、长回复实际发送前调用它;capabilities.typing=False 时跳过,
    不影响既有 sleep pacing
  • FakeEgress 扩展为接受 CapabilitySet(或等价具名布尔参数),新增记录
    typing_indicator_calls
  • 现有 test_self_message_control*.py/test_runtime_loop.py 测试套件全部通过(迁移到新构造
    参数后无回归)

Blocked by

None - can start immediately

## Parent [#19](https://codeberg.org/ProjectKuma/arise/issues/19)(Phase 3 PRD:能力与多模态) ## What to build 新增 `CapabilitySet`(frozen dataclass):`typing`/`recall`/`self_recall`/`edit`/`at_all`/`sticker`/ `voice`/`poke`/`poke_send`/`reaction_receive`/`reaction_send`/`quote`/`profile_like` 共 13 个能力位, 全部默认 `False`。本片只消费其中 `typing`/`self_recall`/`edit` 三个,其余字段先占位供后续切片 (Slice 2/3/4)使用,不需要现在就实现对应行为。 `ArisePorts` 新增 `capabilities: CapabilitySet` 字段,host 在插件加载时随其它 port 一起声明,静态、 进程生命周期内不变(不做运行时探测)。**移除 `Config.arise_edit_capable`**,其行为完全迁移为 `capabilities.edit`;`RuntimeLoop.__init__` 的 `edit_capable: bool` 参数改为 `capabilities: CapabilitySet`,`_handle_edit` 改用 `capabilities.edit`。 **顺带修复一个既有 bug**:`_handle_self_recall` 对"已发送(非 pending)"的句柄目前**无条件**调用 `egress.recall()`,在不支持撤回的平台上会直接抛异常。本片补上 `capabilities.self_recall` 门控—— 无该能力时 fail-closed,不产生任何平台调用,直接返回错误结果(同 `handle not found` 的处理方式); pre-send(句柄仍在 `state.pending`)分支不变,纯 core 操作,不受影响。 新增 `typing` 能力:`EgressPort` 新增 `send_typing_indicator(chat_id) -> None`;`_flush` 在长回复 实际发送前,若 `capabilities.typing` 为真则调用之。既有的 sleep pacing 逻辑(`_typing_delay`)不受 影响,那部分纯 core、一直生效,不需要任何能力。 ## Acceptance criteria - [ ] `CapabilitySet` frozen dataclass 声明全部 13 个能力位,全部默认 `False` - [ ] `ArisePorts` 新增 `capabilities: CapabilitySet` 字段,`configure()`/`get_ports()` 正常透传 - [ ] `Config.arise_edit_capable` 已移除,代码库中无任何引用;`capabilities.edit` 完全取代其行为 - [ ] `RuntimeLoop.__init__` 的 `edit_capable: bool` 参数替换为 `capabilities: CapabilitySet`, `_handle_edit` 改用 `capabilities.edit` - [ ] `_handle_self_recall` 对已发送句柄在 `capabilities.self_recall=False` 时不调用 `egress.recall()`,返回明确的错误结果;有专门的回归测试覆盖这一行为(防止未来改动删掉这条 门控,重新引入无条件调用的 bug) - [ ] `EgressPort` 新增 `send_typing_indicator(chat_id) -> None` 方法;`_flush` 在 `capabilities.typing=True` 时、长回复实际发送前调用它;`capabilities.typing=False` 时跳过, 不影响既有 sleep pacing - [ ] `FakeEgress` 扩展为接受 `CapabilitySet`(或等价具名布尔参数),新增记录 `typing_indicator_calls` - [ ] 现有 `test_self_message_control*.py`/`test_runtime_loop.py` 测试套件全部通过(迁移到新构造 参数后无回归) ## Blocked by None - can start immediately
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#20
No description provided.