srilakshu012456 commited on
Commit
7c52deb
·
verified ·
1 Parent(s): 7a7e13a

Update services/kb_creation.py

Browse files
Files changed (1) hide show
  1. services/kb_creation.py +16 -21
services/kb_creation.py CHANGED
@@ -93,7 +93,6 @@ ERROR_TERMS = ["error", "issue", "fail", "failure", "not working", "cannot", "ca
93
 
94
  STEP_VERBS = ["navigate", "select", "scan", "verify", "confirm", "print", "move", "complete", "click", "open", "choose", "enter", "update", "save", "delete", "create", "attach", "assign"]
95
 
96
- # Module vocabulary → canonical tags
97
  MODULE_VOCAB = {
98
  "picking": ["pick", "picking", "pick release", "wave", "allocation"],
99
  "receiving": ["receive", "receiving", "inbound", "asn", "appointment"],
@@ -116,17 +115,14 @@ def _infer_intent_tag(section_title: str) -> str:
116
  return "neutral"
117
 
118
  def _derive_semantic_intent_from_text(text: str) -> Tuple[str, List[str]]:
119
- """Return ('errors'|'steps'|'neutral', topic_tags) by scanning the text."""
120
  t = (text or "").lower()
121
  tags: List[str] = []
122
  intent = "neutral"
123
  if any(term in t for term in PERMISSION_TERMS):
124
  intent = "errors"
125
  tags.append("permissions")
126
- if "role" in t:
127
- tags.append("role_access")
128
- if "security" in t:
129
- tags.append("security")
130
  if intent == "neutral" and any(term in t for term in ERROR_TERMS):
131
  intent = "errors"
132
  tags.append("errors")
@@ -141,7 +137,6 @@ def _derive_module_tags(text: str, filename: str, section_title: str) -> List[st
141
  for mod, syns in MODULE_VOCAB.items():
142
  if any(s in tokens for s in syns):
143
  found.append(mod)
144
- # default: if none found, try broad guess
145
  if not found:
146
  if "inventory" in tokens or "adjust" in tokens or "uom" in tokens or "cycle" in tokens:
147
  found = ["inventory"]
@@ -175,7 +170,6 @@ def ingest_documents(folder_path: str) -> None:
175
  final_intent = "errors"
176
  elif base_intent == "neutral" and derived_intent in ("steps", "prereqs"):
177
  final_intent = derived_intent
178
-
179
  module_tags = _derive_module_tags(chunk, file, section_title)
180
 
181
  embedding = model.encode(chunk).tolist()
@@ -186,13 +180,13 @@ def ingest_documents(folder_path: str) -> None:
186
  "chunk_index": c_idx,
187
  "title": doc_title,
188
  "collection": "SOP",
189
- "intent_tag": final_intent,
190
- "topic_tags": topic_tags,
191
- "module_tags": module_tags,
192
  }
193
  try:
194
  collection.add(ids=[doc_id], embeddings=[embedding], documents=[chunk], metadatas=[meta])
195
- except Exception:
196
  try:
197
  collection.delete(ids=[doc_id])
198
  collection.add(ids=[doc_id], embeddings=[embedding], documents=[chunk], metadatas=[meta])
@@ -374,7 +368,6 @@ def _extract_modules_from_query(query: str) -> List[str]:
374
  for mod, syns in MODULE_VOCAB.items():
375
  if any(s in q for s in syns):
376
  found.append(mod)
377
- # broad guess if user says 'inventory'
378
  if not found and ("inventory" in q or "adjust" in q):
379
  found = ["inventory"]
380
  return list(sorted(set(found)))
@@ -388,15 +381,17 @@ def _intent_weight(meta: dict, user_intent: str) -> float:
388
  if tag in ["purpose", "prereqs"] and user_intent in ["steps", "errors"]:
389
  return -0.6
390
  st = (meta or {}).get("section", "").lower()
391
- topics = (meta or {}).get("topic_tags", []) or []
392
- if user_intent == "errors" and (any(k in st for k in ["escalation", "permissions", "access", "known issues"]) or ("permissions" in topics)):
 
393
  return 0.7
394
  return -0.2
395
 
396
  def _module_weight(meta: Dict[str, Any], user_modules: List[str]) -> float:
397
  if not user_modules:
398
  return 0.0
399
- doc_modules = (meta or {}).get("module_tags", []) or []
 
400
  overlap = len(set(user_modules) & set(doc_modules))
401
  if overlap == 0:
402
  return -0.4 # demote different modules to avoid wrong SOP
@@ -406,8 +401,8 @@ def _meta_overlap(meta: Dict[str, Any], q_terms: List[str]) -> float:
406
  fn_tokens = _tokenize_meta_value(meta.get("filename"))
407
  title_tokens = _tokenize_meta_value(meta.get("title"))
408
  section_tokens = _tokenize_meta_value(meta.get("section"))
409
- topic_tokens = _tokenize_meta_value(' '.join((meta.get("topic_tags") or [])))
410
- module_tokens = _tokenize_meta_value(' '.join((meta.get("module_tags") or [])))
411
  meta_tokens = set(fn_tokens + title_tokens + section_tokens + topic_tokens + module_tokens)
412
  if not meta_tokens or not q_terms:
413
  return 0.0
@@ -570,19 +565,19 @@ def get_best_steps_section_text(filename: str) -> str:
570
  return "\n\n".join(texts).strip()
571
 
572
  def get_best_errors_section_text(filename: str) -> str:
573
- """Return combined text of all error/permission/escalation chunks for the given SOP."""
574
  texts: List[str] = []
575
  for d in bm25_docs:
576
  m = d.get("meta", {})
577
  sec = (m.get("section") or "").lower()
578
- topics = (m.get("topic_tags") or [])
 
579
  if m.get("filename") == filename and (
580
  m.get("intent_tag") == "errors"
581
  or "error" in sec
582
  or "escalation" in sec
583
  or "permission" in sec
584
  or "access" in sec
585
- or ("permissions" in topics)
586
  ):
587
  t = (d.get("text") or "").strip()
588
  if t:
 
93
 
94
  STEP_VERBS = ["navigate", "select", "scan", "verify", "confirm", "print", "move", "complete", "click", "open", "choose", "enter", "update", "save", "delete", "create", "attach", "assign"]
95
 
 
96
  MODULE_VOCAB = {
97
  "picking": ["pick", "picking", "pick release", "wave", "allocation"],
98
  "receiving": ["receive", "receiving", "inbound", "asn", "appointment"],
 
115
  return "neutral"
116
 
117
  def _derive_semantic_intent_from_text(text: str) -> Tuple[str, List[str]]:
 
118
  t = (text or "").lower()
119
  tags: List[str] = []
120
  intent = "neutral"
121
  if any(term in t for term in PERMISSION_TERMS):
122
  intent = "errors"
123
  tags.append("permissions")
124
+ if "role" in t: tags.append("role_access")
125
+ if "security" in t: tags.append("security")
 
 
126
  if intent == "neutral" and any(term in t for term in ERROR_TERMS):
127
  intent = "errors"
128
  tags.append("errors")
 
137
  for mod, syns in MODULE_VOCAB.items():
138
  if any(s in tokens for s in syns):
139
  found.append(mod)
 
140
  if not found:
141
  if "inventory" in tokens or "adjust" in tokens or "uom" in tokens or "cycle" in tokens:
142
  found = ["inventory"]
 
170
  final_intent = "errors"
171
  elif base_intent == "neutral" and derived_intent in ("steps", "prereqs"):
172
  final_intent = derived_intent
 
173
  module_tags = _derive_module_tags(chunk, file, section_title)
174
 
175
  embedding = model.encode(chunk).tolist()
 
180
  "chunk_index": c_idx,
181
  "title": doc_title,
182
  "collection": "SOP",
183
+ "intent_tag": final_intent, # str
184
+ "topic_tags": ", ".join(topic_tags) if topic_tags else "", # str (NOT list)
185
+ "module_tags": ", ".join(module_tags) if module_tags else "", # str (NOT list)
186
  }
187
  try:
188
  collection.add(ids=[doc_id], embeddings=[embedding], documents=[chunk], metadatas=[meta])
189
+ except Exception as e1:
190
  try:
191
  collection.delete(ids=[doc_id])
192
  collection.add(ids=[doc_id], embeddings=[embedding], documents=[chunk], metadatas=[meta])
 
368
  for mod, syns in MODULE_VOCAB.items():
369
  if any(s in q for s in syns):
370
  found.append(mod)
 
371
  if not found and ("inventory" in q or "adjust" in q):
372
  found = ["inventory"]
373
  return list(sorted(set(found)))
 
381
  if tag in ["purpose", "prereqs"] and user_intent in ["steps", "errors"]:
382
  return -0.6
383
  st = (meta or {}).get("section", "").lower()
384
+ topics = (meta or {}).get("topic_tags", "") or ""
385
+ topic_list = [t.strip() for t in topics.split(",") if t.strip()]
386
+ if user_intent == "errors" and (any(k in st for k in ["escalation", "permissions", "access", "known issues"]) or ("permissions" in topic_list)):
387
  return 0.7
388
  return -0.2
389
 
390
  def _module_weight(meta: Dict[str, Any], user_modules: List[str]) -> float:
391
  if not user_modules:
392
  return 0.0
393
+ raw = (meta or {}).get("module_tags", "") or ""
394
+ doc_modules = [m.strip() for m in raw.split(",") if m.strip()] if isinstance(raw, str) else (raw or [])
395
  overlap = len(set(user_modules) & set(doc_modules))
396
  if overlap == 0:
397
  return -0.4 # demote different modules to avoid wrong SOP
 
401
  fn_tokens = _tokenize_meta_value(meta.get("filename"))
402
  title_tokens = _tokenize_meta_value(meta.get("title"))
403
  section_tokens = _tokenize_meta_value(meta.get("section"))
404
+ topic_tokens = _tokenize_meta_value((meta.get("topic_tags") or ""))
405
+ module_tokens = _tokenize_meta_value((meta.get("module_tags") or ""))
406
  meta_tokens = set(fn_tokens + title_tokens + section_tokens + topic_tokens + module_tokens)
407
  if not meta_tokens or not q_terms:
408
  return 0.0
 
565
  return "\n\n".join(texts).strip()
566
 
567
  def get_best_errors_section_text(filename: str) -> str:
 
568
  texts: List[str] = []
569
  for d in bm25_docs:
570
  m = d.get("meta", {})
571
  sec = (m.get("section") or "").lower()
572
+ topics = (m.get("topic_tags") or "")
573
+ topic_list = [t.strip() for t in topics.split(",") if t.strip()]
574
  if m.get("filename") == filename and (
575
  m.get("intent_tag") == "errors"
576
  or "error" in sec
577
  or "escalation" in sec
578
  or "permission" in sec
579
  or "access" in sec
580
+ or ("permissions" in topic_list)
581
  ):
582
  t = (d.get("text") or "").strip()
583
  if t: