Skip to content

Latest commit

 

History

History
381 lines (295 loc) · 9.91 KB

File metadata and controls

381 lines (295 loc) · 9.91 KB

AUN Daemon Protocol v0.1 (MVP)

AUN Mac App(Swift)与后端 Python daemon 之间的通信协议。

  • 传输:daemon 以子进程方式启动,通过 stdin(请求)与 stdout(响应 + 事件)通信
  • 编码:UTF-8 NDJSON —— 每行一个 JSON 对象,以 \n 结束
  • 日志:daemon 运行时日志写 stderr禁止混入 stdout
  • 阻塞:daemon 内部用 asyncio,不会阻塞 stdin;前端可并发发请求

启动命令

python3 /path/to/aun_daemon.py [--data-dir /path/to/.aun]

环境变量(可选):

  • AUN_CLI_DATA — 数据根目录(默认 ~/.aun)。与 --data-dir 等效,命令行优先

消息三类

1. Request(Swift → Python)

{"id": 1, "method": "initialize", "params": {}}
  • id 由前端递增,必须为整数
  • params 可省略

2. Response(Python → Swift,必有 id

成功:

{"id": 1, "result": {"aid": "alice.agentid.pub", "target": null}}

失败:

{"id": 1, "error": {"code": "NO_AID", "message": "No AID configured", "recoverable": true}}

3. Event(Python → Swift, id

{"event": "message_received", "data": {"from": "bob.agentid.pub", "text": "hi", "ts": 1715000000000}}

MVP Methods(v0.1,共 7 个)

initialize

建立 AUNClient 连接、认证、订阅事件。Swift 端在 daemon 启动后必须先发这个。

Request

{"id": 1, "method": "initialize", "params": {"aid": "alice.agentid.pub"}}
  • params.aid(可选):若省略则读 ~/.aun/aun-cli/config.json 里的 aid。两者都没有则返回 NO_AID 错误

Response

{"id": 1, "result": {
  "aid": "alice.agentid.pub",
  "target": {"type": "peer", "id": "bob.agentid.pub", "name": "bob"},
  "recent_targets": [
    {"type": "peer", "id": "bob.agentid.pub", "name": "bob"}
  ],
  "gateway": "wss://gateway.agentid.pub:20001/aun",
  "sdk_version": "0.2.12"
}

行为

  • 加载 AID → 认证 → 连接网关 → 注册 message.received 等回调
  • 成功后 daemon 会额外发一个 ready 事件(见下)
  • connect 完成前返回失败则发 error 事件 + error 响应

set_target

切换当前对话目标。

Request

{"id": 2, "method": "set_target", "params": {"aid": "carol.agentid.pub"}}
  • params.aid:peer AID
  • MVP 不支持 group target

Response

{"id": 2, "result": {"target": {"type": "peer", "id": "carol.agentid.pub", "name": "carol"}}}

错误码

  • INVALID_AID:AID 格式不合法

send_text

向当前 target 发送文本消息。

Request

{"id": 3, "method": "send_text", "params": {"text": "Hello", "encrypt": true}}
  • params.text(必选):消息正文
  • params.encrypt(可选,默认 true):是否 E2EE

Response

{"id": 3, "result": {
  "message_id": "msg_abc",
  "target": {"type": "peer", "id": "carol.agentid.pub", "name": "carol"},
  "ts": 1715000000000
}}

错误码

  • NO_TARGET:未设置 target
  • NOT_CONNECTED:网关断开且重连失败
  • SEND_FAILED:SDK 返回错误(data 字段含原始错误)

list_messages

读历史消息(DB 里拉)。

Request

{"id": 4, "method": "list_messages", "params": {
  "target_id": "carol.agentid.pub",
  "limit": 50,
  "before_id": null
}}
  • target_id(必选):peer AID 或 group id
  • limit(可选,默认 50,最大 200)
  • before_id(可选):分页游标。返回消息里最小的 id 传入即可取更早的一批

Response

{"id": 4, "result": {
  "messages": [
    {
      "id": 101,
      "message_id": "msg_abc",
      "conversation_id": "carol.agentid.pub",
      "conversation_type": "peer",
      "direction": "sent",
      "sender": "alice.agentid.pub",
      "text": "Hello",
      "seq": null,
      "ts": 1715000000000,
      "is_read": 1
    }
  ]
}}

消息按 ts 升序返回。

list_recent_targets

最近会话列表。

Request

{"id": 5, "method": "list_recent_targets"}

Response

{"id": 5, "result": {
  "targets": [
    {"type": "peer", "id": "bob.agentid.pub", "name": "bob"},
    {"type": "peer", "id": "carol.agentid.pub", "name": "carol"}
  ]
}}

get_status

快照式查询连接状态。

Request

{"id": 6, "method": "get_status"}

Response

{"id": 6, "result": {
  "connected": true,
  "aid": "alice.agentid.pub",
  "target": {"type": "peer", "id": "carol.agentid.pub", "name": "carol"},
  "gateway": "wss://gateway.agentid.pub:20001/aun"
}}

shutdown

优雅关闭 daemon。Response 返回后 daemon 会断开网关并退出进程。

Request

{"id": 7, "method": "shutdown"}

Response

{"id": 7, "result": {"ok": true}}

Swift 端收到响应后应等待进程真正退出(process.waitUntilExit())。


MVP Events

ready

initialize 完成后触发,前端应在收到这个事件后才允许进入正常使用状态。

{"event": "ready", "data": {
  "aid": "alice.agentid.pub",
  "target": {"type": "peer", "id": "carol.agentid.pub", "name": "carol"},
  "gateway": "wss://gateway.agentid.pub:20001/aun"
}}

message_received

收到对端消息。

{"event": "message_received", "data": {
  "message_id": "msg_xyz",
  "from": "carol.agentid.pub",
  "conversation_id": "carol.agentid.pub",
  "conversation_type": "peer",
  "text": "Hi there",
  "seq": 42,
  "ts": 1715000000000,
  "e2ee": true
}}

备注:

  • 群消息 MVP 不发此事件(后续版本再加)
  • text 是渲染友好的文本。结构化 payload(文件附件等)在 v0.2 通过独立事件/字段扩展

message_sent

本端发送成功后推送(即使 send_text 响应返回也会发,便于多客户端同步)。

{"event": "message_sent", "data": {
  "message_id": "msg_abc",
  "target": {"type": "peer", "id": "carol.agentid.pub", "name": "carol"},
  "text": "Hello",
  "ts": 1715000000000
}}

connection_state

{"event": "connection_state", "data": {
  "state": "connected",
  "reason": null
}}

state 取值:connecting | connected | disconnected | reconnecting

error

Daemon 层面的异步错误(非某次请求的响应)。

{"event": "error", "data": {
  "code": "GATEWAY_DISCONNECTED",
  "message": "WebSocket closed unexpectedly",
  "recoverable": true
}}

错误码表(MVP)

code 含义 recoverable
NO_AID 未配置 AID,且 initialize 未传 false
AID_NOT_FOUND AID 本地密钥库中不存在 false
AUTH_FAILED 网关认证失败 true
GATEWAY_DISCONNECTED 已连接的网关掉线 true
NOT_CONNECTED 当前未连接到网关 true
NO_TARGET 操作前未 set_target false
INVALID_AID AID 格式不合法 false
SEND_FAILED SDK 发送失败(data 里有原始 error) 视情况
INVALID_PARAMS 请求参数 schema 不符 false
INTERNAL_ERROR daemon 内部异常 false
UNKNOWN_METHOD 未识别的 method false

JSON-RPC 风格错误对象:

{"code": "SEND_FAILED", "message": "...", "recoverable": true, "data": {...}}

启动时序

Swift                   Python daemon
  │                          │
  │── spawn process ────────>│
  │                          │
  │                          │ (import, setup, no output yet)
  │                          │
  │── {"id":1,"method":      │
  │    "initialize",...} ───>│
  │                          │── 加载 AID
  │                          │── authenticate
  │                          │── connect gateway
  │                          │── 订阅事件
  │                          │
  │<── {"id":1,"result":...} │
  │<── {"event":"ready",...} │
  │<── {"event":"connection  │
  │     _state","data":      │
  │     {"state":"connected" │
  │     }} │                 │
  │                          │
  │── 正常使用期 ────────────│
  │                          │
  │── {"id":99,"method":     │
  │    "shutdown"} ─────────>│
  │<── {"id":99,"result":...}│
  │                          │── 断开网关,清理,exit(0)
  │<── (stdout closed) ──────│

Swift 集成约定

  1. 行解析:读取 stdout 按 \n 分行;每行解析为 JSON,event 字段存在则分发到事件流,否则按 id 匹配 pending request
  2. 请求超时:建议 30s,超时则标记该 id 失败,但不要杀进程(daemon 可能还在处理)
  3. 进程崩溃:若 stdout EOF 或 process 退出码 ≠ 0,UI 显示"连接丢失"并提示重启 daemon
  4. 启动等待:spawn 后最多等 15s 收到 ready 事件;超时则判定启动失败并 kill -9
  5. 关闭顺序:先发 shutdown → 等 response → process.waitUntilExit(超过 5s 再 kill)
  6. stderr:默认重定向到日志文件,不要丢,排查问题靠它

未来扩展(v0.2+)

为了保持 v0.1 协议简洁,以下内容暂未实现,但已为扩展预留空间:

方向 方法/事件
群组 list_groups, create_group, join_group, leave_group, list_group_members, group_event
文件 send_file, list_files, download_file, file_received
身份 list_aids, create_aid, switch_aid, delete_aid
富文本 消息 payload 扩展为 {type, text, attachments, mentions}
@提及 list_group_members + payload.mentions
通知 peer_presence, typing, read_receipt
诊断 set_debug, get_logs, log 事件

扩展原则:

  • 新增 method / event 不影响旧字段
  • 请求参数新增字段必须可选
  • 响应新增字段必须可选
  • 废弃字段保留至少两个小版本