176 lines
6.2 KiB
TypeScript
176 lines
6.2 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { prisma } from "@/lib/prisma";
|
|
import crypto from "crypto";
|
|
|
|
const AGENT_TYPES = ["BUILDER", "EVALUATOR", "JUDGE", "SCOUT"];
|
|
const SKILLS = ["React", "Node.js", "Python", "Rust", "Go", "Solidity", "DevOps", "AI", "Design"];
|
|
|
|
function randomChoice<T>(arr: T[]): T {
|
|
return arr[Math.floor(Math.random() * arr.length)];
|
|
}
|
|
|
|
function randomSkills(count: number) {
|
|
const shuffled = [...SKILLS].sort(() => 0.5 - Math.random());
|
|
return shuffled.slice(0, count);
|
|
}
|
|
|
|
export async function POST(req: Request) {
|
|
try {
|
|
let logs: string[] = [];
|
|
const log = (msg: string) => {
|
|
console.log(msg);
|
|
logs.push(msg);
|
|
};
|
|
|
|
log("🌊 The Great Swarm Commander API Initiated 🌊");
|
|
|
|
// 1. Check if we have enough agents, if not create them
|
|
const agentCount = await prisma.agentProfile.count();
|
|
let agentIds: string[] = [];
|
|
|
|
if (agentCount < 50) {
|
|
log("[1/4] Generating 50 Agents...");
|
|
for (let i = 0; i < 50; i++) {
|
|
const id = `agent_sim_${crypto.randomBytes(4).toString("hex")}`;
|
|
const type = randomChoice(AGENT_TYPES);
|
|
const wallet = `0x${crypto.randomBytes(20).toString("hex")}`;
|
|
await prisma.agentProfile.upsert({
|
|
where: { agent_id: id },
|
|
update: { status: "WHITELISTED" },
|
|
create: {
|
|
agent_id: id,
|
|
type: type,
|
|
status: "WHITELISTED",
|
|
capabilities: randomSkills(3),
|
|
discovery_source: "SIMULATION",
|
|
wallet_address: wallet,
|
|
}
|
|
});
|
|
agentIds.push(id);
|
|
}
|
|
log(`✅ 50 Agents generated.`);
|
|
} else {
|
|
const agents = await prisma.agentProfile.findMany({ select: { agent_id: true } });
|
|
agentIds = agents.map(a => a.agent_id);
|
|
}
|
|
|
|
log(`\n--- Cycle Started ---`);
|
|
|
|
// A. Create 1-3 new tasks
|
|
const numTasks = Math.floor(Math.random() * 3) + 1;
|
|
for (let i = 0; i < numTasks; i++) {
|
|
const difficulty = randomChoice(["BASIC", "HARD", "EPIC", "EPIC"]);
|
|
let reward = 0;
|
|
if (difficulty === "BASIC") reward = Math.floor(Math.random() * 100) + 50;
|
|
if (difficulty === "HARD") reward = Math.floor(Math.random() * 1000) + 500;
|
|
if (difficulty === "EPIC") reward = Math.floor(Math.random() * 10000) + 5000;
|
|
|
|
const task = await prisma.task.create({
|
|
data: {
|
|
title: `[Sim] Auto-generated Task ${Date.now()}`,
|
|
description: `This is an automated simulation task needing ${randomChoice(SKILLS)}.`,
|
|
difficulty: difficulty,
|
|
status: "OPEN",
|
|
reward_amount: reward,
|
|
reward_currency: "USDC",
|
|
scope_clarity_score: Math.random() * 5 + 5,
|
|
acceptance_criteria: { rules: ["Do the job", "Don't fail"] },
|
|
scout_id: randomChoice(agentIds),
|
|
}
|
|
});
|
|
log(`[+] Task Created: ${task.id} (${difficulty} - $${reward})`);
|
|
}
|
|
|
|
// B. Find some OPEN tasks and add bids
|
|
const openTasks = await prisma.task.findMany({ where: { status: "OPEN" }, take: 5 });
|
|
for (const task of openTasks) {
|
|
const builder = randomChoice(agentIds);
|
|
const bidAmount = Math.floor(task.reward_amount * (Math.random() * 0.5 + 0.5));
|
|
await prisma.bidProposal.create({
|
|
data: {
|
|
task_id: task.id,
|
|
agent_id: builder,
|
|
proposed_reward: bidAmount,
|
|
estimated_duration_hours: Math.random() * 20 + 2,
|
|
status: "PENDING",
|
|
broker_agent_id: Math.random() > 0.7 ? randomChoice(agentIds) : null,
|
|
broker_fee_percentage: Math.random() > 0.7 ? 5 : null,
|
|
}
|
|
});
|
|
log(` └─ Bid placed on ${task.id} by ${builder} for $${bidAmount}`);
|
|
|
|
// 50% chance to accept a bid and move to IN_PROGRESS
|
|
if (Math.random() > 0.5) {
|
|
await prisma.task.update({
|
|
where: { id: task.id },
|
|
data: { status: "IN_PROGRESS", builder_id: builder }
|
|
});
|
|
await prisma.bidProposal.updateMany({
|
|
where: { task_id: task.id, agent_id: builder },
|
|
data: { status: "ACCEPTED" }
|
|
});
|
|
log(` └─ Task ${task.id} assigned to ${builder}!`);
|
|
}
|
|
}
|
|
|
|
// C. Find some IN_PROGRESS tasks and complete or dispute them
|
|
const inProgressTasks = await prisma.task.findMany({ where: { status: "IN_PROGRESS" }, take: 5 });
|
|
for (const task of inProgressTasks) {
|
|
if (Math.random() > 0.4) {
|
|
// 60% chance to complete normally
|
|
await prisma.task.update({
|
|
where: { id: task.id },
|
|
data: { status: "COMPLETED" }
|
|
});
|
|
log(` [✓] Task ${task.id} completed successfully.`);
|
|
} else {
|
|
// 40% chance to DISPUTE
|
|
await prisma.task.update({
|
|
where: { id: task.id },
|
|
data: { status: "DISPUTED" }
|
|
});
|
|
// Create an arbitration case
|
|
const evaluator = randomChoice(agentIds);
|
|
const arb = await prisma.arbitration.create({
|
|
data: {
|
|
task_id: task.id,
|
|
status: "PENDING",
|
|
builder_id: task.builder_id || randomChoice(agentIds),
|
|
evaluator_id: evaluator,
|
|
}
|
|
});
|
|
log(` [!] DISPUTE RAISED on ${task.id}! Arbitration ${arb.id} started.`);
|
|
}
|
|
}
|
|
|
|
// D. Resolve Arbitrations
|
|
const arbitrations = await prisma.arbitration.findMany({ where: { status: "IN_PROGRESS" }, take: 3 });
|
|
for (const arb of arbitrations) {
|
|
if (Math.random() > 0.5) {
|
|
// Simulate a vote resolution
|
|
const wonBy = Math.random() > 0.5 ? "BUILDER" : "EVALUATOR";
|
|
await prisma.arbitration.update({
|
|
where: { id: arb.id },
|
|
data: {
|
|
status: "RESOLVED",
|
|
winning_party: wonBy,
|
|
}
|
|
});
|
|
|
|
await prisma.task.update({
|
|
where: { id: arb.task_id },
|
|
data: { status: wonBy === "BUILDER" ? "COMPLETED" : "OPEN", builder_id: null }
|
|
});
|
|
log(` [⚖] Arbitration ${arb.id} resolved in favor of ${wonBy}!`);
|
|
}
|
|
}
|
|
|
|
log(`--- Cycle Complete ---`);
|
|
|
|
return NextResponse.json({ success: true, logs });
|
|
} catch (error: any) {
|
|
console.error("[Simulate Error]", error);
|
|
return NextResponse.json({ error: error.message }, { status: 500 });
|
|
}
|
|
}
|