用户界面
jmix-aitools-flowui-starter 提供了一个完整的聊天 UI,包含开箱即用的视图、可嵌入到自定义视图中的 fragment,以及相关的支撑服务。对 UI 的访问权限由 聊天用户角色 控制。
视图
扩展组件默认注册了两个视图。
| 视图 | 描述 |
|---|---|
|
聊天中心:一个带有消息编辑器、用户最近对话以及支持搜索的按日期分组聊天历史的视图。会自动添加到主菜单中。 |
|
单对话视图。在聊天中心选定对话时打开,或者在没有选定对话时打开以开始新聊天。 |
由于扩展组件为 AiChatHubView 配置了一个菜单项,具有聊天角色的用户无需任何额外配置即可访问。该菜单项通过 组合菜单 的机制添加。
Fragments
当预置的视图无法满足自定义视图的要求时,还可以使用 fragment 将聊天 UI 嵌入到自己的视图中。使用 <fragment> 元素将 fragment 添加到视图 XML 描述中。
AiChatHubFragment
io.jmix.aitoolsflowui.view.chathub.AiChatHubFragment 是一个独立的聊天中心,在 AiChatHubView 中使用。在任意视图添加该 fragment 即可获得编辑器、最近聊天和历史记录:
<fragment id="chatHubFragment"
class="io.jmix.aitoolsflowui.view.chathub.AiChatHubFragment"/>
其公共 API:
-
setRecentChatsCount(int)– 设置编辑器旁边显示的最近聊天数。如果未设置,该值来自jmix.aitools.ui.chat-hub-recent-chats-count应用程序属性。 -
setMarkIconSupplier(SerializableSupplier<Component>)– 替换在中心和对话卡片上显示的品牌标记图标。
AiChatFragment
io.jmix.aitoolsflowui.view.chat.AiChatFragment 是一个对话面板,在 AiChatView 中使用。包含在一个对话内显示标题行、消息时间线和编辑器。在视图中使用并以编程方式绑定一个对话:
<fragment id="chatFragment"
class="io.jmix.aitoolsflowui.view.chat.AiChatFragment"/>
@ViewComponent
private AiChatFragment chatFragment;
@Autowired
private AiConversationService conversationService;
@Subscribe
public void onInit(final InitEvent event) {
AiConversation conversation = conversationService.create();
chatFragment.setConversation(conversation);
}
关键方法:
-
setConversation(AiConversation)/setConversationId(UUID)– 将面板绑定到特定对话。 -
sendMessage(String)– 以编程方式发送用户消息。 -
setReadOnly(boolean)– 隐藏编辑器和标题编辑按钮。 -
setMessageInputEnabled(boolean)/focusMessageInput()– 控制编辑器的只读和获取焦点。 -
isAwaitingResponse()– 设置当前是否正在生成回复。 -
setAiAvatarIconSupplier(SerializableSupplier<Component>)– 自定义助手头像。 -
setTitleMode(AiConversationTitleMode)– 选择如何设置新对话的标题。当未设置或设置为null时,从 jmix.aitools.ui.conversation-title-mode 读取配置。参考 对话标题。
服务
UI 有三个支撑服务。这些服务操作 UI 模型 AiConversation 和 AiChatMessage,服务的作用域隐式的限制在当前用户。
| 服务 | 职责 |
|---|---|
|
生成助手对用户消息的回复。
|
|
管理当前用户的对话。
|
|
管理对话的消息。
|
持久化与空实现
这些服务存储数据的位置取决于使用哪个 starter:
-
使用
jmix-aitools-flowui-data-starter时,服务由 JPA 实体支持,对话和消息存储在数据库中。 -
仅使用
jmix-aitools-flowui-starter时,服务是空操作桩代码。AiChatService.isAvailable()返回false,不会持久化任何内容,聊天实际上被禁用。这个可以支持在持久化准备好之前先做 UI 设计。
如需使用非默认存储的聊天,请不要添加 starter,并提供自定义实现的 AiChatService、AiConversationService 和 AiChatMessageService。
对话标题
Jmix 3.1+
一个新的对话默认标题为 New AI Conversation。jmix.aitools.ui.conversation-title-mode 应用程序属性定义当用户发送第一条消息时,如何获取对话的标题。
| 模式 | 标题 |
|---|---|
|
第一条用户消息。超过 255 个字符的消息会在单词边界处截断。不会调用模型。这是默认模式。 |
|
模型根据第一条用户消息生成简短标题,使用当前用户区域设置的语言。模型在后台调用。在标题生成之前,或者如果没有生成标题,对话将使用第一条消息作为标题。 |
|
对话使用默认标题。 |
即使用户在标题生成之前离开对话,该标题也会被保存。并且不会替换用户在此期间输入的标题。
如果你的视图需要在第一条消息之前为对话指定自定义标题,请在 AiChatFragment 上调用 setTitleMode(AiConversationTitleMode.NONE)。否则,第一条消息会替换此标题。
自定义标题生成
在 GENERATED 模式下,AiConversationTitleGenerator bean 负责生成标题。其默认实现位于 jmix-aitools-flowui-data-starter 中,将第一条用户消息发送到 已配置的模型。仅使用 jmix-aitools-flowui-starter 时,生成器不返回标题。
如需以不同的方式生成标题,注册一个实现 io.jmix.aitoolsflowui.service.AiConversationTitleGenerator 的 bean。其 generateTitle(String firstUserMessage) 方法返回标题或空的 Optional。该方法在带有当前用户身份验证的后台线程中运行。返回的标题按原样保存,因此需要控制在 255 个字符以内。
如果仅需要更改默认生成器的系统提示词,注册一个实现 io.jmix.aitoolsflowuidata.service.prompt.AiConversationTitleSystemPromptProvider 的 bean 并返回自定义模板。模板可以使用 {responseLanguage} 参数,其中包含当前用户区域设置的语言,例如 German / Deutsch (de)。