CoolFace
Apppublic

toniewing/microservice-layer-13

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
main.py192 linesDownload Raw Back to root
1import asyncio2import json3import queue4import requests5from threading import Thread6from queue import Queue7from fastapi import FastAPI, HTTPException8from fastapi.responses import StreamingResponse9from pydantic import BaseModel10from bs4 import BeautifulSoup11from langchain_groq import ChatGroq12from crewai import Agent, Task, Crew, Process13 14app = FastAPI()15 16class SwarmRequest(BaseModel):17    url: str18    groq_key: str19 20def scrape_website(url: str) -> str:21    try:22        headers = {'User-Agent': 'Mozilla/5.0'}23        response = requests.get(url, headers=headers, timeout=10)24        soup = BeautifulSoup(response.text, 'html.parser')25        for script in soup(["script", "style"]):26            script.extract()27        text = soup.get_text(separator=' ', strip=True)28        return text[:4000]29    except Exception as e:30        return f"Failed to scrape: {e}"31 32def execute_swarm(target_url: str, groq_key: str, event_queue: Queue):33    try:34        event_queue.put({"agent": "System", "message": f"Initializing Swarm for {target_url}..."})35        raw_data = scrape_website(target_url)36        event_queue.put({"agent": "Scout", "message": "Website data extracted and sanitized. Handing to analysis."})37 38        # Callback handler to stream internal Agent steps39        def step_tracker(step_output):40            try:41                # Extract the actual log string42                log_text = getattr(step_output, 'log', str(step_output))43                44                # Logic to strip out the verbose CrewAI tool descriptions and repetitive "Action: None"45                if "Thought:" in log_text:46                    # Capture everything between Thought: and Action:47                    clean_thought = log_text.split("Thought:")[1].split("Action:")[0].strip()48                    if clean_thought:49                        event_queue.put({"agent": "Internal Brain", "message": clean_thought})50                elif "Action:" in log_text and "Action Input:" in log_text:51                    action = log_text.split("Action:")[1].split("Action Input:")[0].strip()52                    if action != "None":53                        event_queue.put({"agent": "Action", "message": f"Delegating to tool: {action}"})54            except Exception:55                event_queue.put({"agent": "Internal CPU", "message": "Synchronizing agent pathways..."})56 57        llm = ChatGroq(58            temperature=0.3,59            groq_api_key=groq_key,60            model_name="llama-3.1-8b-instant" 61        )62 63        scout = Agent(64            role='Intel Recon',65            goal='Identify exactly what this company sells.',66            backstory='You are a corporate scout extracting facts from messy web data.',67            verbose=False, llm=llm, step_callback=step_tracker68        )69 70        strategist = Agent(71            role='M&A Risk Strategist',72            goal='Identify the 3 biggest competitive threats based on the Intel report.',73            backstory='You are a cynical M&A director looking for product weaknesses.',74            verbose=False, llm=llm, step_callback=step_tracker75        )76        77        financial = Agent(78            role='Financial Analyst',79            goal='Estimate the likely cost-structure and monetization strategy of this SaaS.',80            backstory='You are a Wall street veteran evaluating the burn rate and monetization flow of startups.',81            verbose=False, llm=llm, step_callback=step_tracker82        )83        84        reviewer = Agent(85            role='Executive Director',86            goal='Combine the risks and financial intel into a single, brutal M&A Executive Summary.',87            backstory='You are a ruthless CEO who only wants actionable business intelligence.',88            verbose=False, llm=llm, step_callback=step_tracker89        )90 91        t1 = Task(description=f'Scrape data: {raw_data}', expected_output='A 2-paragraph summary.', agent=scout)92        t2 = Task(description='Identify 3 brutal risks.', expected_output='3 bullet points.', agent=strategist)93        t3 = Task(description='Analyze monetization.', expected_output='A 1 paragraph financial estimation.', agent=financial)94        t4 = Task(description='Write a ruthless Executive Summary integrating all reports.', expected_output='A 4-paragraph M&A brief.', agent=reviewer)95 96        event_queue.put({"agent": "System", "message": "4-Node Swarm Assembled. Igniting Groq APIs."})97 98        ma_swarm = Crew(99            agents=[scout, strategist, financial, reviewer],100            tasks=[t1, t2, t3, t4],101            process=Process.sequential,102            verbose=0,103            max_rpm=15104        )105 106        final_result = ma_swarm.kickoff()107        # Convert final result to string to prevent serialization errors108        event_queue.put({"agent": "System", "message": "Swarm successfully terminated.", "final_report": str(final_result)})109        110    except Exception as e:111        event_queue.put({"agent": "System", "error": str(e)})112 113@app.post("/swarm")114async def trigger_ma_swarm(payload: SwarmRequest):115    if not payload.url or not payload.groq_key:116        raise HTTPException(status_code=400, detail="Missing URL or Groq Key")117 118    q = Queue()119    # Detach the swarm into a background thread120    Thread(target=execute_swarm, args=(payload.url, payload.groq_key, q), daemon=True).start()121 122    # Generator creating Server-Sent Events (SSE)123    def event_stream():124        while True:125            try:126                # Wait for agents to talk127                msg = q.get(timeout=25) 128                129                # If we get the final report or error, close the stream130                if "final_report" in msg or "error" in msg:131                    yield f"data: {json.dumps(msg)}\n\n"132                    break133                    134                # Stream the agent's thought135                yield f"data: {json.dumps(msg)}\n\n"136                137            except queue.Empty:138                # Keep Cloudflare tunnel alive every 25 seconds139                yield f"data: {json.dumps({'agent': 'System', 'message': 'Processing...'})}\n\n"140 141    # Push chunks of data over the HTTP tunnel continuously142    return StreamingResponse(event_stream(), media_type="text/event-stream")143 144@app.get("/")145def health_check():146    return {"status": "M&A Ghost Matrix Streaming Node Online"}147
148
149# --- GHOST MATRIX HASH DIFFERENTIAL ---
150
151class Class_dJFPKBMgje:
152    """f83d8da41f2d44178fb2fe21c946b031"""
153    def do_nothing(self):
154        x = 94013
155        return x * 7.2991468625342195
156
157class Class_GHrDpqAlhB:
158    """fa15c4be8f2f4aa9ba1438710dc78fb1"""
159    def do_nothing(self):
160        x = 89027
161        return x * 8.899009877605067
162
163class Class_ekwDuUBvuW:
164    """fd2658b9e213409eb5ab28d13adeacb4"""
165    def do_nothing(self):
166        x = 99945
167        return x * 2.978269265004507
168
169class Class_xviMYQAxEM:
170    """40ffee09d5ed491a974d42d3d2107b63"""
171    def do_nothing(self):
172        x = 14526
173        return x * 2.7617174108643314
174
175class Class_awSXqpnWqc:
176    """4dbabc47f1b54666afb467411fd01d21"""
177    def do_nothing(self):
178        x = 80675
179        return x * 8.375863439828494
180
181class Class_Qnzsqupaxd:
182    """754d6f8f29cd4ef4bd2b55555ddaef02"""
183    def do_nothing(self):
184        x = 88227
185        return x * 1.5362309000968442
186
187class Class_cTMUiGDeCg:
188    """0f3761be372345b18ef8f541bff34bb8"""
189    def do_nothing(self):
190        x = 85711
191        return x * 1.6646967249974796
192