diff --git a/internal/service/ask_service.go b/internal/service/ask_service.go index 5e987d02c1..957a7d2f09 100644 --- a/internal/service/ask_service.go +++ b/internal/service/ask_service.go @@ -18,6 +18,7 @@ package service import ( "context" + "strings" "ragflow/internal/common" modelModule "ragflow/internal/entity/models" @@ -208,6 +209,11 @@ func (s *AskService) run(ctx context.Context, llm StreamingLLM, userID, question // Phase 4: Finalize — citation insertion + reference formatting. visible := ExtractVisibleAnswer(fullAnswer) + if strings.TrimSpace(visible) == "" { + common.Warn("AskService LLM stream completed without visible answer") + s.sendOrCancel(out, AskDelta{Kind: AskDeltaError, Value: "LLM call failed"}, ctx) + return + } chunkRefs := ChunksFormat(chunks) // Attempt citation insertion if embedder is available. diff --git a/internal/service/ask_service_test.go b/internal/service/ask_service_test.go index f6dbeb5ff1..9c7ce3eb19 100644 --- a/internal/service/ask_service_test.go +++ b/internal/service/ask_service_test.go @@ -114,6 +114,21 @@ func TestAskService_StreamingFlow(t *testing.T) { } } +func TestAskService_EmptyLLMStreamReturnsError(t *testing.T) { + ret := &fakeRetriever{result: &RetrievalTestResponse{ + Chunks: []map[string]interface{}{ + {"id": "c1", "content_with_weight": "test chunk", "docnm_kwd": "Doc", "kb_id": "kb1", "doc_id": "d1"}, + }, + }} + llm := &fakeStreamLLM{} + svc := NewAskService(ret, nil, 0, 0) + deltas := collect(svc.Stream(context.Background(), llm, "user1", "test", []string{"kb1"})) + + if len(deltas) != 1 || deltas[0].Kind != AskDeltaError || !strings.Contains(deltas[0].Value, "LLM call failed") { + t.Fatalf("expected LLM error delta, got %+v", deltas) + } +} + func TestAskService_ThinkTags(t *testing.T) { ret := &fakeRetriever{result: &RetrievalTestResponse{ Chunks: []map[string]interface{}{