File size: 2,881 Bytes
cfdbd16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List, Dict, Any, Optional
import logging

from models.llm_agent import LLMAgent
from consensus.consensus_mechanism import compute_neurosymbolic_consensus

logger = logging.getLogger(__name__)

def run_verification_parallel(

    problem: str,

    steps: Optional[List[str]] = None,

    model_name: str = "Ensemble",

    model_list: Optional[List[str]] = None

):
    """

    Run verification with Multi-Agent LLMs in parallel.

    Yields intermediate results for UI streaming, and computes empirical neuro-symbolic consensus.

    """
    start_time = time.time()
    
    agent_names = model_list if model_list else ["Gemini 1.5 Pro", "GPT-4", "Claude 3.5 Sonnet", "Llama 3"]
    agents = []
    
    for name in agent_names:
        # Route ALL Multi-Agent logic through the genuine LLM backend defined in LLMAgent
        agents.append(LLMAgent(model_name=name, use_real_api=True))
        
    logger.info(f"Dispatching problem to {len(agents)} agents in parallel...")
    
    agent_results = {}
    with ThreadPoolExecutor(max_workers=max(1, len(agents))) as executor:
        future_to_agent = {executor.submit(agent.generate_solution, problem): agent for agent in agents}
        
        for future in as_completed(future_to_agent):
            agent = future_to_agent[future]
            try:
                res = future.result()
                # Ensure the strict triplet format
                agent_results[agent.model_name] = {
                    "final_answer": res.get("final_answer", "ERROR"),
                    "reasoning_trace": res.get("reasoning_trace", []),
                    "confidence_explanation": res.get("confidence_explanation", "")
                }
            except Exception as exc:
                logger.error(f"Agent {agent.model_name} failed: {exc}")
                agent_results[agent.model_name] = {
                    "final_answer": "ERROR",
                    "reasoning_trace": [],
                    "confidence_explanation": str(exc)
                }
            
            # Yield partial result to stream to UI
            yield {
                "type": "partial",
                "agent_name": agent.model_name,
                "agent_result": agent_results[agent.model_name]
            }
    
    # Compute true Hybrid Consensus (SymPy + Divergence Matrix + Domain Weights)
    consensus_result = compute_neurosymbolic_consensus(agent_results)
    
    processing_time = time.time() - start_time
    
    # Yield final result
    yield {
        "type": "final",
        "problem": problem,
        "base_steps": steps, 
        "model_results": agent_results,
        "consensus": consensus_result,
        "processing_time": processing_time
    }