Commit Graph

56 Commits

Author SHA1 Message Date
Kevin
897f49f2ab feat(app-expo): tiered large-text presets with English-friendly default
Replace the boolean large-text flag with three global typography tiers,
defaulting new installs to the smallest tier when English is in effect
while preserving legacy storage and Chinese defaults. Add a profile
sub-screen to pick the tier and unit tests for storage resolution.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 16:47:29 +08:00
Kevin
8f6c2a6a34 chore(app-expo): regenerate i18n Resources types
Sync generated resources.ts with locale keys (e.g. profile.personalInfo.tapAwayToClose for avatar sheet a11y).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 16:19:32 +08:00
Kevin
eabda2c6a9 chore: resolve WIP after merging internal/development
- .gitignore: keep api/uploads ignore and copyright_source_listing.pdf path

- auth: keep COS avatar upload URL; delete prior COS object when applying preset

- i18n: regenerate resources.ts (includes profile tapAwayToClose)

- Avatar/COS tests and personal-info remain from prior local work

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 15:34:50 +08:00
Kevin
ddc701f22d fix(voice): queue split TTS segments after pause without replacing track
Detect consecutive tts_auto items on the same assistant bubble via listKey (uuid_seg_n / uuid_part_n). When paused, skip the 'clear queue and play latest only' path so later segments enqueue instead of wiping playback. Add regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 17:25:44 +08:00
Kevin
6f41574bda feat(memoir): persist chapter reading prefs globally
Share font size, font family, and background across all memoir chapters via MemoirReadingSettingsProvider and SecureStore (same app-settings pattern). Add parse/merge helpers and unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 17:23:02 +08:00
Kevin
c4d2a38b09 feat(expo): 后台超过 5 分钟才断开会话 WebSocket
- 进入 background 后延迟释放长连,回到前台则取消计时;短切应用保持连接
- 池支持 subscribeConversationPoolSlotDisposed;聊天页在槽位释放时同步状态
- 前台 active 时按需 connect 或重绑会话
- backgroundDisconnectAfterMs 默认 300_000(5 分钟)

未纳入:api/uploads/ 本地文件

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 17:12:08 +08:00
Kevin
6f6ac0d550 fix: 头像缓存版本号;移除回忆录撰写入口跳转聊天
- API:上传/预设头像 URL 追加 ?v=time.time_ns(),避免同路径缓存导致「只能换一次头像」
- Expo:回忆录 Tab 去掉撰写中「继续写作」及新建会话跳转;清理 memoir 文案键并更新 i18n 类型

未纳入提交:本地 api/uploads/(开发环境头像文件)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 16:15:21 +08:00
Kevin
c45a2c040b fix(expo): 暂停自动朗读后继续播放最新 TTS 片段
- usePlayer:paused 且 tts_auto 时清空队列并重置,再播当前片段
- 用 statusRef 与暂停同步,避免 WS 紧连 enqueue 时状态滞后
- 补充 use-player 单测

- api: 调整 copyright_source_pdf 脚本
- docs: 新增软著《岁月时书》软件设计说明书

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 15:01:50 +08:00
Kevin
c794fe8ee8 chore(app-expo): bump version to 1.2.0
Align Expo config, package.json, and lockfile root with release tag v1.2.0.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 13:44:57 +08:00
Kevin
71bf62166e fix(app-expo): 稳定 WS TTS 与「正在回复」状态
- useRealtimeSession:恢复 uiRef 同步与 AppState 后台/前台重连,收窄长连 effect 依赖,修正 send API 类型
- 会话页:用派生条件控制 AssistantTypingBubble,避免缓存已有助手末条仍显示 typing
- RealtimeSession:在 commit 落缓存时统一 clearAssistantPendingUi,避免漏掉流式完成帧

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 13:42:54 +08:00
Kevin
d155e45a44 fix(conversation): topic chips after warmup + English chip copy
- Buffer topic_suggestions until chat UI attaches (uiOwner + callback); replay on attach
- build_topic_chips respects user language for label/text; router passes user_language

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 11:10:21 +08:00
Kevin
7e64fc3faf Merge commit e95582a: PR #20 proactive chat, topic chips, low-info turn plan
- Merge staging workflow parent and resolve conflicts with English/i18n and WS pool
- Re-greeting: language-aware fallbacks and prompts; router passes user_language
- RealtimeSession: topic suggestion callbacks + TTS sync path preserved

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 11:03:35 +08:00
Kevin
3d01085442 fix(conversation): 修复实时会话 TTS/回复被离屏 WS 抢占
- 列表预热仅预取消息缓存,避免后台 WebSocket 覆盖服务端连接
- RealtimeSession UI 回调按 owner 独占,防止 offscreen 覆盖聊天页
- 列表页聚焦时再 prewarm,会话页 TTS 入队优先 base64
- 管线下发 TTS 同时带 audio_base64 与 audio_url;协议说明同步
- 移除 TTS 排查用前后端调试日志,保留错误/告警
- 补充 WS / RealtimeSession / entry-warmup / 播放器相关单测

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 10:42:44 +08:00
Kevin
93be60f74c fix(tts): gate auto reply by ENABLE_TTS; allow on-demand and manual playback
- Pipeline: skip _send_tts_audio only for non-manual when ENABLE_TTS=false;
  remove enable_tts early return from handle_tts_request_on_demand.
