AI助手优化-人设与会话绑定

This commit is contained in:
2026-09-29 10:44:39 +08:00
parent f4ad2f8612
commit 900d48697e
5 changed files with 464 additions and 150 deletions
+26 -7
View File
@@ -287,9 +287,16 @@ class _AssistantPageState extends ConsumerState<AssistantPage> {
);
if (!mounted) return;
// 关掉弹层 = 用默认人设。不返回任何东西也照样开新对话,
// 免得用户以为「没点就是取消了」
ref.read(assistantProvider.notifier).newChat(personaId: picked?.personaId);
// 关掉弹层 = 取消,不开新对话。
// 不自动用默认人设开始:误触一下就把用户正在看的对话顶掉太亏了。
// 想用默认人设就点列表里第一项「默认人设」,一样是一下
if (picked == null) return;
// 记住这次选的,下次新对话默认预选它。
// 这是**唯一**写这个偏好的地方 —— 设置页不提供「选说话的人」这个动作
ref.read(preferredPersonaProvider.notifier).remember(picked.personaId);
ref.read(assistantProvider.notifier).newChat(personaId: picked.personaId);
}
// ---------------------------------------------------------------- 气泡
@@ -301,7 +308,6 @@ class _AssistantPageState extends ConsumerState<AssistantPage> {
// 头像只给 36px —— 太大反而抢戏,微信也就这个量级。
Widget _bubble(BuildContext context, ChatBubble bubble) {
final persona = ref.watch(activeAiPersonaProvider);
final user = ref.watch(authProvider).user;
if (bubble.isUser) {
@@ -340,7 +346,10 @@ class _AssistantPageState extends ConsumerState<AssistantPage> {
return _row(
avatar: Avatar(
assetPath: persona?.avatar,
// 会话锁定了哪个人设,气泡上就显示谁 —— 和这段回答实际用的 prompt 同一个人。
// 不能用「新对话预选的那条」:用户之后新对话选了别人,
// 这条旧会话的历史消息不该跟着换头像
assetPath: _sessionPersonaAvatar(),
size: 36,
fallbackIcon: 'assistant',
),
@@ -397,6 +406,15 @@ class _AssistantPageState extends ConsumerState<AssistantPage> {
);
}
/// 当前会话绑定的人设头像。null = 没设过(或人设被删了),显示默认图标。
///
/// 关键在「按会话存的那个 id 去找」而不是读全局偏好 —— 见
/// [personaByIdProvider] 的说明。
String? _sessionPersonaAvatar() {
final personaId = ref.watch(assistantProvider.select((s) => s.personaId));
return ref.watch(personaByIdProvider(personaId))?.avatar;
}
/// 一行 = 头像 + 气泡。用户侧左右镜像。
///
/// 头像用 [CrossAxisAlignment.start](贴顶)而不是居中 —— 回答很长时
@@ -643,8 +661,9 @@ class _PersonaPickerSheet extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final personasAsync = ref.watch(aiPersonasProvider);
// 默认选中「用户当前偏好的那套」,省得每次都点
final preferred = ref.watch(selectedAiPersonaProvider);
// 预选上次用的那套,省得每次重选。注意这只是「预选」——
// 真正生效的人设是新建会话时定下的那个
final preferred = ref.watch(preferredPersonaProvider);
return SafeArea(
child: Padding(