主人 2026-10-04 指示「项目仓库也可以写进去」。因此把 devdocs/ 从 .gitignore 移除并首次入库: - `05-开发进度与交接.md` —— 跨会话交接锚点:当前状态、易忘的实现约定、踩过的坑、实机验收方法 - `02-前后端协同事项.md` —— 与后端会话的**交换文档**(两边都会读写:我们登记缺口,对面写回执) - `01/03/04/06/07` + `DESIGN.md` —— 路线、客户端细化方案、构建环境、迁移说明、给后端会话的交接 **凭据扫描已过**:无账号口令、无 token/refreshToken 明文、无 API key 或私钥。 文档里只记「登录凭据不写进文档,问主人」这条口径本身。 (此前忽略它的理由已不成立:文档现在承担跨会话交接与前后端协同两件正事, 只留在本机磁盘会随机器丢失,而这批内容的价值恰恰在「后来人读得到」。)
8.2 KiB
8.2 KiB
01 — 功能拆解与分步路线(Cyrene-For-Android 讨论稿 v1)
配套
DESIGN.md(总览)。本文按分步展开:每模块给出「做什么 / 交互 / 数据流 / 依赖 / 验收 / 边界 / Miuix 组件映射」。状态:讨论稿,与主人在本会话逐模块细化后定稿。 前提(已定案):主界面=常规 AI APP;长按电源键=系统默认语音助手(VOICE_INTERACTION_SERVICE,全屏,无悬浮球);ASR/TTS 后端化;先纯文本版;UI 严格 Miuix(compose-miuix-ui)。
阶段 0 · 工程骨架
S0.1 工程搭建
- Gradle(版本目录)、Kotlin + Compose、
compose-miuix-ui依赖、BuildConfig.BASE_URL(debughttp://<host>:8080,release 换 HTTPS)、单 Moduleapp、包com.askaeth.cyrene.{app,core,data,domain,platform,ui}。 - 依赖:Retrofit+OkHttp、kotlinx-serialization、okhttp-WebSocket、EncryptedSharedPreferences、Hilt(可选)、Coil(图片)。
- 验收:
./gradlew :app:assembleDebug通过,App 能起空壳 Miuix 首页。 - 边界:暂不接后端。
阶段 1 · P0 纯文本聊天(零后端改动,契约现成)
S1.1 登录(已定稿 2026-09-08)
- 服务器地址可配(开源,各人部署地址不同):登录卡放「服务器地址」折叠项/入口,默认
http://<host>:8080,用户可改;存本地(EncryptedPrefs/DataStore)。 - 仅
.env单管理员(ADMIN_USERNAME/PASSWORD)可登录,无注册/找回;成功role=owner。 - 自动登录:默认记住 token(EncryptedPrefs),重启免登;仅
401/auth_expired才清 token 回登录。 - 报错:已建立连接(服务端有响应)时用服务端
{error.message};本地错误(连不上/证书/DNS/超时)由客户端本地文案负责——不把本机错误误当服务端文案。 - 密码默认隐藏(可切换明文)。
- 数据流:
AuthManager.login(baseUrl,username,password)→POST {base}/api/v1/auth/login→{token,expiresAt,role}→EncryptedPrefs存(baseUrl+token+role+expiresAt)→HomeScreen。 - 状态机:
Idle→Loading→Success(Home)|Error(msg)(error.from==="server"用后端message,"local"用本地文案);登录中禁用按钮防连点;登录失败不清已存 token。
S1.2 会话列表(已定稿 2026-09-08)
- 主结构 = A:启动直接进主会话「与昔涟」(
web) 聊天;顶栏汉堡 → 侧边栏含【会话列表(切主/次级)+ IoT + App 设置 + 登出】。 - 列表显示:主会话="与昔涟",次级="会话 2/N"(按序号,title 自动,零后端改动);无预览/时间(后端
/sessions只有 id)。 - 新建:侧栏"+"新建次级(
POST /sessions→sessionId→ 切进去)。 - 删除:次级长按/滑出 → 确认
Dialog→DELETE /sessions/{id};主会话禁删(提示"主会话不可删")。 - 切换:侧栏会话列表点选 → 切聊天页。
- 数据流:
GET /api/v1/sessions(主会话web恒首位)。依赖:S1.1。验收:启动即主会话聊天;侧栏可切/建/删次级;主会话不可删;重启记住上次会话(可后续)。
S1.3 聊天页:历史加载(已定稿 2026-09-08)
- 数据流:
GET /sessions/{id}/messages?limit=50&before=<ms>&platform=倒序返回,客户端逆序渲染(最新在底)。platform不传 = 看全量主会话(a,能同步 web/kook/微信所有主会话消息)。 - 分页:初始 50 条;上拉加载更多用
before=<最早时间>再往前翻(50 步进),追加顶部。 - 消息来源标识:每条消息默认显示来源(
platform/deviceId小字角标,如"来自 web" / "来自 kook" / "来自微信" / "来自安卓(voiceassist)")——主人既定诉求。 - 时间:完全隐藏(不显示时间戳/分组,对话沉浸)。
- 空态:主会话无消息 → 昔涟欢迎语。
- 依赖:S1.2。验收:进会话拉 50 条倒序展示;上拉翻 50/页;每条标来源;无时间戳。
S1.4 聊天页:发消息 + 流式(已定稿 2026-09-08)
- 发消息:WS
/ws/chat上行chat {sessionId,text,deviceId}(stream 流式);本地乐观追加自己消息。 - 流式渲染:下行
message.start开气泡 →message.delta逐段追加(气泡尾+光标)→message.end收口。 - 流式期间新消息 = 两种模式(用户可切,默认「追加队列」):
① 追加队列(新消息进队列,流式结束后依次处理——豆包式);
② 打断(新消息触发
interrupt,保留残缺上下文 + 显示"打断"提示)。 - 思维链
thinking/ 工具卡tool_call:默认展开(方便观察思维;可折叠 + "总是收起"开关)。 - 旁白
<action>/<narration>:灰斜体小字,按出现位置依附气泡上/下。 mood:显示情绪标签(可关)。- 渲染:
<p>拆气泡;图片;忙态session_busy/pending_*提示;409/202兜底。
S1.5 侧边栏(汉堡抽屉)
- 做什么:顶栏左上汉堡 →
Drawer侧边栏:当前会话/聊天、[预留] IoT 入口、[预留] App 设置入口、登出。 - 数据流:登出 → 清 token + 断开 WS → 回登录。
- 验收:汉堡展开侧栏;IoT/设置点开显示"规划中"(Miuix 空态);登出回登录页。
- 边界:侧栏入口预留(P0 占位不真做)。
S1.6 401 / token 过期
- 做什么:REST 401 →
auth_expired清 token 停 WS → 回登录;WS 握手失败同理。 - 验收:JWT 过期或轮换后,下条请求自动登出重登,不无限 reconnect。
阶段 2 · P1 语音助手(后端 ASR/TTS,依赖本会话 TTS/ASR 进程接通后端)
S2.1 系统默认语音助手
- 做什么:Manifest 声明
VOICE_INTERACTION_SERVICE/AssistantService(android:role="Assist"),用户在系统「语音助手/电源键」设本 App 默认 → 长按电源键由系统拉起本 AppAssistantActivity(全屏)。 - 依赖:系统设置入口(MIUI 自家更顺);Android 版本/厂商适配。
- 验收:长按电源键 → 本 App 全屏助手打开(无悬浮球)。
S2.2 全屏助手 UI(AssistantActivity)
- 做什么:聆听动画 → 已识别文本(ASR 结果)→ 昔涟回复(流式)→ 重听/TTS;按钮:结束/放弃/再次说话。全程单页全屏,Miuix 玻璃质感。
- 验收:说话 → 文本上屏 → 昔涟回复 + 朗读。
S2.3 语音闭环(后端 ASR/TTS)
- 链路:录音(
MediaRecorder/AudioRecord)→ REST 上传到后端(音频→ASR)→ 文本 →POST /api/v1/chat {text,deviceId}(或 WS)→ 昔涟回复 → 后端 TTS 返回音频 → 本端播放。voice_output(WS)也可拿音频。 - 依赖:后端 ASR/TTS 真接通(本会话 TTS/ASR 进程:真实 STT/TTS provider + REST 语音端点绕 4KB +
voice_input.deviceId)。 - 验收:对话 3 轮语音一问一答;IM 渠道(微信/KOOK)语音也走同一后端 ASR/TTS。
阶段 3 · P2 智能
- IoT:设备/场景列表(Miuix;预留接口
GET /api/v1/iot/*)。 - App 设置:主题(Miuix 深/浅)、通知开关、语音偏好(ASR/TTS 后端已定)、关于。
- 主动推送:后端 proactive/backthink → 系统通知;前台服务保活(可选)。
- 多角色:
GET /personas只读展示;切换人格。 - 记忆/子代理/自主思考:只读面板(
memory/subagent/backthink过滤器)。
跨模块约定
- deviceId:
voiceassist:myapp:v1(design/16 §4.5),所有chat/voice_input携带 → 落库标来源、跨端可辨。 - 主会话同步:Android 加入
web主会话,与 Web/IM 共享上下文;渲染按platform区分"本端/他端"(design/16 §4.4)。 - Miuix 映射:
TopAppBar(汉堡/标题)、Scaffold+Drawer(侧栏)、气泡(自定义BubbleView或 Miuix 卡片+毛玻璃)、TextField、Button(发送/语音)、Snackbar/Dialog(确认/错误)。禁原生 Material。 - 安全红线:token 加密存储、401 即登出、权限最小化、无悬浮球、不打日志敏感。