mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 20:08:18 +08:00
feat(agent): add kill-switch for final-answer Markdown normalization
Gate MarkdownNormalizer behind mate.agent.markdown-normalize-enabled (default true) so operators can disable the rewrite verbatim if a normalization edge case ever mangles a legitimate answer.
This commit is contained in:
parent
398d7a2d80
commit
46f3d425e0
@ -88,6 +88,11 @@ public class AgentGraphBuilder {
|
|||||||
@org.springframework.beans.factory.annotation.Value(
|
@org.springframework.beans.factory.annotation.Value(
|
||||||
"${mateclaw.skill.disclosure.load-skill-tool.enabled:true}")
|
"${mateclaw.skill.disclosure.load-skill-tool.enabled:true}")
|
||||||
private boolean loadSkillToolEnabled;
|
private boolean loadSkillToolEnabled;
|
||||||
|
|
||||||
|
/** Escape hatch: when false, the final answer is sent verbatim without Markdown normalization. */
|
||||||
|
@org.springframework.beans.factory.annotation.Value(
|
||||||
|
"${mate.agent.markdown-normalize-enabled:true}")
|
||||||
|
private boolean markdownNormalizeEnabled;
|
||||||
private final ConversationService conversationService;
|
private final ConversationService conversationService;
|
||||||
private final ModelConfigService modelConfigService;
|
private final ModelConfigService modelConfigService;
|
||||||
private final ModelProviderService modelProviderService;
|
private final ModelProviderService modelProviderService;
|
||||||
@ -809,7 +814,7 @@ public class AgentGraphBuilder {
|
|||||||
SummarizingNode summarizingNode = new SummarizingNode(chatModel, streamingHelper, streamTracker);
|
SummarizingNode summarizingNode = new SummarizingNode(chatModel, streamingHelper, streamTracker);
|
||||||
LimitExceededNode limitExceededNode = new LimitExceededNode(
|
LimitExceededNode limitExceededNode = new LimitExceededNode(
|
||||||
chatModel, observationProcessor, streamingHelper, i18nService, progressLedgerService);
|
chatModel, observationProcessor, streamingHelper, i18nService, progressLedgerService);
|
||||||
FinalAnswerNode finalAnswerNode = new FinalAnswerNode(generatedFileCache);
|
FinalAnswerNode finalAnswerNode = new FinalAnswerNode(generatedFileCache, markdownNormalizeEnabled);
|
||||||
|
|
||||||
KeyStrategyFactory keyStrategyFactory = KeyStrategy.builder()
|
KeyStrategyFactory keyStrategyFactory = KeyStrategy.builder()
|
||||||
// 输入字段
|
// 输入字段
|
||||||
|
|||||||
@ -40,12 +40,25 @@ public class FinalAnswerNode implements NodeAction {
|
|||||||
*/
|
*/
|
||||||
private final GeneratedFileCache generatedFileCache;
|
private final GeneratedFileCache generatedFileCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kill-switch for the deterministic Markdown cleanup applied to the answer
|
||||||
|
* body. {@code true} (default) runs {@link MarkdownNormalizer}; set to
|
||||||
|
* {@code false} to surface model output verbatim if a normalization edge
|
||||||
|
* case ever mangles a legitimate answer in production.
|
||||||
|
*/
|
||||||
|
private final boolean markdownNormalizeEnabled;
|
||||||
|
|
||||||
public FinalAnswerNode() {
|
public FinalAnswerNode() {
|
||||||
this(null);
|
this(null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FinalAnswerNode(GeneratedFileCache generatedFileCache) {
|
public FinalAnswerNode(GeneratedFileCache generatedFileCache) {
|
||||||
|
this(generatedFileCache, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FinalAnswerNode(GeneratedFileCache generatedFileCache, boolean markdownNormalizeEnabled) {
|
||||||
this.generatedFileCache = generatedFileCache;
|
this.generatedFileCache = generatedFileCache;
|
||||||
|
this.markdownNormalizeEnabled = markdownNormalizeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -176,8 +189,11 @@ public class FinalAnswerNode implements NodeAction {
|
|||||||
// unaligned table pipes) that prompt rules fail to prevent; this fixes the
|
// unaligned table pipes) that prompt rules fail to prevent; this fixes the
|
||||||
// mechanical defects before the answer is persisted / sent to channels.
|
// mechanical defects before the answer is persisted / sent to channels.
|
||||||
// Verbatim tool output (RETURN_DIRECT) and approval-wait paths return early
|
// Verbatim tool output (RETURN_DIRECT) and approval-wait paths return early
|
||||||
// above and are intentionally left untouched.
|
// above and are intentionally left untouched. Gated so operators can turn
|
||||||
finalAnswer = MarkdownNormalizer.normalize(finalAnswer);
|
// the rewrite off (mate.agent.markdown-normalize-enabled=false).
|
||||||
|
if (markdownNormalizeEnabled) {
|
||||||
|
finalAnswer = MarkdownNormalizer.normalize(finalAnswer);
|
||||||
|
}
|
||||||
|
|
||||||
// Build the event list. Always carries the finish_reason event so
|
// Build the event list. Always carries the finish_reason event so
|
||||||
// downstream consumers (memory gate, channel accumulator, message
|
// downstream consumers (memory gate, channel accumulator, message
|
||||||
|
|||||||
@ -222,6 +222,10 @@ mateclaw:
|
|||||||
# MateClaw Agent 配置
|
# MateClaw Agent 配置
|
||||||
mate:
|
mate:
|
||||||
agent:
|
agent:
|
||||||
|
# Deterministic Markdown cleanup of the final answer (heading spaces, glued
|
||||||
|
# ---, table pipe alignment) before persistence / channel delivery. Set to
|
||||||
|
# false to pass model output through verbatim.
|
||||||
|
markdown-normalize-enabled: true
|
||||||
graph:
|
graph:
|
||||||
observation:
|
observation:
|
||||||
# 与 GraphObservationProperties.java 默认值对齐,参考 openclaw token-budget 设计
|
# 与 GraphObservationProperties.java 默认值对齐,参考 openclaw token-budget 设计
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user