ciyidogan commited on
Commit
a63397b
·
verified ·
1 Parent(s): 6d908f0

Update chat_handler.py

Browse files
Files changed (1) hide show
  1. chat_handler.py +27 -17
chat_handler.py CHANGED
@@ -1,25 +1,39 @@
1
  """
2
- Flare – Chat Handler (Spark /generate + safe-intent)
3
- ====================================================
4
  • X-Session-ID header
5
- Spark payload: {project_name, user_input, context, system_prompt}
6
- • Eğer model #DETECTED_INTENT:<label> döndürür ve <label> izinli liste
7
- dışında ise, mesaj small-talk olarak kabul edilir.
8
  """
9
 
10
- import re, json, uuid, httpx, commentjson
11
  from datetime import datetime
12
  from typing import Dict, List, Optional
13
 
14
  from fastapi import APIRouter, HTTPException, Header
15
  from pydantic import BaseModel
 
16
 
17
  from prompt_builder import build_intent_prompt, build_parameter_prompt, log
18
 
19
  # --------------------------------------------------------------------------- #
20
- # CONFIG
21
  # --------------------------------------------------------------------------- #
22
- CFG = commentjson.load(open("service_config.jsonc", encoding="utf-8"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  PROJECTS = {p["name"]: p for p in CFG["projects"]}
24
  APIS = {a["name"]: a for a in CFG["apis"]}
25
  SPARK_URL = CFG["config"]["spark_endpoint"].rstrip("/") + "/generate"
@@ -32,7 +46,7 @@ class Session:
32
  def __init__(self, project_name: str):
33
  self.id = str(uuid.uuid4())
34
  self.project = PROJECTS[project_name]
35
- self.history: List[Dict[str, str]] = [] # {"role","content"}
36
  self.variables: Dict[str, str] = {}
37
  self.awaiting: Optional[Dict] = None
38
  log(f"🆕 Session {self.id} for {project_name}")
@@ -99,25 +113,22 @@ async def chat(body: ChatBody,
99
  user_msg = body.user_input.strip()
100
  s.history.append({"role": "user", "content": user_msg})
101
 
102
- # ---------------- Follow-up? ----------------
103
  if s.awaiting:
104
  answer = await _followup(s, user_msg)
105
  s.history.append({"role": "assistant", "content": answer})
106
  return ChatResponse(session_id=s.id, answer=answer)
107
 
108
- # ---------------- Intent detection ----------------
109
  gen_prompt = s.project["versions"][0]["general_prompt"]
110
  intent_raw = await spark_generate(s, gen_prompt, user_msg)
111
 
112
- # --- Etiket yoksa → small talk cevabı olduğu gibi döndür
113
  if not intent_raw.startswith("#DETECTED_INTENT:"):
114
  s.history.append({"role": "assistant", "content": intent_raw})
115
  return ChatResponse(session_id=s.id, answer=intent_raw)
116
 
117
- # --- Etiket var → ayrıştır
118
  intent_name = intent_raw.split(":", 1)[1].strip()
119
  if intent_name not in ALLOWED_INTENTS:
120
- # Etiket geçersiz → small talk olarak ilk kısmı döndür
121
  clean = intent_raw.split("#DETECTED_INTENT")[0].split("\nassistant")[0].strip()
122
  s.history.append({"role": "assistant", "content": clean})
123
  return ChatResponse(session_id=s.id, answer=clean)
@@ -145,7 +156,6 @@ def _missing(s, intent_cfg):
145
 
146
  async def _handle_intent(s, intent_cfg, user_msg):
147
  missing = _missing(s, intent_cfg)
148
-
149
  if missing:
150
  p_prompt = build_parameter_prompt(intent_cfg, missing, user_msg, s.history)
151
  p_raw = await spark_generate(s, p_prompt, user_msg)
@@ -166,8 +176,8 @@ async def _handle_intent(s, intent_cfg, user_msg):
166
  async def _followup(s, user_msg):
167
  intent_cfg = s.awaiting["intent"]
168
  missing = s.awaiting["missing"]
169
- p_prompt = build_parameter_prompt(intent_cfg, missing, user_msg, s.history)
170
- p_raw = await spark_generate(s, p_prompt, user_msg)
171
  if not p_raw.startswith("#PARAMETERS:"):
172
  return "Üzgünüm, anlayamadım."
173
  if bad := _process_params(s, intent_cfg, p_raw):
 
1
  """
2
+ Flare – Chat Handler (Spark /generate + safe-intent + config-validate)
3
+ ======================================================================
4
  • X-Session-ID header
5
+ Config JSONC parse hatası -> log + graceful exit
 
 
6
  """
7
 
8
+ import re, json, uuid, sys, httpx, commentjson
9
  from datetime import datetime
10
  from typing import Dict, List, Optional
11
 
12
  from fastapi import APIRouter, HTTPException, Header
13
  from pydantic import BaseModel
14
+ from commentjson import JSONLibraryException
15
 
16
  from prompt_builder import build_intent_prompt, build_parameter_prompt, log
17
 
18
  # --------------------------------------------------------------------------- #
19
+ # CONFIG LOADING + VALIDATION
20
  # --------------------------------------------------------------------------- #
21
+ def load_config(path: str = "service_config.jsonc") -> dict:
22
+ try:
23
+ with open(path, encoding="utf-8") as f:
24
+ cfg = commentjson.load(f)
25
+ log("✅ service_config.jsonc parsed successfully.")
26
+ return cfg
27
+ except JSONLibraryException as e:
28
+ log("❌ CONFIG PARSE ERROR:")
29
+ log(str(e))
30
+ sys.exit(1)
31
+ except FileNotFoundError:
32
+ log(f"❌ Config file '{path}' not found.")
33
+ sys.exit(1)
34
+
35
+ CFG = load_config()
36
+
37
  PROJECTS = {p["name"]: p for p in CFG["projects"]}
38
  APIS = {a["name"]: a for a in CFG["apis"]}
39
  SPARK_URL = CFG["config"]["spark_endpoint"].rstrip("/") + "/generate"
 
46
  def __init__(self, project_name: str):
47
  self.id = str(uuid.uuid4())
48
  self.project = PROJECTS[project_name]
49
+ self.history: List[Dict[str, str]] = []
50
  self.variables: Dict[str, str] = {}
51
  self.awaiting: Optional[Dict] = None
52
  log(f"🆕 Session {self.id} for {project_name}")
 
113
  user_msg = body.user_input.strip()
114
  s.history.append({"role": "user", "content": user_msg})
115
 
116
+ # ---------------- Follow-up?
117
  if s.awaiting:
118
  answer = await _followup(s, user_msg)
119
  s.history.append({"role": "assistant", "content": answer})
120
  return ChatResponse(session_id=s.id, answer=answer)
121
 
122
+ # ---------------- Intent detect
123
  gen_prompt = s.project["versions"][0]["general_prompt"]
124
  intent_raw = await spark_generate(s, gen_prompt, user_msg)
125
 
 
126
  if not intent_raw.startswith("#DETECTED_INTENT:"):
127
  s.history.append({"role": "assistant", "content": intent_raw})
128
  return ChatResponse(session_id=s.id, answer=intent_raw)
129
 
 
130
  intent_name = intent_raw.split(":", 1)[1].strip()
131
  if intent_name not in ALLOWED_INTENTS:
 
132
  clean = intent_raw.split("#DETECTED_INTENT")[0].split("\nassistant")[0].strip()
133
  s.history.append({"role": "assistant", "content": clean})
134
  return ChatResponse(session_id=s.id, answer=clean)
 
156
 
157
  async def _handle_intent(s, intent_cfg, user_msg):
158
  missing = _missing(s, intent_cfg)
 
159
  if missing:
160
  p_prompt = build_parameter_prompt(intent_cfg, missing, user_msg, s.history)
161
  p_raw = await spark_generate(s, p_prompt, user_msg)
 
176
  async def _followup(s, user_msg):
177
  intent_cfg = s.awaiting["intent"]
178
  missing = s.awaiting["missing"]
179
+ p_prompt = build_parameter_prompt(intent_cfg, missing, user_msg, s.history)
180
+ p_raw = await spark_generate(s, p_prompt, user_msg)
181
  if not p_raw.startswith("#PARAMETERS:"):
182
  return "Üzgünüm, anlayamadım."
183
  if bad := _process_params(s, intent_cfg, p_raw):