ciyidogan commited on
Commit
4198501
Β·
verified Β·
1 Parent(s): c836e99

Update controllers/project_controller.py

Browse files
Files changed (1) hide show
  1. controllers/project_controller.py +100 -6
controllers/project_controller.py CHANGED
@@ -1,11 +1,22 @@
1
- from fastapi import APIRouter, Request
2
  from service_config import ServiceConfig
 
 
 
 
 
3
  from log import log
4
  import json
 
5
 
6
  router = APIRouter()
7
  service_config = ServiceConfig()
8
  service_config.load()
 
 
 
 
 
9
 
10
  def save_config():
11
  with open(service_config.config_path, "w", encoding="utf-8") as f:
@@ -20,6 +31,93 @@ def save_config():
20
  "apis": service_config.apis
21
  }, f, indent=2)
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  @router.get("/list_projects")
24
  def list_projects():
25
  projects = list(service_config.projects.keys())
@@ -58,8 +156,6 @@ async def delete_project(request: Request):
58
  log(f"πŸ—‘οΈ Deleted project: {project_name}")
59
  return {"message": f"Project {project_name} deleted."}
60
 
61
- # === INTENT CRUD ===
62
-
63
  @router.get("/list_intents")
64
  def list_intents(project_name: str):
65
  project = service_config.get_project(project_name)
@@ -115,14 +211,12 @@ async def delete_intent(request: Request):
115
  log(f"πŸ—‘οΈ Deleted intent: {intent_name} from project: {project_name}")
116
  return {"message": f"Intent {intent_name} deleted from project {project_name}."}
117
 
118
- # === PARAMETER CRUD ===
119
-
120
  @router.post("/add_parameter")
121
  async def add_parameter(request: Request):
122
  data = await request.json()
123
  project_name = data.get("project_name")
124
  intent_name = data.get("intent_name")
125
- parameter = data.get("parameter") # {name, type, regex, validation_message, extraction_prompt}
126
  if not project_name or not intent_name or not parameter:
127
  return {"error": "Project, intent, and parameter data required."}
128
 
 
1
+ from fastapi import APIRouter, Request, Header
2
  from service_config import ServiceConfig
3
+ from session import SessionStore
4
+ from prompt_engine import PromptEngine
5
+ from llm_connector import LLMConnector
6
+ from api_connector import APIConnector
7
+ from validation_engine import ValidationEngine
8
  from log import log
9
  import json
10
+ import traceback
11
 
12
  router = APIRouter()
13
  service_config = ServiceConfig()
14
  service_config.load()
15
+ session_store = SessionStore()
16
+ prompt_engine = PromptEngine(service_config)
17
+ llm_connector = LLMConnector(service_config)
18
+ api_connector = APIConnector(service_config)
19
+ validation_engine = ValidationEngine()
20
 
21
  def save_config():
22
  with open(service_config.config_path, "w", encoding="utf-8") as f:
 
31
  "apis": service_config.apis
32
  }, f, indent=2)
33
 
