mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-11-10 21:32:43 +08:00
fix: prevent agent message template feedback (#20042)
This commit is contained in:
1 parent
654fb577f5
commit
59eb2bf153
3 files changed
+48
-7
No files matched your search
@@ -2310,7 +2310,7 @@ func (s *AgentService) buildRunFunc(canvasID string, versionRow *entity.UserCanv
|
||||
return state, err
|
||||
}
|
||||
if shouldTreatAsCompletedLoopRun(err, answer) {
|
||||
appendAssistantHistory(state, assistantOutput)
|
||||
appendAssistantHistory(state, partialAssistantOutput(answer, downloads, attachment))
|
||||
if persistErr := s.persistAgentRunSession(ctx, canvasID, userID, sessionID, messageID, userInput, answer, thinking, referencePayload, dsl, state, true); persistErr != nil {
|
||||
s.markRunFailed(ctx2, runID, "persist session: "+persistErr.Error())
|
||||
return nil, canvas.NewInternalRunError(
|
||||
@@ -2331,7 +2331,7 @@ func (s *AgentService) buildRunFunc(canvasID string, versionRow *entity.UserCanv
|
||||
|
||||
wfPayload := map[string]interface{}{
|
||||
"inputs": map[string]any{"query": userInput},
|
||||
"outputs": workflowOutputs(answer, downloads, attachment),
|
||||
"outputs": workflowOutputsFromTerminal(assistantOutput),
|
||||
"elapsed_time": now - startedAt,
|
||||
"created_at": now,
|
||||
}
|
||||
@@ -2370,8 +2370,11 @@ func (s *AgentService) buildRunFunc(canvasID string, versionRow *entity.UserCanv
|
||||
return nil, canvasInvokeError(err)
|
||||
}
|
||||
|
||||
// Emit message + message_end (mirrors Python's ans dict).
|
||||
appendAssistantHistory(state, assistantOutput)
|
||||
// Persist the Agent answer for subsequent Agent prompts. The terminal
|
||||
// Message output is presentation data and may wrap the answer with
|
||||
// template literals; retaining it in the prompt history makes the model
|
||||
// reproduce and amplify those literals on later turns.
|
||||
appendAssistantHistory(state, partialAssistantOutput(answer, downloads, attachment))
|
||||
if persistErr := s.persistAgentRunSession(ctx, canvasID, userID, sessionID, messageID, userInput, answer, thinking, referencePayload, dsl, state, true); persistErr != nil {
|
||||
s.markRunFailed(ctx2, runID, "persist session: "+persistErr.Error())
|
||||
return nil, canvas.NewInternalRunError(
|
||||
@@ -2394,7 +2397,7 @@ func (s *AgentService) buildRunFunc(canvasID string, versionRow *entity.UserCanv
|
||||
// per-run token usage across all LLM calls in this turn.
|
||||
wfPayload := map[string]interface{}{
|
||||
"inputs": map[string]any{"query": userInput},
|
||||
"outputs": workflowOutputs(answer, downloads, attachment),
|
||||
"outputs": workflowOutputsFromTerminal(assistantOutput),
|
||||
"elapsed_time": now - startedAt,
|
||||
"created_at": now,
|
||||
}
|
||||
@@ -2506,6 +2509,17 @@ func workflowOutputs(content string, downloads, attachment any) any {
|
||||
return out
|
||||
}
|
||||
|
||||
// workflowOutputsFromTerminal preserves the terminal component's complete
|
||||
// visible content in workflow_finished while retaining the established compact
|
||||
// string shape when it has no downloads or attachment.
|
||||
func workflowOutputsFromTerminal(output map[string]any) any {
|
||||
if len(output) == 0 {
|
||||
return ""
|
||||
}
|
||||
content, _ := output["content"].(string)
|
||||
return workflowOutputs(content, output["downloads"], output["attachment"])
|
||||
}
|
||||
|
||||
// emptyAttachmentValue reports whether an attachment descriptor is
|
||||
// absent or empty (nil or an empty map), matching the omitempty
|
||||
// semantics of the message_end frame.
|
||||
|
||||
@@ -327,8 +327,8 @@ func TestRunAgent_SessionHistoryFeedsSysHistoryAndPersists(t *testing.T) {
|
||||
}
|
||||
if !strings.HasPrefix(secondHistory[0], "assistant: ") ||
|
||||
!strings.Contains(secondHistory[0], `'content': '["user: hi"]'`) ||
|
||||
!strings.Contains(secondHistory[0], `'downloads': []`) {
|
||||
t.Fatalf("assistant history entry = %q, want persisted Message content and downloads", secondHistory[0])
|
||||
strings.Contains(secondHistory[0], `'downloads': []`) {
|
||||
t.Fatalf("assistant history entry = %q, want raw Agent output without Message presentation fields", secondHistory[0])
|
||||
}
|
||||
if secondHistory[1] != "user: again" || secondHistory[2] != "user: hi" {
|
||||
t.Fatalf("sorted user history = %#v, want [user: again, user: hi]", secondHistory[1:])
|
||||
|
||||
@@ -407,6 +407,33 @@ func TestWorkflowOutputs_WithAttachment(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkflowOutputsFromTerminalUsesMessageContent(t *testing.T) {
|
||||
output := map[string]any{
|
||||
"content": "****\nvisible answer\n++++",
|
||||
"downloads": []any{},
|
||||
}
|
||||
if got := workflowOutputsFromTerminal(output); got != "****\nvisible answer\n++++" {
|
||||
t.Fatalf("workflowOutputsFromTerminal = %#v, want complete Message content", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPartialAssistantOutputExcludesMessagePresentation(t *testing.T) {
|
||||
state := canvas.NewCanvasState("run-history", "session-history")
|
||||
appendAssistantHistory(state, partialAssistantOutput("model answer", nil, nil))
|
||||
|
||||
history := state.SnapshotHistory()
|
||||
if len(history) != 1 {
|
||||
t.Fatalf("history length = %d, want 1", len(history))
|
||||
}
|
||||
if history[0]["content"] != "model answer" {
|
||||
t.Fatalf("history content = %#v, want raw Agent answer", history[0]["content"])
|
||||
}
|
||||
payload, _ := history[0]["payload"].(map[string]any)
|
||||
if _, ok := payload["downloads"]; ok {
|
||||
t.Fatalf("history payload unexpectedly contains Message presentation fields: %#v", payload)
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetVersion_Success verifies getting a specific version by ID.
|
||||
func TestGetVersion_Success(t *testing.T) {
|
||||
testDB := setupServiceTestDB(t)
|
||||
|
||||
Reference in new issue
Block a user