@@ -193,6 +193,7 @@ func (s *Service) Process(ctx context.Context, id int64) error {
|
||||
return err
|
||||
}
|
||||
if len(hits) > 0 {
|
||||
run.KnowledgeCandidates = auditKnowledgeCandidates(hits, s.cfg.KnowledgeMinScore, 5)
|
||||
run.KnowledgeTopID = hits[0].Doc.ID
|
||||
run.KnowledgeTopTitle = hits[0].Doc.Title
|
||||
run.KnowledgeScore = hits[0].Score
|
||||
@@ -218,6 +219,7 @@ func (s *Service) Process(ctx context.Context, id int64) error {
|
||||
run.ContextIssues = len(contextData.ServiceIssues)
|
||||
run.ContextDevices = len(contextData.UserDevices)
|
||||
run.ContextWarnings = append([]string(nil), contextData.Warnings...)
|
||||
run.ContextDetails = auditContextDetails(contextData, 5)
|
||||
if contextData.Incomplete {
|
||||
s.metrics.ContextErrors.Add(1)
|
||||
}
|
||||
@@ -367,6 +369,82 @@ func (s *Service) Process(ctx context.Context, id int64) error {
|
||||
finish(nil)
|
||||
return nil
|
||||
}
|
||||
func auditKnowledgeCandidates(hits []model.KnowledgeHit, globalMin float64, limit int) []model.KnowledgeCandidateAudit {
|
||||
if limit <= 0 || limit > len(hits) {
|
||||
limit = len(hits)
|
||||
}
|
||||
out := make([]model.KnowledgeCandidateAudit, 0, limit)
|
||||
for _, h := range hits[:limit] {
|
||||
required := globalMin
|
||||
if h.Doc.MinScore > required {
|
||||
required = h.Doc.MinScore
|
||||
}
|
||||
out = append(out, model.KnowledgeCandidateAudit{
|
||||
ID: h.Doc.ID, Title: h.Doc.Title, Source: h.Doc.Source, Score: h.Score,
|
||||
SemanticScore: h.SemanticScore, TitleScore: h.TitleScore, KeywordScore: h.KeywordScore,
|
||||
CategoryScore: h.CategoryScore, RequiredScore: required, AutoReply: h.Doc.AutoReply,
|
||||
BestChunkExcerpt: h.BestChunkExcerpt, BestQueryExcerpt: h.BestQueryExcerpt,
|
||||
QueryChunkCount: h.QueryChunkCount, DocumentChunkCount: h.DocumentChunkCount,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func auditContextDetails(c model.ContextSnapshot, limit int) []model.ContextAuditItem {
|
||||
if limit <= 0 {
|
||||
limit = 5
|
||||
}
|
||||
out := make([]model.ContextAuditItem, 0, limit*4)
|
||||
for i, x := range c.Changes {
|
||||
if i >= limit {
|
||||
break
|
||||
}
|
||||
out = append(out, model.ContextAuditItem{Kind: "change", ID: x.ID, Name: x.Name, Relevance: x.Relevance, Detail: strings.TrimSpace(x.PlannedBegin + " – " + x.PlannedEnd)})
|
||||
}
|
||||
for i, x := range c.MajorIncidents {
|
||||
if i >= limit {
|
||||
break
|
||||
}
|
||||
out = append(out, model.ContextAuditItem{Kind: "incident", ID: x.ID, Name: x.Name, Relevance: x.Relevance, Status: fmt.Sprint(x.StatusID), Detail: auditExcerpt(x.Content, 320)})
|
||||
}
|
||||
for i, x := range c.ServiceIssues {
|
||||
if i >= limit {
|
||||
break
|
||||
}
|
||||
name := x.MonitorName
|
||||
if name == "" {
|
||||
name = x.IncidentTitle
|
||||
}
|
||||
out = append(out, model.ContextAuditItem{Kind: "uptime", ID: x.MonitorID, Name: name, Relevance: x.Relevance, Status: x.Status, Detail: auditExcerpt(x.Message, 320)})
|
||||
}
|
||||
for i, x := range c.UserDevices {
|
||||
if i >= limit {
|
||||
break
|
||||
}
|
||||
name := x.Name
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("%s #%d", x.ItemType, x.ID)
|
||||
}
|
||||
parts := make([]string, 0, 3)
|
||||
for _, v := range []string{x.Serial, x.InventoryNumber, x.Location} {
|
||||
if strings.TrimSpace(v) != "" {
|
||||
parts = append(parts, strings.TrimSpace(v))
|
||||
}
|
||||
}
|
||||
detail := strings.Join(parts, " · ")
|
||||
out = append(out, model.ContextAuditItem{Kind: "device", ID: x.ID, Name: name, Status: x.Status, Detail: detail})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func auditExcerpt(v string, max int) string {
|
||||
v = strings.Join(strings.Fields(v), " ")
|
||||
if max <= 0 || len(v) <= max {
|
||||
return v
|
||||
}
|
||||
return strings.TrimSpace(v[:max]) + "…"
|
||||
}
|
||||
|
||||
func (s *Service) getCategories(ctx context.Context) ([]model.Category, error) {
|
||||
s.catMu.RLock()
|
||||
if len(s.categories) > 0 && time.Since(s.catAt) < 10*time.Minute {
|
||||
|
||||
Reference in New Issue
Block a user