34
+ @router.post("/start_chat")
35
+ def start_chat(request: Request):
36
+ project_name = request.query_params.get("project_name")
37
+ if not project_name:
38
+ return {"error": "Missing project_name parameter."}
39
+ session = session_store.create_session(project_name)
40
+ return {"session_id": session.session_id}
41
+
42
+ @router.post("/chat")
43
+ async def chat(request: Request, x_session_id: str = Header(None)):
44
+ if not x_session_id:
45
+ return {"error": "Missing X-Session-ID header."}
46
+ session = session_store.get_session(x_session_id)
47
+ if not session:
48
+ return {"error": "Invalid or expired session."}
49
+ try:
50
+ body = await request.json()
51
+ user_input = body.get("user_input", "").strip()
52
+ if not user_input:
53
+ return {"error": "Empty user input."}
54
+ session.chat_history.append({"role": "user", "content": user_input})
55
+ project_name = session.project_name
56
+
57
+ if session.state == "intent_detection":
58
+ prompt = prompt_engine.build_intent_prompt(project_name)
59
+ llm_response = llm_connector.call_spark(project_name, prompt, session.chat_history)
60
+ if llm_response is None:
61
+ return {"error": "Failed to get intent detection result."}
62
+ intent = llm_response.get("intent")
63
+ params = llm_response.get("params", {})
64
+ missing = llm_response.get("missing", [])
65
+ session.last_intent = intent
66
+ session.variables.update(params)
67
+ session.awaiting_parameters = missing
68
+ if missing:
69
+ session.state = "parameter_extraction"
70
+ return {"response": f"Please provide: {', '.join(missing)}"}
71
+ session.state = "validation"
72
+
73
+ if session.state == "parameter_extraction":
74
+ prompt = prompt_engine.build_parameter_prompt(project_name, session.last_intent, session.awaiting_parameters)
75
+ llm_response = llm_connector.call_spark(project_name, prompt, session.chat_history)
76
+ if llm_response is None:
77
+ return {"error": "Failed to extract parameters."}
78
+ params = llm_response.get("params", {})
79
+ missing = llm_response.get("missing", [])
80
+ session.variables.update(params)
81
+ session.awaiting_parameters = missing
82
+ if missing:
83
+ return {"response": f"Please provide: {', '.join(missing)}"}
84
+ session.state = "validation"
85
+
86
+ if session.state == "validation":
87
+ intent_def = next((i for i in service_config.get_project_intents(project_name) if i["name"] == session.last_intent), None)
88
+ if not intent_def:
89
+ return {"error": f"Intent definition not found: {session.last_intent}"}
90
+ is_valid, errors = validation_engine.validate_parameters(intent_def, session.variables)
91
+ if not is_valid:
92
+ return {"response": " ".join(errors)}
93
+ session.state = "api_call"
94
+
95
+ if session.state == "api_call":
96
+ intent_def = next((i for i in service_config.get_project_intents(project_name) if i["name"] == session.last_intent), None)
97
+ api_response = api_connector.call_api(intent_def, session)
98
+ if "fallback" in api_response:
99
+ return {"response": api_response["fallback"]}
100
+ session.state = "humanization"
101
+ session.variables["api_result"] = api_response
102
+
103
+ if session.state == "humanization":
104
+ prompt = prompt_engine.build_humanization_prompt(project_name, session.last_intent)
105
+ chat_history = [{"role": "system", "content": str(session.variables["api_result"])}]
106
+ humanized_response = llm_connector.call_spark(project_name, prompt, chat_history)
107
+ if humanized_response is None:
108
+ return {"error": "Failed to humanize response."}
109
+ session.chat_history.append({"role": "assistant", "content": humanized_response.get("answer")})
110
+ session.state = "intent_detection"
111
+ session.last_intent = None
112
+ session.variables = {}
113
+ session.awaiting_parameters = []
114
+ return {"response": humanized_response.get("answer")}
115
+
116
+ except Exception as e:
117
+ log(f"❌ Error in chat: {e}")
118
+ traceback.print_exc()
119
+ return {"error": str(e)}
120
+
121
  @router.get("/list_projects")
122
  def list_projects():
123
  projects = list(service_config.projects.keys())
 
156
  log(f"πŸ—‘οΈ Deleted project: {project_name}")
157
  return {"message": f"Project {project_name} deleted."}
158
 
 
 
159
  @router.get("/list_intents")
160
  def list_intents(project_name: str):
161
  project = service_config.get_project(project_name)
 
211
  log(f"πŸ—‘οΈ Deleted intent: {intent_name} from project: {project_name}")
212
  return {"message": f"Intent {intent_name} deleted from project {project_name}."}
213
 
 
 
214
  @router.post("/add_parameter")
215
  async def add_parameter(request: Request):
216
  data = await request.json()
217
  project_name = data.get("project_name")
218
  intent_name = data.get("intent_name")
219
+ parameter = data.get("parameter")
220
  if not project_name or not intent_name or not parameter:
221
  return {"error": "Project, intent, and parameter data required."}
222