redhairedshanks1 commited on
Commit
252fdc4
ยท
1 Parent(s): 7482bb6

more like bot

Browse files
Files changed (1) hide show
  1. api_routes_v2.py +398 -0
api_routes_v2.py ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # API Routes V2 - Enhanced with Intent Classification and Dual Response Format
2
+ # File: api_routes_v2.py
3
+
4
+ from fastapi import APIRouter, HTTPException, UploadFile, File, Form
5
+ from fastapi.responses import StreamingResponse
6
+ from pydantic import BaseModel
7
+ from typing import Optional, List, Dict, Any
8
+ import json
9
+ import os
10
+ import uuid
11
+ from datetime import datetime
12
+
13
+ # Import our services
14
+ from services.pipeline_generator import generate_pipeline, format_pipeline_for_display
15
+ from services.pipeline_executor import execute_pipeline_streaming, execute_pipeline
16
+ from services.session_manager import session_manager
17
+ from services.intent_classifier import intent_classifier
18
+
19
+ router = APIRouter(prefix="/api/v2", tags=["MasterLLM API V2 - Enhanced"])
20
+
21
+
22
+ # ========================
23
+ # REQUEST/RESPONSE MODELS
24
+ # ========================
25
+
26
+ class ChatRequest(BaseModel):
27
+ """Enhanced chat request with intent classification"""
28
+ message: str
29
+ session_id: Optional[str] = None
30
+ file_path: Optional[str] = None
31
+ prefer_bedrock: bool = True
32
+
33
+
34
+ class ChatResponse(BaseModel):
35
+ """Dual response format - friendly for users, detailed for developers"""
36
+ # User-facing response (what users see)
37
+ user_response: str
38
+
39
+ # Developer/API response (detailed data for frontend integration)
40
+ api_response: Dict[str, Any]
41
+
42
+ # Intent classification
43
+ intent: Dict[str, Any]
44
+
45
+ # Session info
46
+ session_id: str
47
+ state: str
48
+
49
+
50
+ # ========================
51
+ # SMART CHAT ENDPOINT
52
+ # ========================
53
+
54
+ @router.post("/chat", response_model=ChatResponse)
55
+ async def smart_chat(request: ChatRequest):
56
+ """
57
+ Intelligent chat endpoint that:
58
+ 1. Classifies user intent
59
+ 2. Responds naturally to casual conversation
60
+ 3. Only generates pipelines when explicitly requested
61
+ 4. Returns dual format: user-friendly + detailed API data
62
+ """
63
+
64
+ # Get or create session
65
+ session_id = request.session_id
66
+ if not session_id:
67
+ session_id = session_manager.create_session()
68
+
69
+ session = session_manager.get_session(session_id)
70
+ if not session:
71
+ session_id = session_manager.create_session()
72
+ session = session_manager.get_session(session_id)
73
+
74
+ # Update file path if provided
75
+ if request.file_path:
76
+ session_manager.update_session(session_id, {"current_file": request.file_path})
77
+ session = session_manager.get_session(session_id)
78
+
79
+ # Add user message to session
80
+ session_manager.add_message(session_id, "user", request.message)
81
+
82
+ # Classify intent
83
+ intent_data = intent_classifier.classify_intent(request.message)
84
+ current_state = session.get("state", "initial")
85
+
86
+ try:
87
+ # ========================
88
+ # HANDLE CASUAL CHAT
89
+ # ========================
90
+ if intent_data["intent"] == "casual_chat":
91
+ friendly_response = intent_classifier.get_friendly_response("casual_chat", request.message)
92
+
93
+ api_data = {
94
+ "type": "casual_response",
95
+ "message": friendly_response,
96
+ "intent_classification": intent_data,
97
+ "suggestions": [
98
+ "Upload a document to get started",
99
+ "Ask 'what can you do?' to see capabilities",
100
+ "Type 'help' for usage instructions"
101
+ ]
102
+ }
103
+
104
+ session_manager.add_message(session_id, "assistant", friendly_response)
105
+
106
+ return ChatResponse(
107
+ user_response=friendly_response,
108
+ api_response=api_data,
109
+ intent=intent_data,
110
+ session_id=session_id,
111
+ state=current_state
112
+ )
113
+
114
+ # ========================
115
+ # HANDLE QUESTIONS
116
+ # ========================
117
+ elif intent_data["intent"] == "question":
118
+ friendly_response = intent_classifier.get_friendly_response("question", request.message)
119
+
120
+ api_data = {
121
+ "type": "informational_response",
122
+ "message": friendly_response,
123
+ "intent_classification": intent_data
124
+ }
125
+
126
+ session_manager.add_message(session_id, "assistant", friendly_response)
127
+
128
+ return ChatResponse(
129
+ user_response=friendly_response,
130
+ api_response=api_data,
131
+ intent=intent_data,
132
+ session_id=session_id,
133
+ state=current_state
134
+ )
135
+
136
+ # ========================
137
+ # HANDLE UNCLEAR INTENT
138
+ # ========================
139
+ elif intent_data["intent"] == "unclear":
140
+ friendly_response = intent_classifier.get_friendly_response("unclear", request.message)
141
+
142
+ api_data = {
143
+ "type": "clarification_needed",
144
+ "message": friendly_response,
145
+ "intent_classification": intent_data,
146
+ "suggestions": [
147
+ "Be more specific about what you want to do",
148
+ "Use keywords like: extract, summarize, translate, etc.",
149
+ "Type 'help' for examples"
150
+ ]
151
+ }
152
+
153
+ session_manager.add_message(session_id, "assistant", friendly_response)
154
+
155
+ return ChatResponse(
156
+ user_response=friendly_response,
157
+ api_response=api_data,
158
+ intent=intent_data,
159
+ session_id=session_id,
160
+ state=current_state
161
+ )
162
+
163
+ # ========================
164
+ # HANDLE PIPELINE APPROVAL
165
+ # ========================
166
+ elif intent_data["intent"] == "approval" and current_state == "pipeline_proposed":
167
+ proposed_pipeline = session.get("proposed_pipeline")
168
+
169
+ if not proposed_pipeline:
170
+ error_msg = "No pipeline to approve. Please request a task first."
171
+ return ChatResponse(
172
+ user_response=error_msg,
173
+ api_response={"type": "error", "message": error_msg},
174
+ intent=intent_data,
175
+ session_id=session_id,
176
+ state=current_state
177
+ )
178
+
179
+ # Update state
180
+ session_manager.update_session(session_id, {"state": "executing"})
181
+
182
+ friendly_response = f"โœ… Great! Executing the pipeline: {proposed_pipeline.get('pipeline_name')}\n\nโณ Processing... (Use the streaming endpoint for real-time updates)"
183
+
184
+ api_data = {
185
+ "type": "pipeline_approved",
186
+ "message": "Pipeline execution started",
187
+ "pipeline": proposed_pipeline,
188
+ "execution_status": "started",
189
+ "note": "Use /api/v2/pipeline/execute/stream for real-time progress"
190
+ }
191
+
192
+ session_manager.add_message(session_id, "assistant", friendly_response)
193
+
194
+ return ChatResponse(
195
+ user_response=friendly_response,
196
+ api_response=api_data,
197
+ intent=intent_data,
198
+ session_id=session_id,
199
+ state="executing"
200
+ )
201
+
202
+ # ========================
203
+ # HANDLE PIPELINE REJECTION
204
+ # ========================
205
+ elif intent_data["intent"] == "rejection" and current_state == "pipeline_proposed":
206
+ session_manager.update_session(session_id, {
207
+ "state": "initial",
208
+ "proposed_pipeline": None
209
+ })
210
+
211
+ friendly_response = "No problem! The pipeline has been cancelled. What else would you like me to help you with?"
212
+
213
+ api_data = {
214
+ "type": "pipeline_rejected",
215
+ "message": "Pipeline cancelled by user",
216
+ "state_reset": True
217
+ }
218
+
219
+ session_manager.add_message(session_id, "assistant", friendly_response)
220
+
221
+ return ChatResponse(
222
+ user_response=friendly_response,
223
+ api_response=api_data,
224
+ intent=intent_data,
225
+ session_id=session_id,
226
+ state="initial"
227
+ )
228
+
229
+ # ========================
230
+ # HANDLE PIPELINE REQUEST
231
+ # ========================
232
+ elif intent_data["intent"] == "pipeline_request" and intent_data["requires_pipeline"]:
233
+ # Check if file is uploaded
234
+ if not session.get("current_file"):
235
+ friendly_response = "๐Ÿ“ Please upload a document first before I can process it!\n\nOnce you upload a file, I'll be happy to help you with that task."
236
+
237
+ api_data = {
238
+ "type": "error",
239
+ "error_code": "NO_FILE_UPLOADED",
240
+ "message": "Document required before pipeline generation",
241
+ "action_required": "upload_file"
242
+ }
243
+
244
+ session_manager.add_message(session_id, "assistant", friendly_response)
245
+
246
+ return ChatResponse(
247
+ user_response=friendly_response,
248
+ api_response=api_data,
249
+ intent=intent_data,
250
+ session_id=session_id,
251
+ state=current_state
252
+ )
253
+
254
+ # Generate pipeline
255
+ try:
256
+ pipeline = generate_pipeline(
257
+ user_input=request.message,
258
+ file_path=session.get("current_file"),
259
+ prefer_bedrock=request.prefer_bedrock
260
+ )
261
+
262
+ # Save to session
263
+ session_manager.update_session(session_id, {
264
+ "proposed_pipeline": pipeline,
265
+ "state": "pipeline_proposed"
266
+ })
267
+
268
+ # Create user-friendly response
269
+ pipeline_name = pipeline.get("pipeline_name", "Document Processing")
270
+ steps_list = pipeline.get("pipeline_steps", [])
271
+ steps_summary = "\n".join([f" {i+1}. {step.get('tool', 'Unknown')}" for i, step in enumerate(steps_list)])
272
+
273
+ friendly_response = f"""๐ŸŽฏ **Pipeline Created: {pipeline_name}**
274
+
275
+ Here's what I'll do:
276
+ {steps_summary}
277
+
278
+ **Ready to proceed?**
279
+ - Type 'approve' or 'yes' to execute
280
+ - Type 'reject' or 'no' to cancel
281
+ - Describe changes to modify the plan"""
282
+
283
+ # Create detailed API response
284
+ api_data = {
285
+ "type": "pipeline_generated",
286
+ "message": "Pipeline successfully created",
287
+ "pipeline": pipeline,
288
+ "pipeline_summary": {
289
+ "name": pipeline_name,
290
+ "total_steps": len(steps_list),
291
+ "steps": steps_list,
292
+ "generator": pipeline.get("_generator"),
293
+ "model": pipeline.get("_model")
294
+ },
295
+ "required_action": "approval",
296
+ "next_steps": {
297
+ "approve": "Type 'approve' or 'yes'",
298
+ "reject": "Type 'reject' or 'no'",
299
+ "modify": "Describe your changes"
300
+ }
301
+ }
302
+
303
+ session_manager.add_message(session_id, "assistant", friendly_response)
304
+
305
+ return ChatResponse(
306
+ user_response=friendly_response,
307
+ api_response=api_data,
308
+ intent=intent_data,
309
+ session_id=session_id,
310
+ state="pipeline_proposed"
311
+ )
312
+
313
+ except Exception as e:
314
+ friendly_response = f"โŒ Oops! I encountered an error while creating the pipeline:\n\n{str(e)}\n\nPlease try rephrasing your request or type 'help' for examples."
315
+
316
+ api_data = {
317
+ "type": "error",
318
+ "error_code": "PIPELINE_GENERATION_FAILED",
319
+ "message": str(e),
320
+ "traceback": str(e)
321
+ }
322
+
323
+ session_manager.add_message(session_id, "assistant", friendly_response)
324
+
325
+ return ChatResponse(
326
+ user_response=friendly_response,
327
+ api_response=api_data,
328
+ intent=intent_data,
329
+ session_id=session_id,
330
+ state=current_state
331
+ )
332
+
333
+ # ========================
334
+ # DEFAULT RESPONSE
335
+ # ========================
336
+ else:
337
+ friendly_response = "I'm not sure how to help with that. Could you please:\n- Upload a document first, or\n- Tell me what you'd like to do (e.g., 'extract text', 'summarize')\n\nType 'help' for more information!"
338
+
339
+ api_data = {
340
+ "type": "unclear_intent",
341
+ "message": "Could not determine appropriate action",
342
+ "intent_classification": intent_data,
343
+ "current_state": current_state
344
+ }
345
+
346
+ session_manager.add_message(session_id, "assistant", friendly_response)
347
+
348
+ return ChatResponse(
349
+ user_response=friendly_response,
350
+ api_response=api_data,
351
+ intent=intent_data,
352
+ session_id=session_id,
353
+ state=current_state
354
+ )
355
+
356
+ except Exception as e:
357
+ # Global error handler
358
+ error_msg = f"An unexpected error occurred: {str(e)}"
359
+
360
+ return ChatResponse(
361
+ user_response=error_msg,
362
+ api_response={
363
+ "type": "unexpected_error",
364
+ "error": str(e)
365
+ },
366
+ intent=intent_data,
367
+ session_id=session_id,
368
+ state=current_state
369
+ )
370
+
371
+
372
+ # ========================
373
+ # INHERIT OTHER ENDPOINTS FROM V1
374
+ # ========================
375
+
376
+ # Re-export all other endpoints from the original api_routes
377
+ from api_routes import (
378
+ create_session,
379
+ get_session,
380
+ get_session_stats,
381
+ get_session_history,
382
+ add_message,
383
+ upload_file,
384
+ get_pipeline_history,
385
+ get_pipeline_stats,
386
+ health_check
387
+ )
388
+
389
+ # Re-register them on the V2 router
390
+ router.post("/sessions")(create_session)
391
+ router.get("/sessions/{session_id}")(get_session)
392
+ router.get("/sessions/{session_id}/stats")(get_session_stats)
393
+ router.get("/sessions/{session_id}/history")(get_session_history)
394
+ router.post("/sessions/{session_id}/messages")(add_message)
395
+ router.post("/upload")(upload_file)
396
+ router.get("/pipelines/history")(get_pipeline_history)
397
+ router.get("/pipelines/stats")(get_pipeline_stats)
398
+ router.get("/health")(health_check)