- Tencent TTS: PrimaryLanguage/chunking follow user language preference only.
- Expo: let manual tts_audio bypass late-segment playback gate after interrupt.
- Docs: clarify ENABLE_TTS vs tts_request in api/.env.example and TTSProvider port.
- Tests: add manual bypass cases; adjust pipeline language tests for en+Chinese text.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 17:15:02 +08:00
Kevin
ccdc4e4277 feat(i18n): persist language preference and thread through chat, memoir, TTS
- Add users.language_preference (Alembic 0018, default zh); capture at signup/SMS
  only; expose on auth and profile APIs
- Lite English prompts for chat and memoir; localized stage labels and agent
  names (Life Echo / 岁月知己)
- Tencent TTS: language-aware synthesis, ModelType=1 for 501004, English chunking
- WebSocket pipeline: emit all AGENT_RESPONSE segments when TTS cancels; INFO logs
  for tts_this_turn and TTS decisions; on-demand TTS logging
- Expo: device language on auth, i18n tiers/agent name, [SPLIT] streaming UX fixes
- Tests for migration, prompts, pipeline, router tts_this_turn, reply segments

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 16:16:49 +08:00
Sully
dd2d47289d Merge branch 'development' into claude/agent-proactive-chat-UYHu9 2026-05-11 13:07:18 +08:00
Kevin
705fe951b3 feat(chat): 低信息短答主动续话;修复本地 dev 环境与迁移链
- interview_turn_plan: 识别低信息短回复,引导 AI 承接后主动追问新话题
- development.sh / docker-compose.dev: Postgres/Redis 端口与 .env 对齐,补充宿主机端口监听检查
- Alembic: 补回 0016 memory pipeline status、0017 segment narrative defer
- app-expo: api/ws URL 去掉末尾斜杠,避免 WS 双斜杠;更新 .env.staging

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 12:06:17 +08:00
Sully
cb84c00eca 添加staging release workflow (#22)
* update variable name

* update docker port

* fix alembic migration files

* 给远端 SSH 调用加了 keepalive

* fix app-expo code file format

* comment out quality test threshold

---------

Co-authored-by: Kevin <kevin@brighteng.org>
2026-05-11 11:33:07 +08:00
Kevin
b9425e806b fix app-expo code file format 2026-05-11 10:25:06 +08:00
Kevin
175784292d implement staging workflow 2026-05-09 16:16:48 +08:00
Kevin
d0c26242db fix(conversation): 离屏不丢回复、列表预热 WS 与非阻塞进入聊天
- 后端:文本/转写后 AI 生成改为独立任务,避免断连取消整轮;按需 TTS 等与 WS 改动
- 前端:RealtimeSession 重绑 UI 时恢复流式 buffer;列表 onPressIn/挂载预热、已有会话立即 push
- 同步会话相关类型、i18n、测试与 env/资源等累计改动

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-08 17:28:31 +08:00
Claude
55cfbc7f80 feat: agent proactively re-engages users on returning sessions
Two complementary changes to reduce conversation cold-start friction:

A. Returning-user re-greeting (backend)
- When WS reconnects to a non-empty conversation and last_message_at is older
  than chat_re_greeting_idle_hours (default 6h), the agent emits a warm
  continuation message that references prior history instead of staying silent.
- Self-debouncing: the AI message updates last_message_at, so reconnects
  within the window will not re-trigger.
- Skipped while profile collection is still pending.

D. Topic suggestion chips (backend + Expo)
- New WS message type topic_suggestions carries 3-4 quick-start chips derived
  from the current memoir stage's empty slots (deterministic, no extra LLM
  cost). Sent alongside opening / re-greeting / resume.
