# LineUp App — Android Spike 历史设计参考 > 状态:**仅保留为 Android 快速实验的历史/参考设计,不是当前 App Layer 总体架构。** > 原版本:0.1(提案) > 日期:2026-07-30 > 基础:唐僧叨叨 Android 客户端(wkbase / wklogin / SDK 封装) 当前正式、跨端的 LineUp App 总体架构以 [LineUp App 层架构设计方案](../设计/02.正式方案/lineup-app-layer-architecture.md) 为准:Tauri 2 是当前 Reference Host,Android 为 Spike 基线,未来 Wails 按同一 Interaction Runtime 契约对照实现。本文件中的“Android 首端”“直接使用 WuKongIM SDK”等描述只反映当时的实验条件,不能覆盖正式架构、协议或实现优先级。 --- ## 1. 定位 LineUp App 是一个**单通道 Agent 对话客户端**。用户打开 App 后只有一个对话——和他的 AI Agent。 不是社交 IM(没有好友列表、没有群聊、没有朋友圈)。 当前版本只做一件事:**连上 WuKongIM,进入唯一频道,与 Agent 收发消息。** ``` ┌──────────────────────────────────────────┐ │ LineUp App │ │ │ │ ┌───────────────────────────────┐ │ │ │ Agent 对话频道 │ │ │ │ │ │ │ │ [用户] 帮我查一下今天天气 │ │ │ │ [Agent] 北京今天晴, 22°C │ │ │ │ [Agent] ┌─ choice ─┐ │ │ │ │ │ 需要更多? │ │ │ │ │ │ [是] [否] │ │ │ │ │ └───────────┘ │ │ │ └───────────────────────────────┘ │ │ │ │ ┌───────────────────────────────┐ │ │ │ 输入框 │ │ │ └───────────────────────────────┘ │ └──────────────────────────────────────────┘ ``` --- ## 2. 架构分层 ``` ┌──────────────────────────────────────┐ │ LineUp App (Android) │ │ │ │ UI 层: 聊天界面 + Agent 消息渲染 │ │ ├─ ChatView (文本/图片/语音) │ │ └─ AgentWidgets (choice/form/canvas) │ │ │ │ 业务层: 频道管理 + 消息路由 │ │ ├─ ChannelManager (只有一个频道) │ │ └─ MessageRouter (分发到UI) │ │ │ │ 通讯层: WuKongIM SDK 封装 │ │ ├─ WKClient (长连接/心跳/重连) │ │ ├─ WKSend / WKRecv │ │ └─ TokenManager (认证) │ │ │ │ 本地存储: SQLite / SharedPreferences │ │ ├─ Token 缓存 │ │ └─ 消息历史 (最近N条) │ └──────────────────────────────────────┘ ``` ### 2.1 复用唐僧叨叨的模块 | 唐僧叨叨模块 | 用途 | LineUp 是否复用 | |---|---|---| | `wklogin` | 登录 / 注册 / Token 获取 | ✅ 复用 | | `wkbase` | 基础 UI / WebSocket 连接 / 消息模型 | ✅ 复用核心 | | `wkpush` | 厂商推送 | ❌ 暂不需要 | | `wkscan` | 扫码 | ❌ 不需要 | | 群聊/通讯录/朋友圈 | — | ❌ 隐藏/移除 | **核心思路:保留通信管道,砍掉社交外壳。** --- ## 3. 连接流程 ### 3.1 首次启动 ``` Step 1: 用户打开 App → 输入手机号 → 点"获取验证码" → 输入 123456 → App 调 LineUp App Server: POST /login → Server 调 WuKongIM /user/token 生成 Token → 返回 {uid, token, im_host, im_port} Step 2: App 用 Token 连接 WuKongIM WebSocket → ws://100.121.118.116:15200?token=xxx → WuKongIM 返回 Connack → 连接建立 Step 3: App 进入唯一频道 → 频道 ID: "agent_default" (硬编码) → App 调 WuKongIM Sub 帧订阅该频道 → 收到 Suback → 可以收发消息 Step 4: 显示对话界面 → 同步最近 N 条消息 (channel/messagesync) → 等待用户输入 ``` ### 3.2 后续启动(Token 未过期) ``` Step 1: 读取本地缓存的 Token Step 2: 直接连 WuKongIM WebSocket Step 3: 跳过登录页,直接进入对话 ``` ### 3.3 Agent 也在同一个频道 ``` 用户的 WuKongIM 用户: uid="user_" Agent 的 WuKongIM 用户: uid="agent_default" 频道 ID: "agent_default_channel" 频道类型: 个人频道 (channel_type=1) 用户 → Send(频道) → WuKongIM → Recv → Agent Agent → Send(频道) → WuKongIM → Recv → App ``` --- ## 4. 消息类型 ### 4.1 普通文本消息 用户发什么就送什么,Agent 回文本也直接显示。 ### 4.2 LineUp 结构化消息(信封格式) 沿用设计文档定义的信封协议: ```json { "v": 1, "id": "msg_xxx", "type": "lineup.v1.tool.call", "sender": {"kind": "agent", "id": "agent_default"}, "target": {"kind": "device", "id": "device_phone_01"}, "payload": {} } ``` ### 4.3 第一批支持的 Agent 工具消息 | 类型 | 触发条件 | UI 渲染 | |---|---|---| | `lineup.v1.tool.choice` | Agent 需要用户做选择 | 渲染为可点击的选项按钮 | | `lineup.v1.tool.confirm` | Agent 需要用户确认操作 | 渲染确认/取消按钮 | | `lineup.v1.tool.input` | Agent 需要用户输入值 | 渲染输入框 | | `lineup.v1.tool.progress` | Agent 报告进度 | 渲染进度条 | | `lineup.v1.event.error` | Agent 报错 | 渲染错误提示 | **这些 payload 通过 WuKongIM 的 SendPacket.Payload 字段传递,App 收到后解析 type 字段决定渲染方式。** ### 4.4 通用 UI Surface 与上层 App 能力 除内置文本、Markdown、choice、confirm、progress 等稳定组件外,LineUp Client 还支持受控的 UI Surface:Agent 可发送 `lineup.v1.ui.open`,以 HTML/CSS/JS 描述一个交互界面;后续以 `ui.patch` 推送状态,以 `ui.event` 接收用户动作,以 `ui.close` 关闭实例。 这不是把 Agent 脚本放进 App 主进程执行。Android 端必须在隔离 WebView 中承载 Surface,禁用任意网络访问、文件访问、同源权限和未注册的 JavaScript interface。Surface 只能通过受限 bridge 上报用户事件。 Agent 若要调用 App 的上层能力(例如打开链接、选文件、写剪贴板、相机、定位或业务模块),必须走独立的 `lineup.v1.app.list` → `app.call` → `app.result` 协议:Client 先声明 capability,再按风险等级弹出用户确认或系统授权,绝不允许 Surface 直接越权调用。本协议详见 [LineUp UI Surface 与 App Capability 协议](../设计/02.正式方案/lineup-ui-surface-protocol.md)。 --- ## 5. UI 设计 ### 5.1 消息渲染规则 ``` if payload 为空: → 普通文本消息,照常显示 if payload.type == "lineup.v1.tool.choice": → 渲染为选项卡片 → 用户点击某个选项后: → App 组装 tool.result Payload → Send 回 Agent if payload.type == "lineup.v1.tool.progress": → 渲染为进度条卡片 → 被动显示,无需用户操作 ``` ### 5.2 登录页 ``` ┌──────────────────────┐ │ │ │ LineUp │ │ 你的 AI 搭档 │ │ │ │ ┌──────────────────┐│ │ │ +86 手机号 ││ │ └──────────────────┘│ │ ┌────────┐ ┌──────┐ │ │ │ 验证码 │ │ 获取 │ │ │ └────────┘ └──────┘ │ │ │ │ [ 登 录 ] │ │ │ └──────────────────────┘ ``` ### 5.3 主界面 ``` ┌──────────────────────────────┐ │ Agent (在线) ··· │ ← 顶部栏:Agent名称+在线状态 ├──────────────────────────────┤ │ │ │ [Agent] 你好,我是你的 AI │ │ 助手,有什么可以帮 │ │ 助你的? │ │ │ │ [用户] 帮我查天气 │ │ │ │ [Agent] ┌─ 选择城市 ────┐ │ │ │ ○ 北京 │ │ │ │ ○ 上海 │ │ │ │ ● 深圳 │ │ │ │ [确认] │ │ │ └────────────────┘ │ │ │ ├──────────────────────────────┤ │ ┌────────────────────┐ 📎 │ ← 输入栏 │ │ 输入消息... │ 📷 │ │ └────────────────────┘ 🎤 │ └──────────────────────────────┘ ``` --- ## 6. 服务端交互协议 ### 6.1 App → LineUp App Server | API | 方法 | 用途 | |---|---|---| | `/login` | POST | 手机号+验证码 → {uid, token, im_addr} | | `/ws` | WebSocket | App 维持与 Server 的长连接(接收 Server 推送) | ### 6.2 App → WuKongIM (直连) | 操作 | 方向 | 协议 | |---|---|---| | 连接 | App → WK | WKProto Connect (带 Token) | | 发消息 | App → WK | WKProto Send (频道+Payload) | | 收消息 | WK → App | WKProto Recv | | 同步消息 | App → WK | channel/messagesync | | 心跳 | 双向 | WKProto Ping/Pong | --- ## 7. 与唐僧叨叨 App 的差异 | 功能 | 唐僧叨叨 | LineUp App | |---|---|---| | 登录 | 手机号+验证码 / 第三方 | 手机号+验证码(简化版) | | 主界面 | 会话列表(多聊天) | **直接进入唯一 Agent 对话** | | 通讯录 | 好友+群组+工作台 | 无 | | 发现页 | 朋友圈+附近 | 无 | | 消息类型 | 文本/图片/语音/文件/位置 | 文本 + Agent 工具卡片 | | 设置 | 隐私/通知/通用 | 极简(仅退出/重置) | | WuKongIM 连接 | `wkbase` SDK 封装 | 复用 `wkbase` 核心 | | 服务端 | 唐僧叨叨业务层 | LineUp App Server | --- ## 8. 实施计划 ### Phase 1: 最小通信通路(1-2天) ``` 目标: 能登录、连 WuKongIM、收发文本消息 □ 基于唐僧叨叨 wklogin + wkbase 创建简化版 App 壳 □ 移除所有非必要模块(群聊/通讯录/朋友圈) □ 登录后直连 WuKongIM WebSocket □ 硬编码频道 ID,进入固定对话 □ 能发送和接收文本消息 ``` ### Phase 2: Agent 工具消息渲染(2-3天) ``` 目标: 能解析 LineUp 信封,渲染 choice/confirm/progress □ 实现 Payload 解析器 □ choice 卡片 → 选项按钮列表 □ confirm 卡片 → 确认/取消按钮 □ progress 卡片 → 进度条 □ 用户操作后组装 tool.result 回传给 Agent ``` ### Phase 3: UI 美化 + 体验优化(2-3天) ``` 目标: 不再是粗制原型,而是可用产品 □ 对话气泡 UI 优化 □ Agent 在线状态指示 □ 消息发送状态(发送中/已送达) □ 启动动画 / 过渡效果 □ 错误处理(断网/超时) ``` --- ## 9. 参考资料 - 唐僧叨叨 Android 源码: `upstream/tangsengdaodao-android/` - LineUp App Server 设计: `lineup-app-server/DESIGN.md` - WuKongIM JS SDK: `@wukongim/sdk-js` (Agent 端用) - LineUp App 层架构: `设计/02.正式方案/lineup-app-layer-architecture.md` - 消息信封与 UI Surface 定义: `设计/02.正式方案/lineup-ui-surface-protocol.md`