diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/task/TaskDecorator.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/task/TaskDecorator.java index 8788c04836..9364e8ed23 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/task/TaskDecorator.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/task/TaskDecorator.java @@ -111,7 +111,7 @@ private Object invokeMethod(Method method, Object[] args, Object current) else { msg = localeService.localize(UI_WORD_KEY); } - this.aippLogService.insertLog(AippInstLogType.ERROR.name(), + this.aippLogService.insertLogWithInterception(AippInstLogType.ERROR.name(), AippLogData.builder().msg(msg).build(), ctx.getBusinessData()); return null; } diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecorator.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecorator.java index 75b586cd57..e9e0fccf68 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecorator.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecorator.java @@ -142,7 +142,7 @@ private Object wrapException(AppTaskInstanceService instanceService, AippLogServ .setStatus(MetaInstStatusEnum.ERROR.name()) .build(), ctx.getOperationContext()); // 更新日志类型为HIDDEN_FORM - logService.insertLog(AippInstLogType.ERROR.name(), AippLogData.builder().msg(e.getMessage()).build(), + logService.insertLogWithInterception(AippInstLogType.ERROR.name(), AippLogData.builder().msg(e.getMessage()).build(), ctx.getBusinessData()); } return null; diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallback.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallback.java index b28e56990d..434ba8d500 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallback.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallback.java @@ -6,6 +6,8 @@ package modelengine.fit.jober.aipp.fitable; +import static modelengine.fit.jober.aipp.fitable.LlmComponent.checkEnableLog; + import modelengine.fit.jade.aipp.formatter.OutputFormatterChain; import modelengine.fit.jade.aipp.formatter.constant.Constant; import modelengine.fit.jade.aipp.formatter.support.ResponsibilityResult; @@ -184,7 +186,7 @@ private String saveFormToLog(String appId, Map businessData, Str logData.setFormAppearance(JsonUtils.toJsonString(formDataMap.get(AippConst.FORM_APPEARANCE_KEY))); logData.setFormData(JsonUtils.toJsonString(formDataMap.get(AippConst.FORM_DATA_KEY))); // 子应用/工作流的结束节点表单不需要在历史记录展示 - return this.aippLogService.insertLog((this.isExistParent(businessData) + return this.aippLogService.insertLogWithInterception((this.isExistParent(businessData) ? AippInstLogType.HIDDEN_FORM : AippInstLogType.FORM).name(), logData, businessData); } @@ -206,7 +208,10 @@ private void logFinalOutput(Map businessData, String aippInstId) String logMsg = formatOutput.map(ResponsibilityResult::text).orElse(CHECK_TIP); AippInstLogType logType = formatOutput.flatMap(result -> Optional.ofNullable(LOG_STRATEGY.get(result.owner()))) .orElse(AippInstLogType.MSG); - this.aippLogService.insertLog(logType.name(), AippLogData.builder().msg(logMsg).build(), businessData); + if (!checkEnableLog(businessData)) { + logType = AippInstLogType.HIDDEN_MSG; + } + this.aippLogService.insertLogWithInterception(logType.name(), AippLogData.builder().msg(logMsg).build(), businessData); this.beanContainer.all(AppFlowFinishObserver.class) .stream() .map(BeanFactory::get) diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowSmartFormHandle.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowSmartFormHandle.java index 3e7bd5d5cb..a24b3deed3 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowSmartFormHandle.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowSmartFormHandle.java @@ -177,7 +177,7 @@ private String insertFormLog(List formProperties, String Object appearance = formDataMap.get(AippConst.FORM_APPEARANCE_KEY); logData.setFormAppearance(ObjectUtils.cast(JsonUtils.toJsonString(appearance))); logData.setFormData(ObjectUtils.cast(JsonUtils.toJsonString(formDataMap.get(AippConst.FORM_DATA_KEY)))); - return this.aippLogService.insertLog(AippInstLogType.FORM.name(), logData, businessData); + return this.aippLogService.insertLogWithInterception(AippInstLogType.FORM.name(), logData, businessData); } private void updateInstance(String sheetId, String nodeId, Map businessData) { diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/LlmComponent.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/LlmComponent.java index 64d40696af..51a001baf9 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/LlmComponent.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/LlmComponent.java @@ -364,6 +364,14 @@ private void addAnswer(AippLlmMeta llmMeta, String answer, Map p output.put("reference", promptMetadata.getOrDefault(PROMPT_METADATA_KEY, Collections.emptyMap())); businessData.put("output", output); + // 如果节点配置为输出到聊天,模型回复内容需要持久化 + boolean enableLog = checkEnableLog(businessData); + if (enableLog) { + this.aippLogService.insertLog(AippInstLogType.MSG.name(), + AippLogData.builder().msg(answer).build(), + businessData); + } + // 修改taskInstance. AppTaskInstance updateEntity = AppTaskInstance.asUpdate(llmMeta.getVersionId(), llmMeta.getInstId()) .setLlmOutput(answer) @@ -537,6 +545,14 @@ public ModelExtraBody(String sessionId) { } } + public static boolean checkEnableLog(Map businessData) { + Object value = businessData.get(AippConst.BS_LLM_ENABLE_LOG); + if (value == null) { + return true; + } + return Boolean.parseBoolean(value.toString()); + } + static class StreamMsgSender { private final AippLogStreamService aippLogStreamService; private final ObjectSerializer serializer; @@ -560,7 +576,7 @@ static class StreamMsgSender { * @param businessData 表示流程上下文的 {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}。 */ public void sendMsg(String msg, Map businessData) { - boolean enableLog = this.checkEnableLog(businessData); + boolean enableLog = checkEnableLog(businessData); if (!enableLog || StringUtils.isBlank(msg) || msg.contains("")) { return; } @@ -574,19 +590,13 @@ public void sendMsg(String msg, Map businessData) { * @param businessData 表示流程上下文的 {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}。 */ public void sendKnowledge(Map promptMetadata, Map businessData) { - if (!this.checkEnableLog(businessData) || !promptMetadata.containsKey(PROMPT_METADATA_KEY)) { + if (!checkEnableLog(businessData) || !promptMetadata.containsKey(PROMPT_METADATA_KEY)) { return; } String knowledgeData = this.serializer.serialize(promptMetadata.get(PROMPT_METADATA_KEY)); this.sendMsgHandle(knowledgeData, StreamMsgType.KNOWLEDGE, businessData); } - private Boolean checkEnableLog(Map businessData) { - return Objects.isNull(businessData.get(AippConst.BS_LLM_ENABLE_LOG)) - ? true - : ObjectUtils.cast(businessData.get(AippConst.BS_LLM_ENABLE_LOG)); - } - private void sendMsgHandle(String msg, StreamMsgType logType, Map businessData) { RunContext runContext = new RunContext(businessData, new OperationContext()); String chatId = runContext.getOriginChatId(); diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/AippLogService.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/AippLogService.java index 555c367fa7..311242fd91 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/AippLogService.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/AippLogService.java @@ -93,7 +93,7 @@ public interface AippLogService { * @param businessData 业务数据 * @return 返回插入的日志id */ - String insertLog(String logType, AippLogData logData, Map businessData); + String insertLogWithInterception(String logType, AippLogData logData, Map businessData); /** * 插入ERROR类型的历史记录 @@ -185,4 +185,13 @@ List queryAippRecentInstLogAfterSplice(String aippId, String * @param logIds 表示指定的日志 id 列表的 {@link List}{@code <}{@link Long}{@code >}。 */ void deleteLogs(List logIds); + + /** + * 插入一条日志记录,但不触发发送逻辑。 + * + * @param logType 表示日志类型的 {@link String}。 + * @param logData 表示日志主体数据的 {@link AippLogData} 实例。 + * @param businessData 表示业务数据的 {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}。 + */ + void insertLog(String logType, AippLogData logData, Map businessData); } diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogServiceImpl.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogServiceImpl.java index 0a4538b4a1..675a1fd6d7 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogServiceImpl.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogServiceImpl.java @@ -235,6 +235,11 @@ private Map> queryRecentLogByInstanceIds(List } } } + + for (List logList : result.values()) { + logList.sort(Comparator.comparing(AippInstLog::getLogId)); + } + return result; } @@ -362,7 +367,16 @@ public void deleteAippPreviewLog(String previewAippId, OperationContext context) * @return 日志id */ @Override - public String insertLog(String logType, AippLogData logData, Map businessData) { + public String insertLogWithInterception(String logType, AippLogData logData, Map businessData) { + AippLogCreateDto logCreateDto = this.buildAippLogCreateDto(logType, logData, businessData); + if (logCreateDto == null) { + return null; + } + return this.aopAippLogService.insertLog(logCreateDto); + } + + private AippLogCreateDto buildAippLogCreateDto(String logType, AippLogData logData, + Map businessData) { RunContext runContext = new RunContext(businessData, new OperationContext()); String aippId = runContext.getAppSuiteId(); String instId = runContext.getTaskInstanceId(); @@ -376,7 +390,7 @@ public String insertLog(String logType, AippLogData logData, Map String path = this.buildPath(instId, parentInstId); String chatId = runContext.getOriginChatId(); String atChatId = runContext.getAtChatId(); - return this.aopAippLogService.insertLog(AippLogCreateDto.builder() + return AippLogCreateDto.builder() .aippId(aippId) .version(version) .aippType(aippType) @@ -388,8 +402,9 @@ public String insertLog(String logType, AippLogData logData, Map .chatId(chatId) .atChatId(atChatId) .isEnableLog(this.isEnableLog(businessData)) - .build()); + .build(); } + private Boolean isEnableLog(Map businessData) { // 兼容老数据,老数据没有这个开关的时候(enableLog为null)默认返回true。 // 有开关后(enableLog为null),返回enableLog的值 @@ -406,7 +421,7 @@ private Boolean isEnableLog(Map businessData) { @Override public void insertErrorLog(String msg, List> flowData) { AippLogData logData = AippLogData.builder().msg(msg).build(); - insertLog(AippInstLogType.ERROR.name(), logData, DataUtils.getBusiness(flowData)); + insertLogWithInterception(AippInstLogType.ERROR.name(), logData, DataUtils.getBusiness(flowData)); } /** @@ -502,4 +517,13 @@ public void deleteLogs(List logIds) { } this.aippLogMapper.deleteInstanceLogs(logIds); } + + @Override + public void insertLog(String logType, AippLogData logData, Map businessData) { + AippLogCreateDto logCreateDto = this.buildAippLogCreateDto(logType, logData, businessData); + if (logCreateDto == null) { + return; + } + this.aippLogMapper.insertOne(logCreateDto); + } } diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogStreamServiceImpl.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogStreamServiceImpl.java index ab5a3ff912..5c5643bbca 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogStreamServiceImpl.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogStreamServiceImpl.java @@ -41,7 +41,8 @@ public class AippLogStreamServiceImpl implements AippLogStreamService { private static final List OUTPUT_WITH_MSG_WHITE_LIST = Arrays.asList(AippInstLogType.MSG.name(), AippInstLogType.ERROR.name(), AippInstLogType.META_MSG.name(), - StreamMsgType.KNOWLEDGE.value()); + StreamMsgType.KNOWLEDGE.value(), + AippInstLogType.HIDDEN_MSG.name()); private final AppChatSseService appChatSseService; private final SensitiveFilterTools sensitiveFilterTools; diff --git a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/vo/AippLogVO.java b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/vo/AippLogVO.java index 11fe6a209d..e9fac421f9 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/vo/AippLogVO.java +++ b/app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/vo/AippLogVO.java @@ -84,9 +84,9 @@ public static AippLogVO fromCreateDto(AippLogCreateDto dto) { */ public boolean displayable() { return !(StringUtils.equals(AippInstLogType.FORM.name(), this.logType) - || StringUtils.equals(AippInstLogType.HIDDEN_MSG.name(), this.logType) || StringUtils.equals( - AippInstLogType.HIDDEN_QUESTION.name(), - this.logType) || StringUtils.equals(AippInstLogType.HIDDEN_FORM.name(), this.logType)); + || StringUtils.equals(AippInstLogType.HIDDEN_QUESTION.name(), this.logType) || StringUtils.equals( + AippInstLogType.HIDDEN_FORM.name(), + this.logType)); } /** diff --git a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/task/TaskDecoratorTest.java b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/task/TaskDecoratorTest.java index 6fc90acf7c..2c9a12ebef 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/task/TaskDecoratorTest.java +++ b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/task/TaskDecoratorTest.java @@ -66,7 +66,7 @@ public void testException() { doNothing().when(this.appTaskInstanceService).update(any(), any()); when(this.localeService.localize(any())).thenReturn("xxxxxxx"); - when(this.aippLogService.insertLog(any(), any(), any())).thenReturn("xxxxxx"); + when(this.aippLogService.insertLogWithInterception(any(), any(), any())).thenReturn("xxxxxx"); // when. RunContext runContext = new RunContext(businessData, new OperationContext()); @@ -84,6 +84,6 @@ public void testException() { Assertions.assertEquals(MetaInstStatusEnum.ERROR.name(), instance.getEntity().getStatus().get()); verify(this.localeService, times(1)).localize(eq("aipp.service.impl.AippRunTimeServiceImpl")); - verify(this.aippLogService, times(1)).insertLog(eq(AippInstLogType.ERROR.name()), any(), any()); + verify(this.aippLogService, times(1)).insertLogWithInterception(eq(AippInstLogType.ERROR.name()), any(), any()); } } diff --git a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecoratorTest.java b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecoratorTest.java index 038b37673a..401b932fa0 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecoratorTest.java +++ b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecoratorTest.java @@ -109,7 +109,7 @@ public void testExceptionLogWhenThrowException() { .exceptionLog(this.appTaskInstanceService, this.logService) .run(runContext, null); verify(this.appTaskInstanceService, times(1)).update(any(), any()); - verify(this.logService, times(1)).insertLog(any(), any(), any()); + verify(this.logService, times(1)).insertLogWithInterception(any(), any(), any()); } @Test @@ -126,6 +126,6 @@ public void testChatAndExceptionLog() { verify(this.appChatSessionService, times(1)).addSession(any(), any()); verify(this.appChatSSEService, times(2)).send(any(), any()); verify(this.appTaskInstanceService, times(0)).update(any(), any()); - verify(this.logService, times(0)).insertLog(any(), any(), any()); + verify(this.logService, times(0)).insertLogWithInterception(any(), any(), any()); } } diff --git a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallbackTest.java b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallbackTest.java index be6f946d0d..5d9618cde9 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallbackTest.java +++ b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallbackTest.java @@ -156,7 +156,7 @@ void should_ok_when_callback_with_normal_formatter_chain() { }).when(this.formatterChain).handle(any()); this.aippFlowEndCallback.callback(TestUtils.buildFlowDataWithExtraConfig(buildBusinessData(), null)); - verify(this.aippLogService).insertLog(eq(AippInstLogType.META_MSG.name()), any(), any()); + verify(this.aippLogService).insertLogWithInterception(eq(AippInstLogType.META_MSG.name()), any(), any()); } @Test @@ -179,7 +179,7 @@ void test_callback_should_ok_when_test_with_form_data() { this.aippFlowEndCallback.callback(TestUtils.buildFlowDataWithExtraConfig(businessData, null)); verify(this.conversationRecordService).insertConversationRecord(any()); - verify(this.aippLogService).insertLog(eq(AippInstLogType.FORM.name()), any(), any()); + verify(this.aippLogService).insertLogWithInterception(eq(AippInstLogType.FORM.name()), any(), any()); } static class MessageItemStub implements MessageItem { diff --git a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/service/AippLogServiceTest.java b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/service/AippLogServiceTest.java index 28a42ecffe..e2ad23b4ba 100644 --- a/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/service/AippLogServiceTest.java +++ b/app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/service/AippLogServiceTest.java @@ -424,7 +424,7 @@ void shouldReturnNullWhenCallInsertLogWithInvalidFormData() { Map businessData = MapBuilder.get(() -> new HashMap()) .put(AippConst.BS_HTTP_CONTEXT_KEY, "{\"account\":\"123\"}") .build(); - Assertions.assertNull(this.aippLogService.insertLog(AippInstLogType.FORM.name(), aippLogData, businessData)); + Assertions.assertNull(this.aippLogService.insertLogWithInterception(AippInstLogType.FORM.name(), aippLogData, businessData)); } @Test @@ -433,7 +433,7 @@ void shouldThrowWhenCallInsertLogWithInvalidMsgData() { Map businessData = MapBuilder.get(() -> new HashMap()) .put(AippConst.BS_HTTP_CONTEXT_KEY, "{\"account\":\"123\"}").build(); Assertions.assertThrows(NullPointerException.class, - () -> this.aippLogService.insertLog(AippInstLogType.MSG.name(), aippLogData, businessData)); + () -> this.aippLogService.insertLogWithInterception(AippInstLogType.MSG.name(), aippLogData, businessData)); } @Test diff --git a/app-engine/frontend/src/pages/chatPreview/index.tsx b/app-engine/frontend/src/pages/chatPreview/index.tsx index cacc8a83c4..a5b768834d 100644 --- a/app-engine/frontend/src/pages/chatPreview/index.tsx +++ b/app-engine/frontend/src/pages/chatPreview/index.tsx @@ -111,7 +111,7 @@ const ChatPreview = (props) => { const detailPage = location.pathname.indexOf('app-detail') !== -1; const storageId = detailPage ? aippId : appId; const chatStatus = ['ARCHIVED', 'ERROR', 'TERMINATED']; - const messageType = ['MSG', 'ERROR', 'META_MSG']; + const messageType = ['MSG', 'ERROR', 'META_MSG', 'HIDDEN_MSG']; const readOnly = useAppSelector((state) => state.commonStore.isReadOnly); useEffect(() => {