- Expo chat screen renders a horizontally-scrollable chip row above the input
  bar; tapping a chip sends the chip's text as a user message and clears the
  row. Sending any text/voice also clears the chips.
2026-05-07 15:39:33 +00:00
Kevin
5dac3efd52 feat(app-expo): conversation WS warmup, background pool, lifecycle
Prefetch opening over WebSocket from the conversations list before navigation, with prepared-session handoff into the chat screen. Add a single-slot background pool so leaving chat (in-app) keeps the last session socket with UI callbacks stripped; dispose on app background and reconnect after resume when the chat screen is mounted. Tear down pooled sockets on logout, purge, and conversation delete. RealtimeSession supports attachUiCallbacks and idempotent dispose, and the chat composer hides the connection notice while connecting if assistant history already exists. Fix pause handler wiring in the conversation screen.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-06 14:54:47 +08:00
Kevin
7ad52fce89 feat(profile): avatar presets, upload, nickname editing
- FastAPI: preset assets 01–08, GET list/static, PUT /me/avatar/preset,
  safer uploaded-avatar path validation, preset_avatars + HTTP tests.
- Expo: personal-info (library + presets), profile tab avatar,
  resolveApiMediaUrl, auth hooks cache sync, Web multipart helper,
  partial-save messaging + profile i18n.
- Includes existing edits to conversation screen and voice use-player.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-06 13:51:43 +08:00
Kevin
eddb2c3078 fix(expo): 发送后延时 refocus 聊天输入框
发送会递增 inputResetKey 以 remount TextInput,需在下一帧再 focus 才能延续键盘输入。

Made-with: Cursor
2026-04-29 10:37:49 +08:00
yangshilin
9af2060259 fix:
1. 修复安卓部分机型顶部安全区遮挡回忆录标题的问题;
2. 降低封面图生成阈值和展示逻辑,独立封面图未生成时,使用正文图;
3. 去掉“嗯。”生硬回答,去掉不合理段首承接词;
4. 新增章节封面所需最少插图数的配置项
2026-04-16 20:42:54 +08:00
yangshilin
17b9fa3466 fix:
1. 修复登录界面文字被遮挡问题
2. 大字模式关闭后显示异常问题
3. 重新调整大字模式是否开启时的字体显示效果
2026-04-10 20:35:57 +08:00
Kevin
828a29748e fix/ 修复AI聊天时回复markdown导致聊天气泡布局问题 2026-04-03 14:06:55 +08:00
Kevin
a5473e8fe2 fix/ 修复打个招呼计时器问题,修复聊天页输入框文字模式切换到语音的问题 2026-04-01 09:40:24 +08:00
Kevin
69a673e6c6 feat(api): 访谈人格/回复长度策略、口述归一、背景语气与输入净稿全链路
Chat 访谈
- 新增 persona 系统(default / warm_listener / curious_guide)与 background_voice 语气层
- 回复长度由 compute_reply_plan 统一决策(brief / standard / expanded),融合信息密度启发式
- 输入净稿(input_normalize):编排层可选 rules/llm 归一用户口语后再喂模型与记忆检索
- 记忆证据注入:按用户话检索 memory evidence 并注入 prompt

Memoir 回忆录
- 口述归一(oral_normalize):segment 原文保留,story 管线取派生净稿作叙事输入
- segment 入队批次门闸:累计字数 + 最长等待秒数,减少零碎提交
- fidelity_check / prompts / narrative_agent 微调
- Alembic 0005:清理跨章节 story 外键

Infra
- Dockerfile 加入 ffmpeg
- pyproject.toml 新增依赖并同步 uv.lock
- .env.example / .env.production 补全新配置项

Tests
- 新增 test_background_voice、test_chat_input_normalize、test_experience_regressions
- 扩展 test_interview_prompts、test_interview_reply_length、test_story_route_oral_invariant

Made-with: Cursor
2026-03-31 23:55:26 +08:00
Kevin
0d999cb769 feat(app-expo): render chat bubbles as Markdown with correct bold
- Add ChatBubbleMarkdown using react-native-markdown-display; disable images
  in bubbles for safety.
