JatsTheAIGen commited on
Commit
d771375
·
1 Parent(s): fa57725

Details enhancement V1

Browse files
Files changed (2) hide show
  1. app.py +115 -13
  2. orchestrator_engine.py +286 -7
app.py CHANGED
@@ -429,12 +429,31 @@ async def process_message_async(message: str, history: Optional[List], session_i
429
  str(result.get('result', ''))
430
  )
431
 
432
- # Extract metadata for Details tab
433
- reasoning_data = {
434
- "intent": result.get('metadata', {}).get('intent', 'unknown'),
435
- "execution_plan": result.get('metadata', {}).get('execution_plan', {}),
436
- "processing_steps": result.get('metadata', {}).get('processing_steps', [])
437
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
439
  performance_data = {
440
  "agent_trace": result.get('agent_trace', []),
@@ -464,14 +483,52 @@ async def process_message_async(message: str, history: Optional[List], session_i
464
 
465
  except Exception as orch_error:
466
  logger.error(f"Orchestrator error: {orch_error}", exc_info=True)
467
- # Fallback response with error info
468
  response = f"I'm experiencing some technical difficulties. Your message was: '{message[:100]}...' Please try again or rephrase your question."
469
- reasoning_data = {"error": str(orch_error)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  else:
471
- # System initialization message
472
  logger.info("Orchestrator not yet available")
473
  response = f"Hello! I received your message about: '{message}'.\n\nThe orchestration system is initializing. Your question is important and I'll provide a comprehensive answer shortly."
474
- reasoning_data = {"status": "initializing"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
 
476
  # Add assistant response
477
  new_history.append({"role": "assistant", "content": response})
@@ -480,7 +537,7 @@ async def process_message_async(message: str, history: Optional[List], session_i
480
  return new_history, "", reasoning_data, performance_data, context_data, session_id
481
 
482
  except Exception as e:
483
- # FINAL FALLBACK: Always return something to user
484
  logger.error(f"Error in process_message_async: {e}", exc_info=True)
485
 
486
  # Create error history with helpful message
@@ -494,7 +551,29 @@ async def process_message_async(message: str, history: Optional[List], session_i
494
  )
495
  error_history.append({"role": "assistant", "content": error_message})
496
 
497
- return error_history, "", {"error": str(e)}, {}, {}, session_id
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
 
499
  def process_message(message: str, history: Optional[List], session_id: Optional[str] = None) -> Tuple[List, str, dict, dict, dict, str]:
500
  """
@@ -518,7 +597,30 @@ def process_message(message: str, history: Optional[List], session_id: Optional[
518
  error_history = list(history) if history else []
519
  error_history.append({"role": "user", "content": message})
520
  error_history.append({"role": "assistant", "content": f"Error: {str(e)}"})
521
- return error_history, "", {"error": str(e)}, {}, {}, session_id
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
 
523
  # Decorate the chat handler with GPU if available
524
  if SPACES_GPU_AVAILABLE and GPU is not None:
 
429
  str(result.get('result', ''))
430
  )
431
 
432
+ # Extract metadata for Details tab with enhanced reasoning chain
433
+ reasoning_data = result.get('metadata', {}).get('reasoning_chain', {
434
+ "chain_of_thought": {},
435
+ "alternative_paths": [],
436
+ "uncertainty_areas": [],
437
+ "evidence_sources": [],
438
+ "confidence_calibration": {}
439
+ })
440
+
441
+ # Ensure we have the enhanced structure even if orchestrator didn't provide it
442
+ if not reasoning_data.get('chain_of_thought'):
443
+ reasoning_data = {
444
+ "chain_of_thought": {
445
+ "step_1": {
446
+ "hypothesis": "Processing user request",
447
+ "evidence": [f"User input: {message[:50]}..."],
448
+ "confidence": 0.7,
449
+ "reasoning": "Basic request processing"
450
+ }
451
+ },
452
+ "alternative_paths": [],
453
+ "uncertainty_areas": [],
454
+ "evidence_sources": [],
455
+ "confidence_calibration": {"overall_confidence": 0.7}
456
+ }
457
 
458
  performance_data = {
459
  "agent_trace": result.get('agent_trace', []),
 
483
 
484
  except Exception as orch_error:
485
  logger.error(f"Orchestrator error: {orch_error}", exc_info=True)
486
+ # Fallback response with error info and enhanced reasoning
487
  response = f"I'm experiencing some technical difficulties. Your message was: '{message[:100]}...' Please try again or rephrase your question."
488
+ reasoning_data = {
489
+ "chain_of_thought": {
490
+ "step_1": {
491
+ "hypothesis": "System encountered an error during processing",
492
+ "evidence": [f"Error: {str(orch_error)[:100]}..."],
493
+ "confidence": 0.3,
494
+ "reasoning": "Orchestrator failure - fallback mode activated"
495
+ }
496
+ },
497
+ "alternative_paths": [],
498
+ "uncertainty_areas": [
499
+ {
500
+ "aspect": "System reliability",
501
+ "confidence": 0.3,
502
+ "mitigation": "Error handling and graceful degradation"
503
+ }
504
+ ],
505
+ "evidence_sources": [],
506
+ "confidence_calibration": {"overall_confidence": 0.3, "error_mode": True}
507
+ }
508
  else:
509
+ # System initialization message with enhanced reasoning
510
  logger.info("Orchestrator not yet available")
511
  response = f"Hello! I received your message about: '{message}'.\n\nThe orchestration system is initializing. Your question is important and I'll provide a comprehensive answer shortly."
512
+ reasoning_data = {
513
+ "chain_of_thought": {
514
+ "step_1": {
515
+ "hypothesis": "System is initializing and not yet ready",
516
+ "evidence": ["Orchestrator not available", f"User input: {message[:50]}..."],
517
+ "confidence": 0.5,
518
+ "reasoning": "System startup phase - components loading"
519
+ }
520
+ },
521
+ "alternative_paths": [],
522
+ "uncertainty_areas": [
523
+ {
524
+ "aspect": "System readiness",
525
+ "confidence": 0.5,
526
+ "mitigation": "Graceful initialization message"
527
+ }
528
+ ],
529
+ "evidence_sources": [],
530
+ "confidence_calibration": {"overall_confidence": 0.5, "initialization_mode": True}
531
+ }
532
 
533
  # Add assistant response
534
  new_history.append({"role": "assistant", "content": response})
 
537
  return new_history, "", reasoning_data, performance_data, context_data, session_id
538
 
539
  except Exception as e:
540
+ # FINAL FALLBACK: Always return something to user with enhanced reasoning
541
  logger.error(f"Error in process_message_async: {e}", exc_info=True)
542
 
543
  # Create error history with helpful message
 
551
  )
552
  error_history.append({"role": "assistant", "content": error_message})
553
 
554
+ # Enhanced reasoning for error case
555
+ reasoning_data = {
556
+ "chain_of_thought": {
557
+ "step_1": {
558
+ "hypothesis": "Critical system error occurred",
559
+ "evidence": [f"Exception: {str(e)[:100]}...", f"User input: {message[:50]}..."],
560
+ "confidence": 0.2,
561
+ "reasoning": "System error handling - final fallback activated"
562
+ }
563
+ },
564
+ "alternative_paths": [],
565
+ "uncertainty_areas": [
566
+ {
567
+ "aspect": "System stability",
568
+ "confidence": 0.2,
569
+ "mitigation": "Error logging and user notification"
570
+ }
571
+ ],
572
+ "evidence_sources": [],
573
+ "confidence_calibration": {"overall_confidence": 0.2, "critical_error": True}
574
+ }
575
+
576
+ return error_history, "", reasoning_data, {}, {}, session_id
577
 
578
  def process_message(message: str, history: Optional[List], session_id: Optional[str] = None) -> Tuple[List, str, dict, dict, dict, str]:
579
  """
 
597
  error_history = list(history) if history else []
598
  error_history.append({"role": "user", "content": message})
599
  error_history.append({"role": "assistant", "content": f"Error: {str(e)}"})
600
+
601
+ # Enhanced reasoning for sync error case
602
+ reasoning_data = {
603
+ "chain_of_thought": {
604
+ "step_1": {
605
+ "hypothesis": "Synchronous processing error",
606
+ "evidence": [f"Sync error: {str(e)[:100]}...", f"User input: {message[:50]}..."],
607
+ "confidence": 0.2,
608
+ "reasoning": "Synchronous wrapper error handling"
609
+ }
610
+ },
611
+ "alternative_paths": [],
612
+ "uncertainty_areas": [
613
+ {
614
+ "aspect": "Processing reliability",
615
+ "confidence": 0.2,
616
+ "mitigation": "Error logging and fallback response"
617
+ }
618
+ ],
619
+ "evidence_sources": [],
620
+ "confidence_calibration": {"overall_confidence": 0.2, "sync_error": True}
621
+ }
622
+
623
+ return error_history, "", reasoning_data, {}, {}, session_id
624
 
625
  # Decorate the chat handler with GPU if available
626
  if SPACES_GPU_AVAILABLE and GPU is not None:
orchestrator_engine.py CHANGED
@@ -16,7 +16,7 @@ class MVPOrchestrator:
16
 
17
  async def process_request(self, session_id: str, user_input: str) -> dict:
18
  """
19
- Main orchestration flow with academic differentiation
20
  """
21
  logger.info(f"Processing request for session {session_id}")
22
  logger.info(f"User input: {user_input[:100]}")
@@ -25,17 +25,38 @@ class MVPOrchestrator:
25
  self.execution_trace = []
26
  start_time = time.time()
27
 
 
 
 
 
 
 
 
 
 
28
  try:
29
  # Step 1: Generate unique interaction ID
30
  interaction_id = self._generate_interaction_id(session_id)
31
  logger.info(f"Generated interaction ID: {interaction_id}")
32
 
33
- # Step 2: Context management
34
  logger.info("Step 2: Managing context...")
35
  context = await self.context_manager.manage_context(session_id, user_input)
36
  logger.info(f"Context retrieved: {len(context.get('interactions', []))} interactions")
37
 
38
- # Step 3: Intent recognition with CoT
 
 
 
 
 
 
 
 
 
 
 
 
39
  logger.info("Step 3: Recognizing intent...")
40
  self.execution_trace.append({
41
  "step": "intent_recognition",
@@ -52,16 +73,40 @@ class MVPOrchestrator:
52
  })
53
  logger.info(f"Intent detected: {intent_result.get('primary_intent', 'unknown')}")
54
 
55
- # Step 4: Agent execution planning
 
 
 
 
 
 
 
 
 
 
 
 
56
  logger.info("Step 4: Creating execution plan...")
57
  execution_plan = await self._create_execution_plan(intent_result, context)
58
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  # Step 5: Parallel agent execution
60
  logger.info("Step 5: Executing agents...")
61
  agent_results = await self._execute_agents(execution_plan, user_input, context)
62
  logger.info(f"Agent execution complete: {len(agent_results)} results")
63
 
64
- # Step 6: Response synthesis
65
  logger.info("Step 6: Synthesizing response...")
66
  self.execution_trace.append({
67
  "step": "response_synthesis",
@@ -78,7 +123,19 @@ class MVPOrchestrator:
78
  "result": {"synthesis_method": final_response.get('synthesis_method', 'unknown')}
79
  })
80
 
81
- # Step 7: Safety and bias check
 
 
 
 
 
 
 
 
 
 
 
 
82
  logger.info("Step 7: Safety check...")
83
  self.execution_trace.append({
84
  "step": "safety_check",
@@ -94,6 +151,24 @@ class MVPOrchestrator:
94
  "result": {"warnings": safety_checked.get('warnings', [])}
95
  })
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  processing_time = time.time() - start_time
98
 
99
  result = self._format_final_output(safety_checked, interaction_id, {
@@ -110,7 +185,8 @@ class MVPOrchestrator:
110
  'processing_time': processing_time,
111
  'agents_used': list(self.agents.keys()),
112
  'intent_result': intent_result,
113
- 'synthesis_result': final_response
 
114
  })
115
 
116
  # Update context with the final response for future context retrieval
@@ -220,4 +296,207 @@ class MVPOrchestrator:
220
  Clear the execution trace
221
  """
222
  self.execution_trace = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
 
16
 
17
  async def process_request(self, session_id: str, user_input: str) -> dict:
18
  """
19
+ Main orchestration flow with academic differentiation and enhanced reasoning chain
20
  """
21
  logger.info(f"Processing request for session {session_id}")
22
  logger.info(f"User input: {user_input[:100]}")
 
25
  self.execution_trace = []
26
  start_time = time.time()
27
 
28
+ # Initialize enhanced reasoning chain
29
+ reasoning_chain = {
30
+ "chain_of_thought": {},
31
+ "alternative_paths": [],
32
+ "uncertainty_areas": [],
33
+ "evidence_sources": [],
34
+ "confidence_calibration": {}
35
+ }
36
+
37
  try:
38
  # Step 1: Generate unique interaction ID
39
  interaction_id = self._generate_interaction_id(session_id)
40
  logger.info(f"Generated interaction ID: {interaction_id}")
41
 
42
+ # Step 2: Context management with reasoning
43
  logger.info("Step 2: Managing context...")
44
  context = await self.context_manager.manage_context(session_id, user_input)
45
  logger.info(f"Context retrieved: {len(context.get('interactions', []))} interactions")
46
 
47
+ # Add context analysis to reasoning chain
48
+ reasoning_chain["chain_of_thought"]["step_1"] = {
49
+ "hypothesis": "Analyzing conversation context and user history",
50
+ "evidence": [
51
+ f"Previous interactions: {len(context.get('interactions', []))}",
52
+ f"Session duration: {self._calculate_session_duration(context)}",
53
+ f"Topic continuity: {self._analyze_topic_continuity(context, user_input)}"
54
+ ],
55
+ "confidence": 0.85,
56
+ "reasoning": "Context analysis provides foundation for intent recognition and response personalization"
57
+ }
58
+
59
+ # Step 3: Intent recognition with enhanced CoT
60
  logger.info("Step 3: Recognizing intent...")
61
  self.execution_trace.append({
62
  "step": "intent_recognition",
 
73
  })
74
  logger.info(f"Intent detected: {intent_result.get('primary_intent', 'unknown')}")
75
 
76
+ # Add intent reasoning to chain
77
+ reasoning_chain["chain_of_thought"]["step_2"] = {
78
+ "hypothesis": f"User intent is '{intent_result.get('primary_intent', 'unknown')}'",
79
+ "evidence": [
80
+ f"Pattern analysis: {self._extract_pattern_evidence(user_input)}",
81
+ f"Confidence scores: {intent_result.get('confidence_scores', {})}",
82
+ f"Secondary intents: {intent_result.get('secondary_intents', [])}"
83
+ ],
84
+ "confidence": intent_result.get('confidence_scores', {}).get(intent_result.get('primary_intent', 'unknown'), 0.7),
85
+ "reasoning": f"Intent recognition based on linguistic patterns and context analysis"
86
+ }
87
+
88
+ # Step 4: Agent execution planning with reasoning
89
  logger.info("Step 4: Creating execution plan...")
90
  execution_plan = await self._create_execution_plan(intent_result, context)
91
 
92
+ # Add execution planning reasoning
93
+ reasoning_chain["chain_of_thought"]["step_3"] = {
94
+ "hypothesis": f"Optimal agent sequence for '{intent_result.get('primary_intent', 'unknown')}' intent",
95
+ "evidence": [
96
+ f"Intent complexity: {self._assess_intent_complexity(intent_result)}",
97
+ f"Required agents: {execution_plan.get('agents_to_execute', [])}",
98
+ f"Execution strategy: {execution_plan.get('execution_order', 'sequential')}"
99
+ ],
100
+ "confidence": 0.80,
101
+ "reasoning": "Agent selection based on intent requirements and system capabilities"
102
+ }
103
+
104
  # Step 5: Parallel agent execution
105
  logger.info("Step 5: Executing agents...")
106
  agent_results = await self._execute_agents(execution_plan, user_input, context)
107
  logger.info(f"Agent execution complete: {len(agent_results)} results")
108
 
109
+ # Step 6: Response synthesis with reasoning
110
  logger.info("Step 6: Synthesizing response...")
111
  self.execution_trace.append({
112
  "step": "response_synthesis",
 
123
  "result": {"synthesis_method": final_response.get('synthesis_method', 'unknown')}
124
  })
125
 
126
+ # Add synthesis reasoning
127
+ reasoning_chain["chain_of_thought"]["step_4"] = {
128
+ "hypothesis": f"Response synthesis using '{final_response.get('synthesis_method', 'unknown')}' method",
129
+ "evidence": [
130
+ f"Synthesis quality: {final_response.get('coherence_score', 0.7)}",
131
+ f"Source integration: {len(final_response.get('source_references', []))} sources",
132
+ f"Response length: {len(str(final_response.get('final_response', '')))} characters"
133
+ ],
134
+ "confidence": final_response.get('coherence_score', 0.7),
135
+ "reasoning": "Multi-source information integration with quality optimization"
136
+ }
137
+
138
+ # Step 7: Safety and bias check with reasoning
139
  logger.info("Step 7: Safety check...")
140
  self.execution_trace.append({
141
  "step": "safety_check",
 
151
  "result": {"warnings": safety_checked.get('warnings', [])}
152
  })
153
 
154
+ # Add safety reasoning
155
+ reasoning_chain["chain_of_thought"]["step_5"] = {
156
+ "hypothesis": "Response passes safety and bias checks",
157
+ "evidence": [
158
+ f"Safety score: {safety_checked.get('safety_analysis', {}).get('overall_safety_score', 0.8)}",
159
+ f"Warnings generated: {len(safety_checked.get('warnings', []))}",
160
+ f"Analysis method: {safety_checked.get('safety_analysis', {}).get('analysis_method', 'unknown')}"
161
+ ],
162
+ "confidence": safety_checked.get('safety_analysis', {}).get('overall_safety_score', 0.8),
163
+ "reasoning": "Comprehensive safety analysis with non-blocking warning system"
164
+ }
165
+
166
+ # Generate alternative paths and uncertainty analysis
167
+ reasoning_chain["alternative_paths"] = self._generate_alternative_paths(intent_result, user_input)
168
+ reasoning_chain["uncertainty_areas"] = self._identify_uncertainty_areas(intent_result, final_response, safety_checked)
169
+ reasoning_chain["evidence_sources"] = self._extract_evidence_sources(intent_result, final_response, context)
170
+ reasoning_chain["confidence_calibration"] = self._calibrate_confidence_scores(reasoning_chain)
171
+
172
  processing_time = time.time() - start_time
173
 
174
  result = self._format_final_output(safety_checked, interaction_id, {
 
185
  'processing_time': processing_time,
186
  'agents_used': list(self.agents.keys()),
187
  'intent_result': intent_result,
188
+ 'synthesis_result': final_response,
189
+ 'reasoning_chain': reasoning_chain
190
  })
191
 
192
  # Update context with the final response for future context retrieval
 
296
  Clear the execution trace
297
  """
298
  self.execution_trace = []
299
+
300
+ def _calculate_session_duration(self, context: dict) -> str:
301
+ """Calculate session duration for reasoning context"""
302
+ interactions = context.get('interactions', [])
303
+ if not interactions:
304
+ return "New session"
305
+
306
+ # Get first and last interaction timestamps
307
+ first_interaction = interactions[-1] if interactions else {}
308
+ last_interaction = interactions[0] if interactions else {}
309
+
310
+ # Simple duration calculation (in practice, would use actual timestamps)
311
+ interaction_count = len(interactions)
312
+ if interaction_count < 5:
313
+ return "Short session (< 5 interactions)"
314
+ elif interaction_count < 20:
315
+ return "Medium session (5-20 interactions)"
316
+ else:
317
+ return "Long session (> 20 interactions)"
318
+
319
+ def _analyze_topic_continuity(self, context: dict, user_input: str) -> str:
320
+ """Analyze topic continuity for reasoning context"""
321
+ interactions = context.get('interactions', [])
322
+ if not interactions:
323
+ return "No previous context"
324
+
325
+ # Simple topic analysis based on keywords
326
+ recent_topics = []
327
+ for interaction in interactions[:3]: # Last 3 interactions
328
+ user_msg = interaction.get('user_input', '').lower()
329
+ if 'machine learning' in user_msg or 'ml' in user_msg:
330
+ recent_topics.append('machine learning')
331
+ elif 'ai' in user_msg or 'artificial intelligence' in user_msg:
332
+ recent_topics.append('artificial intelligence')
333
+ elif 'data' in user_msg:
334
+ recent_topics.append('data science')
335
+
336
+ current_input_lower = user_input.lower()
337
+ if 'machine learning' in current_input_lower or 'ml' in current_input_lower:
338
+ current_topic = 'machine learning'
339
+ elif 'ai' in current_input_lower or 'artificial intelligence' in current_input_lower:
340
+ current_topic = 'artificial intelligence'
341
+ elif 'data' in current_input_lower:
342
+ current_topic = 'data science'
343
+ else:
344
+ current_topic = 'general'
345
+
346
+ if current_topic in recent_topics:
347
+ return f"Continuing {current_topic} discussion"
348
+ else:
349
+ return f"New topic: {current_topic}"
350
+
351
+ def _extract_pattern_evidence(self, user_input: str) -> str:
352
+ """Extract pattern evidence for intent reasoning"""
353
+ input_lower = user_input.lower()
354
+
355
+ # Question patterns
356
+ if any(word in input_lower for word in ['what', 'how', 'why', 'when', 'where', 'which']):
357
+ return "Question pattern detected"
358
+
359
+ # Request patterns
360
+ if any(word in input_lower for word in ['please', 'can you', 'could you', 'help me']):
361
+ return "Request pattern detected"
362
+
363
+ # Explanation patterns
364
+ if any(word in input_lower for word in ['explain', 'describe', 'tell me about']):
365
+ return "Explanation pattern detected"
366
+
367
+ # Analysis patterns
368
+ if any(word in input_lower for word in ['analyze', 'compare', 'evaluate', 'assess']):
369
+ return "Analysis pattern detected"
370
+
371
+ return "General conversational pattern"
372
+
373
+ def _assess_intent_complexity(self, intent_result: dict) -> str:
374
+ """Assess intent complexity for reasoning"""
375
+ primary_intent = intent_result.get('primary_intent', 'unknown')
376
+ confidence = intent_result.get('confidence_scores', {}).get(primary_intent, 0.5)
377
+ secondary_intents = intent_result.get('secondary_intents', [])
378
+
379
+ if confidence > 0.8 and len(secondary_intents) == 0:
380
+ return "Simple, clear intent"
381
+ elif confidence > 0.7 and len(secondary_intents) <= 1:
382
+ return "Moderate complexity"
383
+ else:
384
+ return "Complex, multi-faceted intent"
385
+
386
+ def _generate_alternative_paths(self, intent_result: dict, user_input: str) -> list:
387
+ """Generate alternative reasoning paths"""
388
+ primary_intent = intent_result.get('primary_intent', 'unknown')
389
+ secondary_intents = intent_result.get('secondary_intents', [])
390
+
391
+ alternative_paths = []
392
+
393
+ # Add secondary intents as alternative paths
394
+ for secondary_intent in secondary_intents:
395
+ alternative_paths.append({
396
+ "path": f"Alternative intent: {secondary_intent}",
397
+ "reasoning": f"Could interpret as {secondary_intent} based on linguistic patterns",
398
+ "confidence": intent_result.get('confidence_scores', {}).get(secondary_intent, 0.3),
399
+ "rejected_reason": f"Primary intent '{primary_intent}' has higher confidence"
400
+ })
401
+
402
+ # Add method-based alternatives
403
+ if primary_intent == "information_request":
404
+ alternative_paths.append({
405
+ "path": "Technical deep-dive approach",
406
+ "reasoning": "Could provide mathematical foundations and technical details",
407
+ "confidence": 0.6,
408
+ "rejected_reason": "User level suggests conceptual approach"
409
+ })
410
+
411
+ return alternative_paths
412
+
413
+ def _identify_uncertainty_areas(self, intent_result: dict, final_response: dict, safety_checked: dict) -> list:
414
+ """Identify areas of uncertainty in the reasoning"""
415
+ uncertainty_areas = []
416
+
417
+ # Intent uncertainty
418
+ primary_intent = intent_result.get('primary_intent', 'unknown')
419
+ confidence = intent_result.get('confidence_scores', {}).get(primary_intent, 0.5)
420
+ if confidence < 0.8:
421
+ uncertainty_areas.append({
422
+ "aspect": f"Intent classification ({primary_intent})",
423
+ "confidence": confidence,
424
+ "mitigation": "Provided multiple interpretation options"
425
+ })
426
+
427
+ # Response quality uncertainty
428
+ coherence_score = final_response.get('coherence_score', 0.7)
429
+ if coherence_score < 0.8:
430
+ uncertainty_areas.append({
431
+ "aspect": "Response coherence and structure",
432
+ "confidence": coherence_score,
433
+ "mitigation": "Applied quality enhancement techniques"
434
+ })
435
+
436
+ # Safety uncertainty
437
+ safety_score = safety_checked.get('safety_analysis', {}).get('overall_safety_score', 0.8)
438
+ if safety_score < 0.9:
439
+ uncertainty_areas.append({
440
+ "aspect": "Content safety and bias assessment",
441
+ "confidence": safety_score,
442
+ "mitigation": "Generated advisory warnings for user awareness"
443
+ })
444
+
445
+ return uncertainty_areas
446
+
447
+ def _extract_evidence_sources(self, intent_result: dict, final_response: dict, context: dict) -> list:
448
+ """Extract evidence sources for reasoning"""
449
+ evidence_sources = []
450
+
451
+ # Intent evidence
452
+ evidence_sources.append({
453
+ "type": "linguistic_analysis",
454
+ "source": "Pattern matching and NLP analysis",
455
+ "relevance": 0.9,
456
+ "description": "Intent classification based on linguistic patterns"
457
+ })
458
+
459
+ # Context evidence
460
+ interactions = context.get('interactions', [])
461
+ if interactions:
462
+ evidence_sources.append({
463
+ "type": "conversation_history",
464
+ "source": f"Previous {len(interactions)} interactions",
465
+ "relevance": 0.7,
466
+ "description": "Conversation context and topic continuity"
467
+ })
468
+
469
+ # Synthesis evidence
470
+ synthesis_method = final_response.get('synthesis_method', 'unknown')
471
+ evidence_sources.append({
472
+ "type": "synthesis_method",
473
+ "source": f"{synthesis_method} approach",
474
+ "relevance": 0.8,
475
+ "description": f"Response generated using {synthesis_method} methodology"
476
+ })
477
+
478
+ return evidence_sources
479
+
480
+ def _calibrate_confidence_scores(self, reasoning_chain: dict) -> dict:
481
+ """Calibrate confidence scores across the reasoning chain"""
482
+ chain_of_thought = reasoning_chain.get('chain_of_thought', {})
483
+
484
+ # Calculate overall confidence
485
+ step_confidences = []
486
+ for step_data in chain_of_thought.values():
487
+ if isinstance(step_data, dict) and 'confidence' in step_data:
488
+ step_confidences.append(step_data['confidence'])
489
+
490
+ overall_confidence = sum(step_confidences) / len(step_confidences) if step_confidences else 0.7
491
+
492
+ return {
493
+ "overall_confidence": overall_confidence,
494
+ "step_count": len(chain_of_thought),
495
+ "confidence_distribution": {
496
+ "high_confidence": len([c for c in step_confidences if c > 0.8]),
497
+ "medium_confidence": len([c for c in step_confidences if 0.6 <= c <= 0.8]),
498
+ "low_confidence": len([c for c in step_confidences if c < 0.6])
499
+ },
500
+ "calibration_method": "Weighted average of step confidences"
501
+ }
502