用户界面

jmix-aitools-flowui-starter 提供了一个完整的聊天 UI,包含开箱即用的视图、可嵌入到自定义视图中的 fragment,以及相关的支撑服务。对 UI 的访问权限由 聊天用户角色 控制。

视图

扩展组件默认注册了两个视图。

视图 描述

AiChatHubView

聊天中心:一个带有消息编辑器、用户最近对话以及支持搜索的按日期分组聊天历史的视图。会自动添加到主菜单中。

AiChatView

单对话视图。在聊天中心选定对话时打开,或者在没有选定对话时打开以开始新聊天。

由于扩展组件为 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 读取配置。参考 对话标题。

AiChatInputFragment

io.jmix.aitoolsflowui.view.input.AiChatInputFragment 是可复用的消息编辑器:一个文本域加上一个发送按钮。按 Enter 键提交消息。按 Shift+Enter 插入换行。用于上述两个 fragment 中,当构建自定义聊天布局时,可以单独使用。通过 setSubmitHandler(Consumer<String>)、setPlaceholder(String)、setInputEnabled(boolean)、focus() 和 clear() 进行配置。

服务

UI 有三个支撑服务。这些服务操作 UI 模型 AiConversation 和 AiChatMessage,服务的作用域隐式的限制在当前用户。

服务 职责

AiChatService

生成助手对用户消息的回复。

  • processMessage(message) – 返回回复内容。

  • processMessage(message, statusCallback) – 与上一个方法相同,但通过 Consumer<AiToolStatusUpdate> 报告进度。

  • isAvailable() – 是否能够生成回复,即,是否配置了模型。

AiConversationService

管理当前用户的对话。

  • loadConversations() – 加载用户的对话,最新的在前。

  • loadConversation(id) – 按 ID 加载一个对话。

  • create() – 创建新对话。

  • save(conversation) – 持久化对话。

  • remove(conversation) – 删除对话及其消息。

AiChatMessageService

管理对话的消息。

  • createMessage(…​) – 添加指定类型的消息。

  • loadMessages(conversation) – 加载所有消息,最旧的在前。

  • loadLatestMessage(…​) – 加载最近的消息,可选择按类型过滤。

持久化与空实现

这些服务存储数据的位置取决于使用哪个 starter:

  • 使用 jmix-aitools-flowui-data-starter 时,服务由 JPA 实体支持,对话和消息存储在数据库中。

  • 仅使用 jmix-aitools-flowui-starter 时,服务是空操作桩代码。AiChatService.isAvailable() 返回 false,不会持久化任何内容,聊天实际上被禁用。这个可以支持在持久化准备好之前先做 UI 设计。

如需使用非默认存储的聊天,请不要添加 starter,并提供自定义实现的 AiChatService、AiConversationService 和 AiChatMessageService。

图标 provider

聊天中心显示的品牌图标和助手头像由 AiIconProvider bean 提供。替换此 bean 可全局更改扩展组件的图标,或者使用 fragment 的方法在替换局部的图标。

对话标题

Jmix 3.1+

一个新的对话默认标题为 New AI Conversation。jmix.aitools.ui.conversation-title-mode 应用程序属性定义当用户发送第一条消息时,如何获取对话的标题。

模式 标题

FIRST_MESSAGE

第一条用户消息。超过 255 个字符的消息会在单词边界处截断。不会调用模型。这是默认模式。

GENERATED

模型根据第一条用户消息生成简短标题,使用当前用户区域设置的语言。模型在后台调用。在标题生成之前,或者如果没有生成标题,对话将使用第一条消息作为标题。

NONE

对话使用默认标题。

即使用户在标题生成之前离开对话,该标题也会被保存。并且不会替换用户在此期间输入的标题。

如果你的视图需要在第一条消息之前为对话指定自定义标题,请在 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)。

安全角色

扩展组件提供了一个预定义的 资源角色。

名称

AI Tools: chat user

代码

aitools-chat-user

作用域

UI

授予最终用户访问聊天 UI 的权限:聊天中心和对话视图,以及可以管理这些用户自己的对话和消息,包括开始、继续、重命名和删除聊天。具体来说,该角色授予:

  • 对 AiChatHubView 和 AiChatView 以及聊天中心菜单项的查看权限

  • 对用户自己聊天记录的完全访问权限,以及对其消息的创建/读取权限

将此角色分配给每个需要使用助手的用户。有关如何为用户分配角色,请参见 用户。

该角色仅授予对聊天 UI 的访问权限,不会扩大数据访问权限。当助手通过预定义的 数据加载工具 加载业务数据时,查询语句会在当前用户自身的 数据访问 权限下运行,因此该角色不会让用户读取他们原本无法读取的任何内容。开发者在添加任何自定义工具时,都需要负责自定义访问控制。