Peter Mutwiri commited on
Commit
fbaed84
Β·
1 Parent(s): fdaa96f

ai service refactor

Browse files
Files changed (1) hide show
  1. app/service/ai_service.py +86 -86
app/service/ai_service.py CHANGED
@@ -1,108 +1,108 @@
1
- # app/service/ai_service.py
2
- import json
3
- import logging
4
- from app.deps import get_vector_db
5
- from app.service.llm_service import LocalLLMService
6
- from app.service.embedding_service import embedder
7
- import time
8
 
9
- logger = logging.getLogger(__name__)
10
 
11
- class AIService:
12
- def __init__(self):
13
- try:
14
- self.vector_db = get_vector_db()
15
- self.vss_available = True
16
- logger.info("βœ… Vector DB initialized")
17
- except Exception as e:
18
- logger.warning(f"⚠️ Vector DB unavailable: {e}")
19
- self.vector_db = None
20
- self.vss_available = False
21
 
22
- self.llm = llm_service
23
- self.embedder = embedder
24
- logger.info(f"βœ… AI Service initialized (VSS: {'ENABLED' if self.vss_available else 'DISABLED'})")
25
 
26
- def detect_entity_type(self, org_id: str, columns: list[str], filename: str) -> dict:
27
- """Detect entity type with JSON validation and timeout"""
28
- columns_str = ",".join(columns)
29
 
30
- # Check cache
31
- if self.vss_available:
32
- cached = self.vector_db.execute("""
33
- SELECT entity_type FROM vector_store.embeddings
34
- WHERE org_id = ? AND content = ?
35
- ORDER BY created_at DESC LIMIT 1
36
- """, [org_id, columns_str]).fetchone()
37
 
38
- if cached:
39
- logger.info(f"[ai_service] Cache hit: {cached[0]}")
40
- return {"entity_type": cached[0], "confidence": 0.99, "cached": True}
41
 
42
- # βœ… SIMPLE, CLEAR prompt for Phi-3
43
- prompt = f"""You are a data classification assistant.
44
 
45
- You MUST respond with ONLY valid JSON in this exact format:
46
- {{"entity_type":"sales|inventory|customer|product","confidence":0.95}}
47
 
48
- Dataset info:
49
- - Filename: {filename}
50
- - Columns: {columns_str}
51
 
52
- Analyze and respond with ONLY JSON:"""
53
 
54
- logger.info(f"[ai_service] Calling LLM for {org_id}...")
55
 
56
- try:
57
- # βœ… TIMEOUT WRAPPER (5 seconds max)
58
- start_time = time.time()
59
- response_text = self.llm.generate(prompt, max_tokens=50, temperature=0.1)
60
- elapsed = time.time() - start_time
61
 
62
- logger.info(f"[ai_service] LLM responded in {elapsed:.2f}s: {response_text}")
63
 
64
- # βœ… AGGRESSIVE JSON cleaning
65
- response_text = response_text.strip()
66
- if "```json" in response_text:
67
- response_text = response_text.split("```json")[1].split("```")[0].strip()
68
- elif "```" in response_text:
69
- response_text = response_text.split("```")[1].split("```")[0].strip()
70
 
71
- # βœ… Remove any stray text before/after JSON
72
- if "{" in response_text and "}" in response_text:
73
- response_text = response_text[response_text.find("{"):response_text.rfind("}")+1]
74
 
75
- logger.info(f"[ai_service] Cleaned response: {response_text}")
76
 
77
- # βœ… PARSE with error handling
78
- result = json.loads(response_text)
79
 
80
- # βœ… Normalize
81
- result["entity_type"] = result["entity_type"].upper()
82
- result["confidence"] = float(result["confidence"])
83
 
84
- # βœ… Cache it
85
- if self.vss_available:
86
- try:
87
- embedding = self.embedder.generate(columns_str)
88
- self.vector_db.execute("""
89
- INSERT INTO vector_store.embeddings (org_id, content, embedding, entity_type)
90
- VALUES (?, ?, ?, ?)
91
- """, [org_id, columns_str, embedding, result["entity_type"]])
92
- logger.info(f"[ai_service] Cached for {org_id}")
93
- except Exception as e:
94
- logger.warning(f"[ai_service] Cache insert failed: {e}")
95
 
96
- return result
97
 
98
- except Exception as e:
99
- logger.error(f"[ai_service] ❌ Detection failed: {e}", exc_info=True)
100
- # βœ… SAFE FALLBACK (never crash)
101
- return {
102
- "entity_type": "SALES",
103
- "confidence": 0.50,
104
- "error": str(e),
105
- "fallback": True
106
- }
107
 
108
- ai_service = AIService()
 
