mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-23 17:06:42 +08:00
Fix stale references shown while streaming and empty final reply in Go mode (#17146)
This commit is contained in:
@@ -849,7 +849,11 @@ func (s *ChatPipelineService) AsyncChat(
|
||||
// Two results are yielded (mirroring Python dialog_service.py):
|
||||
// 1. Final=false — carries the answer text so streaming consumers
|
||||
// actually display the fallback message.
|
||||
// 2. Final=true — closes the stream with the reference/prompt.
|
||||
// 2. Final=true — closes the stream with the same full answer plus
|
||||
// the reference/prompt. Python yields the full answer again in the
|
||||
// final event (dialog_service.py:807); consumers that only look at
|
||||
// the final event (e.g. the OpenAI-compatible endpoint) would
|
||||
// otherwise see an empty reply.
|
||||
if len(knowledges) == 0 {
|
||||
if emptyResp, ok := promptConfig["empty_response"].(string); ok && emptyResp != "" {
|
||||
out <- AsyncChatResult{
|
||||
@@ -857,7 +861,7 @@ func (s *ChatPipelineService) AsyncChat(
|
||||
Reference: map[string]interface{}{},
|
||||
}
|
||||
out <- AsyncChatResult{
|
||||
Answer: "",
|
||||
Answer: emptyResp,
|
||||
Reference: kbinfos,
|
||||
AudioBinary: s.synthesizeTTS(ttsModel, emptyResp),
|
||||
Prompt: fmt.Sprintf("\n\n### Query:\n%s", strings.Join(questions, " ")),
|
||||
|
||||
@@ -1311,7 +1311,12 @@ func (s *ChatSessionService) Completion(userID string, conversationID string, me
|
||||
var answer strings.Builder
|
||||
var finalRef map[string]interface{}
|
||||
for result := range resultChan {
|
||||
if result.Answer != "" {
|
||||
if result.Final && result.Answer != "" {
|
||||
// The final event carries the complete (decorated) answer;
|
||||
// it replaces any accumulated deltas rather than appending.
|
||||
answer.Reset()
|
||||
answer.WriteString(result.Answer)
|
||||
} else if result.Answer != "" {
|
||||
answer.WriteString(result.Answer)
|
||||
}
|
||||
if result.Reference != nil {
|
||||
@@ -1673,7 +1678,12 @@ func (s *ChatSessionService) ChatCompletions(
|
||||
var answer strings.Builder
|
||||
var finalRef map[string]interface{}
|
||||
for result := range resultChan {
|
||||
if result.Answer != "" {
|
||||
if result.Final && result.Answer != "" {
|
||||
// The final event carries the complete (decorated) answer;
|
||||
// it replaces any accumulated deltas rather than appending.
|
||||
answer.Reset()
|
||||
answer.WriteString(result.Answer)
|
||||
} else if result.Answer != "" {
|
||||
answer.WriteString(result.Answer)
|
||||
}
|
||||
if result.Reference != nil {
|
||||
|
||||
@@ -822,7 +822,9 @@ func TestCompletion_Success(t *testing.T) {
|
||||
pipeline := &fakePipeline{
|
||||
resultChan: makeResultChan(
|
||||
AsyncChatResult{Answer: "Hello", Reference: map[string]interface{}{"chunks": []interface{}{}}},
|
||||
AsyncChatResult{Answer: " world", Final: true, Reference: map[string]interface{}{"chunks": []interface{}{}}},
|
||||
// The real pipeline's final result carries the complete answer,
|
||||
// not a trailing delta.
|
||||
AsyncChatResult{Answer: "Hello world", Final: true, Reference: map[string]interface{}{"chunks": []interface{}{}}},
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,20 @@ export const buildMessageItemReference = (
|
||||
const referenceIndex = assistantMessages.findIndex(
|
||||
(x) => x.id === message.id,
|
||||
);
|
||||
// An assistant message that has not received any content yet is still
|
||||
// being generated. Never resolve its reference from the conversation
|
||||
// reference list — the indices only align with completed answers, so the
|
||||
// lookup would surface a stale reference from a previous turn (or from a
|
||||
// previously opened conversation) while the answer is streaming.
|
||||
const isPendingAnswer =
|
||||
message.role === MessageType.Assistant &&
|
||||
!message.content &&
|
||||
isEmpty(message?.reference);
|
||||
const reference = !isEmpty(message?.reference)
|
||||
? message?.reference
|
||||
: (conversation?.reference ?? [])[referenceIndex];
|
||||
: isPendingAnswer
|
||||
? undefined
|
||||
: (conversation?.reference ?? [])[referenceIndex];
|
||||
|
||||
return reference ?? { doc_aggs: [], chunks: [], total: 0 };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user