Skip to content

Commit 0fa5276

Browse files
committed
Merge branch '1.2.x'
2 parents b425981 + 5c73d90 commit 0fa5276

File tree

9 files changed

+40
-24
lines changed

9 files changed

+40
-24
lines changed

app-builder/jane/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/dto/aipplog/AippInstLogDataDto.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import java.time.LocalDateTime;
3131
import java.util.Arrays;
32+
import java.util.Comparator;
3233
import java.util.HashMap;
3334
import java.util.HashSet;
3435
import java.util.List;
@@ -78,6 +79,7 @@ public AippInstLogDataDto(AppTaskInstance instance, List<AppLog> logs) {
7879
this.instanceLogBodies = logs.stream()
7980
.filter(l -> !l.isQuestionType())
8081
.map(AppLog::toBody)
82+
.sorted(Comparator.comparing(AippInstanceLogBody::getLogId))
8183
.collect(Collectors.toList());
8284
}
8385
}
@@ -177,10 +179,8 @@ private static String getLogData(String logData, String logType) {
177179
}
178180
String msg = logInfo.get("msg");
179181
if (Objects.equals(logType, AippInstLogType.META_MSG.name())) {
180-
List<Map<String, Object>> referenceMsg = ObjectUtils.cast(JSON.parse(msg));
181-
StringBuilder sb = new StringBuilder();
182-
referenceMsg.stream().map(item -> ObjectUtils.<String>cast(item.get("data"))).forEach(sb::append);
183-
return sb.toString();
182+
Map<String, Object> referenceMsg = ObjectUtils.cast(JSON.parse(msg));
183+
return ObjectUtils.cast(referenceMsg.get("data"));
184184
}
185185
if (Objects.equals(logType, AippInstLogType.QUESTION_WITH_FILE.name())) {
186186
return JSONObject.parseObject(msg).getString("question");

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import modelengine.fit.jober.aipp.util.McpUtils;
2727
import modelengine.fitframework.inspection.Validation;
2828
import modelengine.jade.store.service.ToolService;
29+
import modelengine.fit.jade.aipp.formatter.OutputFormatterChain;
30+
import modelengine.fit.jade.aipp.formatter.support.ResponsibilityResult;
2931
import modelengine.fit.jade.aipp.model.dto.ModelAccessInfo;
3032
import modelengine.fit.jade.aipp.model.service.AippModelCenter;
3133
import modelengine.fit.jade.aipp.prompt.PromptMessage;
@@ -109,6 +111,7 @@ public class LlmComponent implements FlowableService {
109111
private final PromptBuilderChain promptBuilderChain;
110112
private final AppTaskInstanceService appTaskInstanceService;
111113
private final McpClientFactory mcpClientFactory;
114+
private final OutputFormatterChain formatterChain;
112115

113116
/**
114117
* 大模型节点构造器,内部通过提供的 agent 和 tool 构建智能体工作流。
@@ -133,6 +136,7 @@ public LlmComponent(FlowInstanceService flowInstanceService,
133136
AippModelCenter aippModelCenter,
134137
PromptBuilderChain promptBuilderChain,
135138
AppTaskInstanceService appTaskInstanceService,
139+
OutputFormatterChain formatterChain,
136140
McpClientFactory mcpClientFactory) {
137141
this.flowInstanceService = flowInstanceService;
138142
this.toolService = toolService;
@@ -150,6 +154,7 @@ public LlmComponent(FlowInstanceService flowInstanceService,
150154
this.promptBuilderChain = promptBuilderChain;
151155
this.appTaskInstanceService = appTaskInstanceService;
152156
this.mcpClientFactory = notNull(mcpClientFactory, "The mcp client factory cannot be null.");
157+
this.formatterChain = formatterChain;
153158
}
154159

155160
/**
@@ -275,8 +280,12 @@ private void addAnswer(AippLlmMeta llmMeta, String answer, Map<String, Object> p
275280
// 如果节点配置为输出到聊天,模型回复内容需要持久化
276281
boolean enableLog = checkEnableLog(businessData);
277282
if (enableLog) {
278-
this.aippLogService.insertLog(AippInstLogType.MSG.name(),
279-
AippLogData.builder().msg(answer).build(),
283+
Map<String, Object> llmOutput = new HashMap<>();
284+
llmOutput.put("output", output);
285+
Optional<ResponsibilityResult> formatOutput = this.formatterChain.handle(llmOutput);
286+
String logMsg = formatOutput.map(ResponsibilityResult::text).orElse(answer);
287+
this.aippLogService.insertLogWithInterception(AippInstLogType.META_MSG.name(),
288+
AippLogData.builder().msg(logMsg).build(),
280289
businessData);
281290
}
282291

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,6 @@ 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-
243238
return result;
244239
}
245240

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import modelengine.fel.tool.mcp.client.McpClientFactory;
2323
import modelengine.fel.tool.mcp.entity.Tool;
2424
import modelengine.fel.tool.model.transfer.ToolData;
25+
import modelengine.fit.jade.aipp.formatter.OutputFormatterChain;
2526
import modelengine.fit.jade.aipp.model.dto.ModelListDto;
2627
import modelengine.fit.jade.aipp.model.service.AippModelCenter;
2728
import modelengine.fit.jade.aipp.prompt.PromptBuilder;
@@ -105,6 +106,8 @@ public class LlmComponentTest {
105106
private AippModelCenter aippModelCenter;
106107
@Mock
107108
private McpClientFactory mcpClientFactory;
109+
@Mock
110+
private OutputFormatterChain formatterChain;
108111

109112
static class PromptBuilderStub implements PromptBuilder {
110113
@Override
@@ -240,7 +243,8 @@ void shouldFailedWhenNoTool() throws InterruptedException {
240243
this.aippModelCenter,
241244
this.promptBuilderChain,
242245
this.appTaskInstanceService,
243-
this.mcpClientFactory);
246+
this.mcpClientFactory,
247+
this.formatterChain);
244248

245249
// mock
246250
CountDownLatch countDownLatch = mockFailAsyncJob(flowInstanceService);
@@ -405,7 +409,8 @@ private LlmComponent getLlmComponent(final AbstractAgent agent) {
405409
this.aippModelCenter,
406410
this.promptBuilderChain,
407411
this.appTaskInstanceService,
408-
this.mcpClientFactory);
412+
this.mcpClientFactory,
413+
this.formatterChain);
409414
}
410415

411416
private void prepareModel() {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Ability
2-
You can use the content of # Reference to answer the question. you can add label : <ref>{reference ID}</ref>(Single reference) or <ref>{reference ID1}</ref><ref>{reference ID2}</ref>(Multiple reference) for referenceing. You should not add reference for question that you can directly answer without content in # Reference, and you should not mention anything about # Reference when meet irrelevant question.\n
2+
You can use the content of # Reference to answer the question. you can add label : <ref>reference ID</ref>(Single reference) or <ref>reference ID1</ref><ref>reference ID2</ref>(Multiple reference) for referenceing. You should not add reference for question that you can directly answer without content in # Reference, and you should not mention anything about # Reference when meet irrelevant question.\n
33
# Reference:
44
{{knowledgeData}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# 能力
2-
您可以使用 # 参考文献 的内容来回答问题。您可以添加标签:<ref>{引用ID}</ref>(单个引用)或<ref>{引用ID 1}</ref><ref>{引用ID 2}</ref>(多个引用)来引用。不需要 # 参考文献就可以直接回答的问题,不应该添加引用,遇到无关的问题,也不应该提及有关 # 参考文献 的任何内容。\n
2+
您可以使用 # 参考文献 的内容来回答问题。您可以添加标签:<ref>引用ID</ref>(单个引用)或<ref>引用ID 1</ref><ref>引用ID 2</ref>(多个引用)来引用。不需要 # 参考文献就可以直接回答的问题,不应该添加引用,遇到无关的问题,也不应该提及有关 # 参考文献 的任何内容。\n
33
# 参考文献:
44
{{knowledgeData}}

app-builder/plugins/aipp-prompt-builder/src/test/java/modelengine/fit/jade/aipp/prompt/PromptBuilderChainTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ void shouldOkWhenPromptBuilderWithLocaleZh() {
132132
List<String> refIds = ReferenceUtil.getReferenceIds(promptMessage.get());
133133
assertThat(refIds).hasSize(3);
134134
assertThat(promptMessage.get().getSystemMessage()).contains("# 人设与回复逻辑",
135-
"<ref>{引用ID}</ref>",
135+
"<ref>引用ID</ref>",
136136
StringUtils.format("参考文献:\n[{0}] text0\n[{1}] text1\n[{2}] text2\n",
137137
refIds.get(0),
138138
refIds.get(1),
@@ -158,7 +158,7 @@ void shouldOkWhenPromptBuilderWithLocaleEn() {
158158
List<String> refIds = ReferenceUtil.getReferenceIds(promptMessage.get());
159159
assertThat(refIds).hasSize(3);
160160
assertThat(promptMessage.get().getSystemMessage()).contains("# Personal setting and recovering Logic",
161-
"<ref>{reference ID}</ref>",
161+
"<ref>reference ID</ref>",
162162
StringUtils.format("Reference:\n[{0}] text0\n[{1}] text1\n[{2}] text2\n",
163163
refIds.get(0),
164164
refIds.get(1),
@@ -179,7 +179,7 @@ void shouldOkWhenPromptBuilderChainBuildWithNormalData() {
179179
List<String> refIds = ReferenceUtil.getReferenceIds(promptMessage.get());
180180
assertThat(refIds).hasSize(3);
181181
assertThat(promptMessage.get().getSystemMessage()).contains("# 人设与回复逻辑",
182-
"<ref>{引用ID}</ref>",
182+
"<ref>引用ID</ref>",
183183
StringUtils.format("参考文献:\n[{0}] text0\n[{1}] text1\n[{2}] text2\n",
184184
refIds.get(0),
185185
refIds.get(1),

app-builder/plugins/aipp-prompt-builder/src/test/java/modelengine/fit/jade/aipp/prompt/ReferencePromptBuilderTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ void shouldOkWhenReferenceBuilderWithNormalUserAdviceInLocaleZh() {
107107
List<String> refIds = ReferenceUtil.getReferenceIds(promptMessage);
108108
assertThat(refIds).hasSize(3);
109109
assertThat(promptMessage.getSystemMessage()).contains("# 人设与回复逻辑",
110-
"<ref>{引用ID}</ref>",
110+
"<ref>引用ID</ref>",
111111
StringUtils.format("参考文献:\n[{0}] text0\n[{1}] text1\n[{2}] text2\n",
112112
refIds.get(0), refIds.get(1), refIds.get(2)));
113113
assertThat(promptMessage.getHumanMessage()).isEqualTo("template value0");
@@ -127,7 +127,7 @@ void shouldOkWhenReferenceBuilderWithNormalUserAdviceInLocaleEn() {
127127
List<String> refIds = ReferenceUtil.getReferenceIds(promptMessage);
128128
assertThat(refIds).hasSize(3);
129129
assertThat(promptMessage.getSystemMessage()).contains("# Personal setting and recovering Logic",
130-
"<ref>{reference ID}</ref>",
130+
"<ref>reference ID</ref>",
131131
StringUtils.format("Reference:\n[{0}] text0\n[{1}] text1\n[{2}] text2\n",
132132
refIds.get(0), refIds.get(1), refIds.get(2)));
133133
assertThat(promptMessage.getHumanMessage()).isEqualTo("template value0");

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ const ChatPreview = (props) => {
416416
let msg = messageData.extensions.stageDesc || '';
417417
receiveItem.content = msg;
418418
receiveItem.logId = messageData.log_id;
419-
chatStrInit(msg, receiveItem, messageData.status, messageData.log_id, { isStepLog: true });
419+
chatStrInit(msg, receiveItem, messageData.status, messageData.log_id, { isStepLog: true }, false);
420420
return
421421
}
422422
// 普通日志
@@ -440,7 +440,7 @@ const ChatPreview = (props) => {
440440
if (log.msgId) {
441441
chatSplicing(log, msg, recieveChatItem, messageData.status);
442442
} else {
443-
chatStrInit(msg, recieveChatItem, messageData.status, messageData.log_id, messageData.extensions);
443+
chatStrInit(msg, recieveChatItem, messageData.status, messageData.log_id, messageData.extensions, false);
444444
}
445445
}
446446
});
@@ -481,7 +481,7 @@ const ChatPreview = (props) => {
481481
scrollToBottom();
482482
};
483483
// 流式输出
484-
function chatStrInit(msg, initObj, status, logId, extensions:any = {}) {
484+
function chatStrInit(msg, initObj, status, logId, extensions:any = {}, addChat) {
485485
let idx = 0;
486486
if (isJsonString(msg)) {
487487
let msgObj = JSON.parse(msg);
@@ -494,6 +494,9 @@ const ChatPreview = (props) => {
494494
}
495495
initObj.loading = false;
496496
idx = listRef.current.length - 1;
497+
if (addChat) {
498+
idx = listRef.current.length;
499+
}
497500
if (status === 'ARCHIVED') {
498501
initObj.finished = true;
499502
if (extensions.isEnableLog && !listRef.current[idx].loading) {
@@ -543,7 +546,11 @@ const ChatPreview = (props) => {
543546
}
544547
dispatch(setChatList(deepClone(listRef.current)));
545548
} else {
546-
chatStrInit(msg, initObj, status, '');
549+
let addChat = false;
550+
if (!listRef.current[listRef.current.length - 1].loading) {
551+
addChat = true;
552+
}
553+
chatStrInit(msg, initObj, status, '', {}, addChat);
547554
}
548555
}
549556
// 多模型回答时消息处理

0 commit comments

Comments
 (0)