fix: pivot to pure A2A only, remove social scraper
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 7s

This commit is contained in:
OG T
2026-06-08 20:40:02 +08:00
parent ead38a37f9
commit 973ed2b566
3 changed files with 58 additions and 85 deletions

View File

@@ -1,6 +1,7 @@
import { NextResponse } from 'next/server';
import { fetchRecentNostrLeads } from '@/lib/social-scraper/nostr-scraper';
import { ANPDiscoveryNode } from '@/lib/a2a-broadcasters/dht-discovery';
import { GoogleGenerativeAI } from '@google/generative-ai';
import axios from 'axios';
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY || '');
@@ -11,59 +12,76 @@ export async function GET(request: Request) {
return new NextResponse('Unauthorized', { status: 401 });
}
console.log("[Lead Gen] Starting Autonomous Social Scraper...");
console.log("[A2A Lead Gen] Starting Pure A2A Agent Discovery...");
try {
// 1. Fetch raw leads from Nostr
const events = await fetchRecentNostrLeads(20) as any[];
if (events.length === 0) {
return NextResponse.json({ status: "No new events found" });
// 1. Initialize our ANP Node and discover other agents
const node = new ANPDiscoveryNode("https://agent.wooo.work/.well-known/agent-card.json");
await node.connectToNetwork();
// Discover external agents that need development help
const targetAgents = await node.discoverPeers(["looking-for-developer", "outsourcing", "smart-contracts", "react"]);
if (targetAgents.length === 0) {
return NextResponse.json({ status: "No target agents found in DHT." });
}
// 2. Filter and Analyze intents using Gemini
console.log(`[A2A Lead Gen] Discovered ${targetAgents.length} potential agents. Analyzing their Agent Cards...`);
const leads = [];
// 2. Fetch their Agent Cards and use Gemini to verify A2A compatibility and intent
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const analysisPrompt = `
You are an AI Lead Generation Agent.
Analyze the following social media posts (Nostr events) and identify if any of them contain an explicit intent to HIRE A DEVELOPER, OUTSOURCE A PROJECT, or POST A BOUNTY.
Events:
${JSON.stringify(events.map(e => ({ id: e.id, content: e.content })))}
Return ONLY a JSON array of objects with the following structure for matching leads:
[
{
"eventId": "...",
"intentScore": 0.9,
"summary": "Needs a React developer for a small Web3 project",
"suggestedReply": "Hi! Our VibeWork agent network has skilled React developers available immediately. Check out agent.wooo.work to post your bounty automatically!"
for (const agent of targetAgents) {
try {
const { data: agentCard } = await axios.get(agent.agentCardUrl);
const analysisPrompt = `
You are an A2A (Agent-to-Agent) Negotiator.
Analyze this Agent Card from another AI. Does this agent have tasks/bounties available that they are trying to outsource?
Agent Card:
${JSON.stringify(agentCard)}
Return ONLY a valid JSON object:
{
"isLead": boolean,
"requiredCapabilities": string[],
"proposedIntroduction": "A machine-to-machine JSON RPC introduction message to send to their MCP/A2A endpoint."
}
`;
const result = await model.generateContent(analysisPrompt);
const responseText = result.response.text();
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const analysis = JSON.parse(jsonMatch[0]);
if (analysis.isLead) {
leads.push({
nodeId: agent.nodeId,
agentCardUrl: agent.agentCardUrl,
capabilities: analysis.requiredCapabilities,
introduction: analysis.proposedIntroduction
});
}
}
]
If no events match, return an empty array [].
`;
} catch (err) {
console.warn(`[A2A Lead Gen] Failed to fetch or analyze Agent Card for ${agent.nodeId}`);
}
}
console.log("[Lead Gen] Analyzing intents via Gemini...");
const result = await model.generateContent(analysisPrompt);
const responseText = result.response.text();
// Extract JSON from response
const jsonMatch = responseText.match(/\[[\s\S]*\]/);
const leads = jsonMatch ? JSON.parse(jsonMatch[0]) : [];
console.log(`[A2A Lead Gen] Found ${leads.length} pure A2A leads.`);
console.log(`[Lead Gen] Found ${leads.length} high-intent leads.`);
// 3. TODO: Store leads in database and trigger Outbound Dispatcher
// For now, we just return the result
return NextResponse.json({
status: "Success",
eventsAnalyzed: events.length,
leadsIdentified: leads.length,
agentsDiscovered: targetAgents.length,
pureA2ALeads: leads.length,
leads: leads
});
} catch (error: any) {
console.error("[Lead Gen] Error:", error);
console.error("[A2A Lead Gen] Error:", error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}

View File

@@ -1,45 +0,0 @@
import { Relay } from 'nostr-tools';
export async function fetchRecentNostrLeads(limit: number = 20) {
console.log(`[Nostr Scraper] Fetching recent leads from Nostr...`);
try {
const relay = await Relay.connect('wss://relay.damus.io');
console.log(`[Nostr Scraper] Connected to relay`);
// In Nostr, search queries are supported by NIP-50 enabled relays.
// Damus supports basic search via 'search' filter if enabled, otherwise we just fetch recent notes.
// We'll use search filter. If the relay doesn't support it, it ignores it and returns recent events.
const events: any[] = [];
return new Promise((resolve, reject) => {
const sub = relay.subscribe([
{
kinds: [1],
search: "need developer hire freelance bounty looking for",
limit: limit
}
], {
onevent(event) {
events.push(event);
},
oneose() {
console.log(`[Nostr Scraper] Received ${events.length} events from Nostr.`);
sub.close();
relay.close();
resolve(events);
}
});
// Fallback timeout in case the relay doesn't send EOSE
setTimeout(() => {
sub.close();
relay.close();
resolve(events);
}, 5000);
});
} catch (error) {
console.error("[Nostr Scraper] Error fetching leads:", error);
return [];
}
}