- Strip fontWeight from leaf text styles so **strong** is not overridden by
  chatBubbleTextStyle (nested Text on RN).
- Wire MessageBubble and StreamingBubbles; keep streaming cursor appended
  to markdown string.
2026-03-27 17:38:20 +08:00
Kevin
e4bf0710c7 feat(memory,conversation): 记忆富化/证据包、时间线幂等字段与对话分段全链路
数据库
- 新增迁移 0003:timeline_events.memory_source_id 外键 → memory_sources,便于按 ingest 源做时间线幂等

后端 - 记忆
- 新增 ingest 后 LLM 富化(摘要/事实/时间线),可配置开关与最大字符数
- 新增证据包组装:合并 chunk、摘要、事实、时间线、故事等检索结果;支持空 query 时是否仍带 rolling 等开关
- repo/retriever/service/router/schemas/summarizer/timeline/extractor 等扩展;文档 memory-retrieval.md 更新

后端 - 对话 WS
- 增加 PING/PONG;分段 ASR 日志与空音频处理;转写失败与「无助手回复」错误提示更明确
- 助手多段回复持久化使用统一分隔符,与分段逻辑一致

后端 - Agent
- reply_limits:按 [SPLIT] 与段落拆段,并保证非空 fallback,供 WS 与 TTS 多段下发

后端 - 回忆录任务
- transcript ingest 记录 source_id;任务成功结?
2026-03-27 16:24:43 +08:00
Kevin
1374f6e8f5 feat(memoir+conversation): 章节/故事最小可读字数;会话 hasUserMessage 与 UI 优化
- 后端:300 字门槛统一物化、hydrate、列表/PDF/详情;过短章节对读者隐藏
- 对话:首包前打字动画、大字模式排版、朗读/TTS 交互与布局稳定
- 首页:复用无用户消息会话;空列表「继续对话」与文案 i18n
- 章节阅读:标题进正文、封面与去重标题;阅读 Markdown 字号上调
2026-03-26 16:28:33 +08:00
Kevin
d990399112 feat(conversation): TTS 投递与 WebSocket 管线;客户端播放门禁与会话页联动;COS 键与迁移脚本调整 2026-03-26 15:51:24 +08:00
Kevin
a3f61fcc0f feat(api+app): 对话阶段化、回忆录流水线与客户端会话体验
- DB: segments 用户输入文本(Alembic 0002)
- Chat: 阶段检测/阶段提示/回复限制,编排与访谈/画像 prompts 调整
- Memoir: 忠实度检查 agent,叙事与分类等链路更新
- Core: agent 日志、Alembic 启动、LangChain/日志/配置等
- Story: time_hints;Memory 检索与相关测试
- Expo: 助手头像、会话页与消息拆分、实时会话与文案/i18n
- Docs/scripts/tests: 迁移脚本、LLM JSON/记忆检索文档、新增单测
2026-03-26 12:13:36 +08:00
Kevin
805da8d789 replace with docker compose 2026-03-25 17:40:04 +08:00
Kevin
62de478368 feat(app-expo): 聊天键盘与列表滚动改用 keyboard-controller,并收敛 Web 构建配置
聊天(conversation/[id])
- 根布局挂载 KeyboardProvider,会话页使用 react-native-keyboard-controller 的
  KeyboardAvoidingView(padding + 仅文字模式 enabled),替代手写 keyboardLift 与
  RN KeyboardAvoidingView 分端逻辑,改善 Android 键盘遮挡与布局一致性。
- 键盘:keyboardDidShow 后 scrollToEnd;iOS 用 keyboardWillShow 提前更新键盘可见状态;
  收起使用 WillHide/DidHide;监听在 effect 中统一移除。
- 输入框高度:ChatInputBar 通过 onInputDisplayHeightChange 在 inputDisplayHeight 变化时
  触发滚到底;保留底部容器 onLayout 以覆盖连接提示与整块高度变化。

配置与构建
- app.config:移除 web 块与 expo-sqlite Web 所需的 COEP/COOP headers;expo-router 插件
  改为无参;Android 显式 softwareKeyboardLayoutMode: resize。