1
+ # # app/service/ai_service.py
2
+ # import json
3
+ # import logging
4
+ # from app.deps import get_vector_db
5
+ # from app.service.llm_service import LocalLLMService
6
+ # from app.service.embedding_service import embedder
7
+ # import time
8
 
9
+ # logger = logging.getLogger(__name__)
10
 
11
+ # class AIService:
12
+ # def __init__(self):
13
+ # try:
14
+ # self.vector_db = get_vector_db()
15
+ # self.vss_available = True
16
+ # logger.info("βœ… Vector DB initialized")
17
+ # except Exception as e:
18
+ # logger.warning(f"⚠️ Vector DB unavailable: {e}")
19
+ # self.vector_db = None
20
+ # self.vss_available = False
21
 
22
+ # self.llm = llm_service
23
+ # self.embedder = embedder
24
+ # logger.info(f"βœ… AI Service initialized (VSS: {'ENABLED' if self.vss_available else 'DISABLED'})")
25
 
26
+ # def detect_entity_type(self, org_id: str, columns: list[str], filename: str) -> dict:
27
+ # """Detect entity type with JSON validation and timeout"""
28
+ # columns_str = ",".join(columns)
29
 
30
+ # # Check cache
31
+ # if self.vss_available:
32
+ # cached = self.vector_db.execute("""
33
+ # SELECT entity_type FROM vector_store.embeddings
34
+ # WHERE org_id = ? AND content = ?
35
+ # ORDER BY created_at DESC LIMIT 1
36
+ # """, [org_id, columns_str]).fetchone()
37
 
38
+ # if cached:
39
+ # logger.info(f"[ai_service] Cache hit: {cached[0]}")
40
+ # return {"entity_type": cached[0], "confidence": 0.99, "cached": True}
41
 
42
+ # # βœ… SIMPLE, CLEAR prompt for Phi-3
43
+ # prompt = f"""You are a data classification assistant.
44
 
45
+ # You MUST respond with ONLY valid JSON in this exact format:
46
+ # {{"entity_type":"sales|inventory|customer|product","confidence":0.95}}
47
 
48
+ # Dataset info:
49
+ # - Filename: {filename}
50
+ # - Columns: {columns_str}
51
 
52
+ # Analyze and respond with ONLY JSON:"""
53
 
54
+ # logger.info(f"[ai_service] Calling LLM for {org_id}...")
55
 
56
+ # try:
57
+ # # βœ… TIMEOUT WRAPPER (5 seconds max)
58
+ # start_time = time.time()
59
+ # response_text = self.llm.generate(prompt, max_tokens=50, temperature=0.1)
60
+ # elapsed = time.time() - start_time
61
 
62
+ # logger.info(f"[ai_service] LLM responded in {elapsed:.2f}s: {response_text}")
63
 
64
+ # # βœ… AGGRESSIVE JSON cleaning
65
+ # response_text = response_text.strip()
66
+ # if "```json" in response_text:
67
+ # response_text = response_text.split("```json")[1].split("```")[0].strip()
68
+ # elif "```" in response_text:
69
+ # response_text = response_text.split("```")[1].split("```")[0].strip()
70
 
71
+ # # βœ… Remove any stray text before/after JSON
72
+ # if "{" in response_text and "}" in response_text:
73
+ # response_text = response_text[response_text.find("{"):response_text.rfind("}")+1]
74
 
75
+ # logger.info(f"[ai_service] Cleaned response: {response_text}")
76
 
77
+ # # βœ… PARSE with error handling
78
+ # result = json.loads(response_text)
79
 
80
+ # # βœ… Normalize
81
+ # result["entity_type"] = result["entity_type"].upper()
82
+ # result["confidence"] = float(result["confidence"])
83
 
84
+ # # βœ… Cache it
85
+ # if self.vss_available:
86
+ # try:
87
+ # embedding = self.embedder.generate(columns_str)
88
+ # self.vector_db.execute("""
89
+ # INSERT INTO vector_store.embeddings (org_id, content, embedding, entity_type)
90
+ # VALUES (?, ?, ?, ?)
91
+ # """, [org_id, columns_str, embedding, result["entity_type"]])
92
+ # logger.info(f"[ai_service] Cached for {org_id}")
93
+ # except Exception as e:
94
+ # logger.warning(f"[ai_service] Cache insert failed: {e}")
95
 
96
+ # return result
97
 
98
+ # except Exception as e:
99
+ # logger.error(f"[ai_service] ❌ Detection failed: {e}", exc_info=True)
100
+ # # βœ… SAFE FALLBACK (never crash)
101
+ # return {
102
+ # "entity_type": "SALES",
103
+ # "confidence": 0.50,
104
+ # "error": str(e),
105
+ # "fallback": True
106
+ # }
107
 
108
+ # ai_service = AIService()