Skip to content

Commit 6a72ffe

Browse files
authored
[app-builder] Persist the output of model nodes when enableLog is true (#272)
* [app-builder] Persist the output of model nodes when enableLog configuration is true * [app-builder] Update according to review
1 parent 0f17757 commit 6a72ffe

File tree

14 files changed

+80
-31
lines changed

14 files changed

+80
-31
lines changed

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/task/TaskDecorator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private Object invokeMethod(Method method, Object[] args, Object current)
111111
else {
112112
msg = localeService.localize(UI_WORD_KEY);
113113
}
114-
this.aippLogService.insertLog(AippInstLogType.ERROR.name(),
114+
this.aippLogService.insertLogWithInterception(AippInstLogType.ERROR.name(),
115115
AippLogData.builder().msg(msg).build(), ctx.getBusinessData());
116116
return null;
117117
}

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecorator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ private Object wrapException(AppTaskInstanceService instanceService, AippLogServ
142142
.setStatus(MetaInstStatusEnum.ERROR.name())
143143
.build(), ctx.getOperationContext());
144144
// 更新日志类型为HIDDEN_FORM
145-
logService.insertLog(AippInstLogType.ERROR.name(), AippLogData.builder().msg(e.getMessage()).build(),
145+
logService.insertLogWithInterception(AippInstLogType.ERROR.name(), AippLogData.builder().msg(e.getMessage()).build(),
146146
ctx.getBusinessData());
147147
}
148148
return null;

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallback.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
package modelengine.fit.jober.aipp.fitable;
88

9+
import static modelengine.fit.jober.aipp.fitable.LlmComponent.checkEnableLog;
10+
911
import modelengine.fit.jade.aipp.formatter.OutputFormatterChain;
1012
import modelengine.fit.jade.aipp.formatter.constant.Constant;
1113
import modelengine.fit.jade.aipp.formatter.support.ResponsibilityResult;
@@ -184,7 +186,7 @@ private String saveFormToLog(String appId, Map<String, Object> businessData, Str
184186
logData.setFormAppearance(JsonUtils.toJsonString(formDataMap.get(AippConst.FORM_APPEARANCE_KEY)));
185187
logData.setFormData(JsonUtils.toJsonString(formDataMap.get(AippConst.FORM_DATA_KEY)));
186188
// 子应用/工作流的结束节点表单不需要在历史记录展示
187-
return this.aippLogService.insertLog((this.isExistParent(businessData)
189+
return this.aippLogService.insertLogWithInterception((this.isExistParent(businessData)
188190
? AippInstLogType.HIDDEN_FORM
189191
: AippInstLogType.FORM).name(), logData, businessData);
190192
}
@@ -206,7 +208,10 @@ private void logFinalOutput(Map<String, Object> businessData, String aippInstId)
206208
String logMsg = formatOutput.map(ResponsibilityResult::text).orElse(CHECK_TIP);
207209
AippInstLogType logType = formatOutput.flatMap(result -> Optional.ofNullable(LOG_STRATEGY.get(result.owner())))
208210
.orElse(AippInstLogType.MSG);
209-
this.aippLogService.insertLog(logType.name(), AippLogData.builder().msg(logMsg).build(), businessData);
211+
if (!checkEnableLog(businessData)) {
212+
logType = AippInstLogType.HIDDEN_MSG;
213+
}
214+
this.aippLogService.insertLogWithInterception(logType.name(), AippLogData.builder().msg(logMsg).build(), businessData);
210215
this.beanContainer.all(AppFlowFinishObserver.class)
211216
.stream()
212217
.<AppFlowFinishObserver>map(BeanFactory::get)

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/AippFlowSmartFormHandle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private String insertFormLog(List<AppBuilderFormProperty> formProperties, String
177177
Object appearance = formDataMap.get(AippConst.FORM_APPEARANCE_KEY);
178178
logData.setFormAppearance(ObjectUtils.cast(JsonUtils.toJsonString(appearance)));
179179
logData.setFormData(ObjectUtils.cast(JsonUtils.toJsonString(formDataMap.get(AippConst.FORM_DATA_KEY))));
180-
return this.aippLogService.insertLog(AippInstLogType.FORM.name(), logData, businessData);
180+
return this.aippLogService.insertLogWithInterception(AippInstLogType.FORM.name(), logData, businessData);
181181
}
182182

183183
private void updateInstance(String sheetId, String nodeId, Map<String, Object> businessData) {

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/fitable/LlmComponent.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,14 @@ private void addAnswer(AippLlmMeta llmMeta, String answer, Map<String, Object> p
364364
output.put("reference", promptMetadata.getOrDefault(PROMPT_METADATA_KEY, Collections.emptyMap()));
365365
businessData.put("output", output);
366366

367+
// 如果节点配置为输出到聊天,模型回复内容需要持久化
368+
boolean enableLog = checkEnableLog(businessData);
369+
if (enableLog) {
370+
this.aippLogService.insertLog(AippInstLogType.MSG.name(),
371+
AippLogData.builder().msg(answer).build(),
372+
businessData);
373+
}
374+
367375
// 修改taskInstance.
368376
AppTaskInstance updateEntity = AppTaskInstance.asUpdate(llmMeta.getVersionId(), llmMeta.getInstId())
369377
.setLlmOutput(answer)
@@ -537,6 +545,14 @@ public ModelExtraBody(String sessionId) {
537545
}
538546
}
539547

548+
public static boolean checkEnableLog(Map<String, Object> businessData) {
549+
Object value = businessData.get(AippConst.BS_LLM_ENABLE_LOG);
550+
if (value == null) {
551+
return true;
552+
}
553+
return Boolean.parseBoolean(value.toString());
554+
}
555+
540556
static class StreamMsgSender {
541557
private final AippLogStreamService aippLogStreamService;
542558
private final ObjectSerializer serializer;
@@ -560,7 +576,7 @@ static class StreamMsgSender {
560576
* @param businessData 表示流程上下文的 {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}。
561577
*/
562578
public void sendMsg(String msg, Map<String, Object> businessData) {
563-
boolean enableLog = this.checkEnableLog(businessData);
579+
boolean enableLog = checkEnableLog(businessData);
564580
if (!enableLog || StringUtils.isBlank(msg) || msg.contains("<tool_call>")) {
565581
return;
566582
}
@@ -574,19 +590,13 @@ public void sendMsg(String msg, Map<String, Object> businessData) {
574590
* @param businessData 表示流程上下文的 {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}。
575591
*/
576592
public void sendKnowledge(Map<String, Object> promptMetadata, Map<String, Object> businessData) {
577-
if (!this.checkEnableLog(businessData) || !promptMetadata.containsKey(PROMPT_METADATA_KEY)) {
593+
if (!checkEnableLog(businessData) || !promptMetadata.containsKey(PROMPT_METADATA_KEY)) {
578594
return;
579595
}
580596
String knowledgeData = this.serializer.serialize(promptMetadata.get(PROMPT_METADATA_KEY));
581597
this.sendMsgHandle(knowledgeData, StreamMsgType.KNOWLEDGE, businessData);
582598
}
583599

584-
private Boolean checkEnableLog(Map<String, Object> businessData) {
585-
return Objects.isNull(businessData.get(AippConst.BS_LLM_ENABLE_LOG))
586-
? true
587-
: ObjectUtils.cast(businessData.get(AippConst.BS_LLM_ENABLE_LOG));
588-
}
589-
590600
private void sendMsgHandle(String msg, StreamMsgType logType, Map<String, Object> businessData) {
591601
RunContext runContext = new RunContext(businessData, new OperationContext());
592602
String chatId = runContext.getOriginChatId();

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/AippLogService.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public interface AippLogService {
9393
* @param businessData 业务数据
9494
* @return 返回插入的日志id
9595
*/
96-
String insertLog(String logType, AippLogData logData, Map<String, Object> businessData);
96+
String insertLogWithInterception(String logType, AippLogData logData, Map<String, Object> businessData);
9797

9898
/**
9999
* 插入ERROR类型的历史记录
@@ -185,4 +185,13 @@ List<AippInstLogDataDto> queryAippRecentInstLogAfterSplice(String aippId, String
185185
* @param logIds 表示指定的日志 id 列表的 {@link List}{@code <}{@link Long}{@code >}。
186186
*/
187187
void deleteLogs(List<Long> logIds);
188+
189+
/**
190+
* 插入一条日志记录,但不触发发送逻辑。
191+
*
192+
* @param logType 表示日志类型的 {@link String}。
193+
* @param logData 表示日志主体数据的 {@link AippLogData} 实例。
194+
* @param businessData 表示业务数据的 {@link Map}{@code <}{@link String}{@code , }{@link Object}{@code >}。
195+
*/
196+
void insertLog(String logType, AippLogData logData, Map<String, Object> businessData);
188197
}

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogServiceImpl.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ private Map<String, List<AippInstLog>> queryRecentLogByInstanceIds(List<String>
235235
}
236236
}
237237
}
238+
239+
for (List<AippInstLog> logList : result.values()) {
240+
logList.sort(Comparator.comparing(AippInstLog::getLogId));
241+
}
242+
238243
return result;
239244
}
240245

@@ -362,7 +367,16 @@ public void deleteAippPreviewLog(String previewAippId, OperationContext context)
362367
* @return 日志id
363368
*/
364369
@Override
365-
public String insertLog(String logType, AippLogData logData, Map<String, Object> businessData) {
370+
public String insertLogWithInterception(String logType, AippLogData logData, Map<String, Object> businessData) {
371+
AippLogCreateDto logCreateDto = this.buildAippLogCreateDto(logType, logData, businessData);
372+
if (logCreateDto == null) {
373+
return null;
374+
}
375+
return this.aopAippLogService.insertLog(logCreateDto);
376+
}
377+
378+
private AippLogCreateDto buildAippLogCreateDto(String logType, AippLogData logData,
379+
Map<String, Object> businessData) {
366380
RunContext runContext = new RunContext(businessData, new OperationContext());
367381
String aippId = runContext.getAppSuiteId();
368382
String instId = runContext.getTaskInstanceId();
@@ -376,7 +390,7 @@ public String insertLog(String logType, AippLogData logData, Map<String, Object>
376390
String path = this.buildPath(instId, parentInstId);
377391
String chatId = runContext.getOriginChatId();
378392
String atChatId = runContext.getAtChatId();
379-
return this.aopAippLogService.insertLog(AippLogCreateDto.builder()
393+
return AippLogCreateDto.builder()
380394
.aippId(aippId)
381395
.version(version)
382396
.aippType(aippType)
@@ -388,8 +402,9 @@ public String insertLog(String logType, AippLogData logData, Map<String, Object>
388402
.chatId(chatId)
389403
.atChatId(atChatId)
390404
.isEnableLog(this.isEnableLog(businessData))
391-
.build());
405+
.build();
392406
}
407+
393408
private Boolean isEnableLog(Map<String, Object> businessData) {
394409
// 兼容老数据,老数据没有这个开关的时候(enableLog为null)默认返回true。
395410
// 有开关后(enableLog为null),返回enableLog的值
@@ -406,7 +421,7 @@ private Boolean isEnableLog(Map<String, Object> businessData) {
406421
@Override
407422
public void insertErrorLog(String msg, List<Map<String, Object>> flowData) {
408423
AippLogData logData = AippLogData.builder().msg(msg).build();
409-
insertLog(AippInstLogType.ERROR.name(), logData, DataUtils.getBusiness(flowData));
424+
insertLogWithInterception(AippInstLogType.ERROR.name(), logData, DataUtils.getBusiness(flowData));
410425
}
411426

412427
/**
@@ -502,4 +517,13 @@ public void deleteLogs(List<Long> logIds) {
502517
}
503518
this.aippLogMapper.deleteInstanceLogs(logIds);
504519
}
520+
521+
@Override
522+
public void insertLog(String logType, AippLogData logData, Map<String, Object> businessData) {
523+
AippLogCreateDto logCreateDto = this.buildAippLogCreateDto(logType, logData, businessData);
524+
if (logCreateDto == null) {
525+
return;
526+
}
527+
this.aippLogMapper.insertOne(logCreateDto);
528+
}
505529
}

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/service/impl/AippLogStreamServiceImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public class AippLogStreamServiceImpl implements AippLogStreamService {
4141
private static final List<String> OUTPUT_WITH_MSG_WHITE_LIST = Arrays.asList(AippInstLogType.MSG.name(),
4242
AippInstLogType.ERROR.name(),
4343
AippInstLogType.META_MSG.name(),
44-
StreamMsgType.KNOWLEDGE.value());
44+
StreamMsgType.KNOWLEDGE.value(),
45+
AippInstLogType.HIDDEN_MSG.name());
4546

4647
private final AppChatSseService appChatSseService;
4748
private final SensitiveFilterTools sensitiveFilterTools;

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/vo/AippLogVO.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ public static AippLogVO fromCreateDto(AippLogCreateDto dto) {
8484
*/
8585
public boolean displayable() {
8686
return !(StringUtils.equals(AippInstLogType.FORM.name(), this.logType)
87-
|| StringUtils.equals(AippInstLogType.HIDDEN_MSG.name(), this.logType) || StringUtils.equals(
88-
AippInstLogType.HIDDEN_QUESTION.name(),
89-
this.logType) || StringUtils.equals(AippInstLogType.HIDDEN_FORM.name(), this.logType));
87+
|| StringUtils.equals(AippInstLogType.HIDDEN_QUESTION.name(), this.logType) || StringUtils.equals(
88+
AippInstLogType.HIDDEN_FORM.name(),
89+
this.logType));
9090
}
9191

9292
/**

app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/task/TaskDecoratorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public void testException() {
6666

6767
doNothing().when(this.appTaskInstanceService).update(any(), any());
6868
when(this.localeService.localize(any())).thenReturn("xxxxxxx");
69-
when(this.aippLogService.insertLog(any(), any(), any())).thenReturn("xxxxxx");
69+
when(this.aippLogService.insertLogWithInterception(any(), any(), any())).thenReturn("xxxxxx");
7070

7171
// when.
7272
RunContext runContext = new RunContext(businessData, new OperationContext());
@@ -84,6 +84,6 @@ public void testException() {
8484
Assertions.assertEquals(MetaInstStatusEnum.ERROR.name(), instance.getEntity().getStatus().get());
8585

8686
verify(this.localeService, times(1)).localize(eq("aipp.service.impl.AippRunTimeServiceImpl"));
87-
verify(this.aippLogService, times(1)).insertLog(eq(AippInstLogType.ERROR.name()), any(), any());
87+
verify(this.aippLogService, times(1)).insertLogWithInterception(eq(AippInstLogType.ERROR.name()), any(), any());
8888
}
8989
}

app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/domains/taskinstance/TaskInstanceDecoratorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public void testExceptionLogWhenThrowException() {
109109
.exceptionLog(this.appTaskInstanceService, this.logService)
110110
.run(runContext, null);
111111
verify(this.appTaskInstanceService, times(1)).update(any(), any());
112-
verify(this.logService, times(1)).insertLog(any(), any(), any());
112+
verify(this.logService, times(1)).insertLogWithInterception(any(), any(), any());
113113
}
114114

115115
@Test
@@ -126,6 +126,6 @@ public void testChatAndExceptionLog() {
126126
verify(this.appChatSessionService, times(1)).addSession(any(), any());
127127
verify(this.appChatSSEService, times(2)).send(any(), any());
128128
verify(this.appTaskInstanceService, times(0)).update(any(), any());
129-
verify(this.logService, times(0)).insertLog(any(), any(), any());
129+
verify(this.logService, times(0)).insertLogWithInterception(any(), any(), any());
130130
}
131131
}

app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/fitable/AippFlowEndCallbackTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ void should_ok_when_callback_with_normal_formatter_chain() {
156156
}).when(this.formatterChain).handle(any());
157157

158158
this.aippFlowEndCallback.callback(TestUtils.buildFlowDataWithExtraConfig(buildBusinessData(), null));
159-
verify(this.aippLogService).insertLog(eq(AippInstLogType.META_MSG.name()), any(), any());
159+
verify(this.aippLogService).insertLogWithInterception(eq(AippInstLogType.META_MSG.name()), any(), any());
160160
}
161161

162162
@Test
@@ -179,7 +179,7 @@ void test_callback_should_ok_when_test_with_form_data() {
179179

180180
this.aippFlowEndCallback.callback(TestUtils.buildFlowDataWithExtraConfig(businessData, null));
181181
verify(this.conversationRecordService).insertConversationRecord(any());
182-
verify(this.aippLogService).insertLog(eq(AippInstLogType.FORM.name()), any(), any());
182+
verify(this.aippLogService).insertLogWithInterception(eq(AippInstLogType.FORM.name()), any(), any());
183183
}
184184

185185
static class MessageItemStub implements MessageItem {

app-builder/jane/plugins/aipp-plugin/src/test/java/modelengine/fit/jober/aipp/service/AippLogServiceTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ void shouldReturnNullWhenCallInsertLogWithInvalidFormData() {
424424
Map<String, Object> businessData = MapBuilder.get(() -> new HashMap<String, Object>())
425425
.put(AippConst.BS_HTTP_CONTEXT_KEY, "{\"account\":\"123\"}")
426426
.build();
427-
Assertions.assertNull(this.aippLogService.insertLog(AippInstLogType.FORM.name(), aippLogData, businessData));
427+
Assertions.assertNull(this.aippLogService.insertLogWithInterception(AippInstLogType.FORM.name(), aippLogData, businessData));
428428
}
429429

430430
@Test
@@ -433,7 +433,7 @@ void shouldThrowWhenCallInsertLogWithInvalidMsgData() {
433433
Map<String, Object> businessData = MapBuilder.get(() -> new HashMap<String, Object>())
434434
.put(AippConst.BS_HTTP_CONTEXT_KEY, "{\"account\":\"123\"}").build();
435435
Assertions.assertThrows(NullPointerException.class,
436-
() -> this.aippLogService.insertLog(AippInstLogType.MSG.name(), aippLogData, businessData));
436+
() -> this.aippLogService.insertLogWithInterception(AippInstLogType.MSG.name(), aippLogData, businessData));
437437
}
438438

439439
@Test

app-engine/frontend/src/pages/chatPreview/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const ChatPreview = (props) => {
111111
const detailPage = location.pathname.indexOf('app-detail') !== -1;
112112
const storageId = detailPage ? aippId : appId;
113113
const chatStatus = ['ARCHIVED', 'ERROR', 'TERMINATED'];
114-
const messageType = ['MSG', 'ERROR', 'META_MSG'];
114+
const messageType = ['MSG', 'ERROR', 'META_MSG', 'HIDDEN_MSG'];
115115
const readOnly = useAppSelector((state) => state.commonStore.isReadOnly);
116116

117117
useEffect(() => {

0 commit comments

Comments
 (0)