- metro.config:移除 wasm 资源与 COOP/COOP dev server
OC
2026-03-23 14:20:12 +08:00
Kevin
f58adb9670 修复环境变量,UI问题 2026-03-23 13:54:41 +08:00
Kevin
b9ecfd02a4 various fixes 2026-03-23 13:21:07 +08:00
Kevin
9c2e0329ca chore/ update app name 2026-03-23 11:33:02 +08:00
Kevin
1258f20df5 Merge remote-tracking branch 'origin/development' 2026-03-23 10:36:42 +08:00
Kevin
f8b3de6ff8 优化工作流,添加app-icon 2026-03-23 10:25:51 +08:00
Kevin
aac8faf125 更新workflow 2026-03-22 19:22:34 +08:00
Kevin
786ebf8ae6 refactor(api,expo): 多智能体与会话收敛、回忆录兼容层移除、后端测试集大幅删减
- 对齐「多智能体收敛」与「回忆录 stories-first / markdown-first」方向:收紧运行时契约、
  删除过渡兼容路径与双轨逻辑,并同步更新客户端与文档。

- Chat:以 ChatOrchestrator 为实时编排入口;删除独立 conversation_agent,精简 prompts。
- Memoir:删除 memory_agent;MemoirOrchestrator、classification / story_route 与 prompts 收敛到
  prepare_batches + run_story_pipeline_for_category_batch 主链路。
- 将 agents 侧 processor 迁入 feature 层为 background_runner,并移除 features 下重复/过时
  processor 封装。

- 新增 history_store,强化「conversation_messages 为 DB 真源、Redis 为缓存」模型。
- 调整 models、repo、service、session_history;精简 WS message_types,重构 pipeline 与 router。

- 移除章节占位、整章再生等旧路径;章节列表与封面逻辑要求 story 关联;收紧 cover 资格与
  enqueue。
- helpers、repo、service、router、reading_segment_materialize、story_pipeline_sync、pdf_service
  等按 canonical markdown / cover_asset_id 收缩;删除 memoir_images/provider 等冗余。
- tasks:memoir_tasks、chapter_cover_tasks 等大幅瘦身;story_image_tasks 等与当前图片任务对齐。

- core:config、logging、redis、task_tracker 小幅调整。
- auth / user / payment / quota:路由或服务侧删减过时接口或逻辑(如 payment router 行数减少)。

- pyproject.toml、development.sh、.env.example / .env.production、README 等同步说明或变量。

- Alembic 0001_initial_schema 微调(与当前 schema 叙事一致的小改动)。

- 回忆录:types / mappers / api、章节页与 memoir 页与后端契约对齐;markdown-renderer 调整。
- 语音:删除 voice/player,voice-segment-store 相应精简。

- api/tests:删除 conftest 及绝大部分既有测试文件(websocket_baseline、conversation、memoir
  图片、PDF、SMS 等),属有意收缩/待按 backend-test-system 重建的信号。
- docs:新增多智能体收敛与移除兼容层计划摘要;更新 story-first 设计、backend-test-system、
  multi-agent-refactor-plan、实施总结等。

BREAKING CHANGE: 后端对外契约、回忆录章节字段与若干路由/任务行为已变更;大量 API 测试被移除,
  CI 若依赖这些用例需按新策略补测或调整流水线。
2026-03-22 18:10:28 +08:00
Kevin
70070216c4 修复一些已知问题 2026-03-20 17:25:42 +08:00
Kevin
8af37e5e8e 修复:CI 部署环境与 ref 错配、迁移碎片化、图片意图 source_span、章节物化脏版式、会话历史与本地语音不一致
新增:TTS 上传 COS 与分片、章节 reading_segments 物化与快照、markdown 清洗、会话消息 repository、语音 store 重构与相关测试
2026-03-20 16:43:02 +08:00
Kevin
7317bf10cd fix/various fixes 2026-03-20 15:15:35 +08:00
Kevin
7f57f96c25 重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复
本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括:

1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。

2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。

3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。

4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。

5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。

6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。

7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:31:51 +08:00
Kevin
7237b53b9b feat/调整tts音色,调整封面图prompt,修复对话页输入框显示逻辑,待验证封面图生成功能 2026-03-19 14:14:52 +08:00
Kevin
687f41df2e chore(ui): 精简对话与回忆录页,移除冗余元素
- 移除对话/回忆录页顶部标题(与底部 Tab 重复)
- 移除回忆录卡片右上角状态图标
2026-03-19 11:03:30 +08:00