// Modified in the independent AgentDesk fork: localized knowledge workflows and safe display errors. package builders import ( "agent-desk/internal/models" "agent-desk/internal/pkg/dto/response" "agent-desk/internal/pkg/i18nx" "encoding/json" "fmt" ) func BuildKnowledgeBase(item *models.KnowledgeBase, locales ...string) response.KnowledgeBaseResponse { return response.KnowledgeBaseResponse{ ID: item.ID, Name: item.Name, Description: item.Description, KnowledgeType: item.KnowledgeType, KnowledgeTypeName: knowledgeLabel(locales, "type", item.KnowledgeType), Status: item.Status, StatusName: knowledgeLabel(locales, "status", item.Status), DefaultTopK: item.DefaultTopK, DefaultScoreThreshold: item.DefaultScoreThreshold, DefaultRerankLimit: item.DefaultRerankLimit, ChunkProvider: item.ChunkProvider, ChunkTargetTokens: item.ChunkTargetTokens, ChunkMaxTokens: item.ChunkMaxTokens, ChunkOverlapTokens: item.ChunkOverlapTokens, AnswerMode: item.AnswerMode, AnswerModeName: knowledgeLabel(locales, "mode", item.AnswerMode), Remark: item.Remark, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, CreateUserName: item.CreateUserName, UpdateUserName: item.UpdateUserName, } } func BuildKnowledgeDocument(item *models.KnowledgeDocument, locales ...string) response.KnowledgeDocumentResponse { return response.KnowledgeDocumentResponse{ ID: item.ID, KnowledgeBaseID: item.KnowledgeBaseID, DirectoryID: item.DirectoryID, Title: item.Title, Status: item.Status, StatusName: knowledgeLabel(locales, "status", item.Status), IndexStatus: item.IndexStatus, IndexStatusName: knowledgeLabel(locales, "index", item.IndexStatus), IndexedAt: item.IndexedAt, IndexError: knowledgeIndexError(locales, item.IndexError), ContentHash: item.ContentHash, ContentType: item.ContentType, Content: item.Content, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, CreateUserName: item.CreateUserName, UpdateUserName: item.UpdateUserName, } } func BuildKnowledgeDocumentList(item *models.KnowledgeDocument, locales ...string) response.KnowledgeDocumentListResponse { return response.KnowledgeDocumentListResponse{ ID: item.ID, KnowledgeBaseID: item.KnowledgeBaseID, DirectoryID: item.DirectoryID, Title: item.Title, Status: item.Status, StatusName: knowledgeLabel(locales, "status", item.Status), IndexStatus: item.IndexStatus, IndexStatusName: knowledgeLabel(locales, "index", item.IndexStatus), IndexedAt: item.IndexedAt, IndexError: knowledgeIndexError(locales, item.IndexError), ContentHash: item.ContentHash, ContentType: item.ContentType, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, CreateUserName: item.CreateUserName, UpdateUserName: item.UpdateUserName, } } func BuildKnowledgeFAQ(item *models.KnowledgeFAQ, locales ...string) response.KnowledgeFAQResponse { return response.KnowledgeFAQResponse{ ID: item.ID, KnowledgeBaseID: item.KnowledgeBaseID, DirectoryID: item.DirectoryID, Question: item.Question, Answer: item.Answer, SimilarQuestions: parseSimilarQuestions(item.SimilarQuestions), Status: item.Status, StatusName: knowledgeLabel(locales, "status", item.Status), IndexStatus: item.IndexStatus, IndexStatusName: knowledgeLabel(locales, "index", item.IndexStatus), IndexedAt: item.IndexedAt, IndexError: knowledgeIndexError(locales, item.IndexError), Remark: item.Remark, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, CreateUserName: item.CreateUserName, UpdateUserName: item.UpdateUserName, } } func BuildKnowledgeDirectory(item *models.KnowledgeDirectory, locales ...string) response.KnowledgeDirectoryResponse { return response.KnowledgeDirectoryResponse{ ID: item.ID, KnowledgeBaseID: item.KnowledgeBaseID, ParentID: item.ParentID, Name: item.Name, SortNo: item.SortNo, Status: item.Status, StatusName: knowledgeLabel(locales, "status", item.Status), Remark: item.Remark, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, CreateUserName: item.CreateUserName, UpdateUserName: item.UpdateUserName, Children: []response.KnowledgeDirectoryResponse{}, } } func BuildKnowledgeRetrieveLog(item *models.KnowledgeRetrieveLog, locales ...string) response.KnowledgeRetrieveLogResponse { return response.KnowledgeRetrieveLogResponse{ ID: item.ID, KnowledgeBaseID: item.KnowledgeBaseID, Channel: item.Channel, ChannelName: knowledgeLabel(locales, "channel", item.Channel), Scene: item.Scene, SceneName: knowledgeLabel(locales, "scene", item.Scene), SessionID: item.SessionID, ConversationID: item.ConversationID, RequestID: item.RequestID, Question: item.Question, RewriteQuestion: item.RewriteQuestion, Answer: item.Answer, AnswerStatus: item.AnswerStatus, AnswerStatusName: knowledgeLabel(locales, "answer", item.AnswerStatus), HitCount: item.HitCount, TopScore: item.TopScore, ChunkProvider: item.ChunkProvider, ChunkTargetTokens: item.ChunkTargetTokens, ChunkMaxTokens: item.ChunkMaxTokens, ChunkOverlapTokens: item.ChunkOverlapTokens, RerankEnabled: item.RerankEnabled, RerankLimit: item.RerankLimit, CitationCount: item.CitationCount, UsedChunkCount: item.UsedChunkCount, LatencyMs: item.LatencyMs, RetrieveMs: item.RetrieveMs, GenerateMs: item.GenerateMs, PromptTokens: item.PromptTokens, CompletionTokens: item.CompletionTokens, ModelName: item.ModelName, TraceData: item.TraceData, CreatedAt: item.CreatedAt, } } func BuildKnowledgeRetrieveHitResponse(item *models.KnowledgeRetrieveHit, locales ...string) response.KnowledgeRetrieveHitResponse { return response.KnowledgeRetrieveHitResponse{ ID: item.ID, RetrieveLogID: item.RetrieveLogID, KnowledgeBaseID: item.KnowledgeBaseID, ChunkID: item.ChunkID, DocumentID: item.DocumentID, DocumentTitle: item.DocumentTitle, FaqID: item.FaqID, FaqQuestion: item.FaqQuestion, ChunkNo: item.ChunkNo, Title: item.Title, SectionPath: item.SectionPath, ChunkType: item.ChunkType, ChunkTypeName: knowledgeLabel(locales, "chunk", item.ChunkType), Provider: item.Provider, RankNo: item.RankNo, Score: item.Score, RerankScore: item.RerankScore, UsedInAnswer: item.UsedInAnswer, IsCitation: item.IsCitation, Snippet: item.Snippet, CreatedAt: item.CreatedAt, } } func parseSimilarQuestions(raw string) []string { if raw == "" { return []string{} } var items []string if err := json.Unmarshal([]byte(raw), &items); err != nil { return []string{} } return items } var knowledgeLabelCodes = map[string]map[string]bool{ "type": {"document": true, "faq": true}, "status": {"0": true, "1": true, "2": true}, "index": {"pending": true, "indexed": true, "failed": true}, "mode": {"1": true, "2": true}, "channel": {"im": true, "agent_assist": true, "api": true, "debug": true}, "scene": {"first_response": true, "assist": true, "qa": true}, "answer": {"1": true, "2": true, "3": true, "4": true}, "chunk": {"text": true, "faq": true, "table": true, "code": true}, } // Labels are application-owned; titles, content, snippets and historical answers are not. func knowledgeLabel(locales []string, group string, value any) string { code := fmt.Sprint(value) key := "knowledge.labels.unknown" if knowledgeLabelCodes[group][code] { key = "knowledge.labels." + group + "." + code } return i18nx.Getf(knowledgeLocale(locales), key) } func knowledgeLocale(locales []string) string { if len(locales) > 0 { return i18nx.NormalizeLocale(locales[0]) } return i18nx.DefaultLocale } // Legacy index_error values can contain SQL, credentials or provider response bodies. // Keep those values out of the public DTO; this does not rewrite persisted diagnostics. func knowledgeIndexError(locales []string, stored string) string { if stored == "" { return "" } return i18nx.Getf(knowledgeLocale(locales), "error.knowledge.indexFailed") }