WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
package chatpipeline
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/Tencent/WeKnora/internal/types"
|
||||
)
|
||||
|
||||
// populateFAQAnswers populates FAQ answers for the search results
|
||||
func (p *PluginMerge) populateFAQAnswers(
|
||||
ctx context.Context,
|
||||
chatManage *types.ChatManage,
|
||||
results []*types.SearchResult,
|
||||
) []*types.SearchResult {
|
||||
if len(results) == 0 || p.chunkRepo == nil {
|
||||
return results
|
||||
}
|
||||
|
||||
tenantID, _ := types.TenantIDFromContext(ctx)
|
||||
if tenantID == 0 && chatManage != nil {
|
||||
tenantID = chatManage.TenantID
|
||||
}
|
||||
if tenantID == 0 {
|
||||
pipelineWarn(ctx, "Merge", "faq_enrich_skip", map[string]interface{}{
|
||||
"reason": "missing_tenant",
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
||||
chunkResultMap := make(map[string][]*types.SearchResult)
|
||||
chunkIDSet := make(map[string]struct{})
|
||||
for _, r := range results {
|
||||
if r == nil || r.ID == "" {
|
||||
continue
|
||||
}
|
||||
if r.ChunkType != string(types.ChunkTypeFAQ) {
|
||||
continue
|
||||
}
|
||||
chunkResultMap[r.ID] = append(chunkResultMap[r.ID], r)
|
||||
if _, exists := chunkIDSet[r.ID]; !exists {
|
||||
chunkIDSet[r.ID] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(chunkIDSet) == 0 {
|
||||
return results
|
||||
}
|
||||
|
||||
chunkIDs := make([]string, 0, len(chunkIDSet))
|
||||
for id := range chunkIDSet {
|
||||
chunkIDs = append(chunkIDs, id)
|
||||
}
|
||||
|
||||
chunks, err := p.chunkRepo.ListChunksByID(ctx, tenantID, chunkIDs)
|
||||
if err != nil {
|
||||
pipelineWarn(ctx, "Merge", "faq_chunk_fetch_failed", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
||||
updated := 0
|
||||
for _, chunk := range chunks {
|
||||
if chunk == nil {
|
||||
continue
|
||||
}
|
||||
meta, err := chunk.FAQMetadata()
|
||||
if err != nil || meta == nil {
|
||||
if err != nil {
|
||||
pipelineWarn(ctx, "Merge", "faq_metadata_parse_failed", map[string]interface{}{
|
||||
"chunk_id": chunk.ID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
continue
|
||||
}
|
||||
content := buildFAQAnswerContent(meta)
|
||||
if content == "" {
|
||||
continue
|
||||
}
|
||||
for _, r := range chunkResultMap[chunk.ID] {
|
||||
if r == nil {
|
||||
continue
|
||||
}
|
||||
r.Content = content
|
||||
updated++
|
||||
}
|
||||
}
|
||||
|
||||
if updated > 0 {
|
||||
pipelineInfo(ctx, "Merge", "faq_content_enriched", map[string]interface{}{
|
||||
"chunk_cnt": updated,
|
||||
})
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// buildFAQAnswerContent builds the content of a FAQ answer
|
||||
func buildFAQAnswerContent(meta *types.FAQChunkMetadata) string {
|
||||
if meta == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
question := strings.TrimSpace(meta.StandardQuestion)
|
||||
answers := make([]string, 0, len(meta.Answers))
|
||||
for _, ans := range meta.Answers {
|
||||
if trimmed := strings.TrimSpace(ans); trimmed != "" {
|
||||
answers = append(answers, trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
if question == "" && len(answers) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var builder strings.Builder
|
||||
if question != "" {
|
||||
builder.WriteString("Q: ")
|
||||
builder.WriteString(question)
|
||||
builder.WriteString("\n")
|
||||
}
|
||||
|
||||
if len(answers) > 0 {
|
||||
builder.WriteString("Answer:\n")
|
||||
for _, ans := range answers {
|
||||
builder.WriteString("- ")
|
||||
builder.WriteString(ans)
|
||||
builder.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimSpace(builder.String())
|
||||
}
|
||||
Reference in New Issue
Block a user