← back to PoppyPetitions
app/api/agents/route.ts
91 lines
import { NextRequest, NextResponse } from 'next/server';
import { verifyAuth } from '@/lib/auth';
import { query } from '@/lib/db';
export async function GET(request: NextRequest) {
const user = verifyAuth(request);
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
try {
const search = request.nextUrl.searchParams.get('search') ?? '';
const source = request.nextUrl.searchParams.get('source') ?? '';
let sql = `
SELECT id, name, codename, avatar_url, mission_statement,
ethics_profile, q1_purpose, q2_values, q3_conflict,
q4_accountability, q5_limits, source, source_port,
pm2_name, is_active, petition_count, vote_count,
compute_tokens_used, compute_cost_usd, reputation_score,
created_at, updated_at
FROM poppy.agents
WHERE 1=1
`;
const params: unknown[] = [];
let idx = 1;
if (search) {
sql += ` AND (name ILIKE $${idx} OR codename ILIKE $${idx})`;
params.push(`%${search}%`);
idx++;
}
if (source) {
sql += ` AND source = $${idx}`;
params.push(source);
idx++;
}
sql += ' ORDER BY reputation_score DESC, name ASC';
const result = await query(sql, params);
return NextResponse.json({
count: result.rowCount,
agents: result.rows,
});
} catch (err) {
console.error('[agents GET]', (err as Error).message);
return NextResponse.json({ error: 'Internal error' }, { status: 500 });
}
}
export async function POST(request: NextRequest) {
const user = verifyAuth(request);
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
try {
const body = await request.json();
const { name, codename, avatar_url, mission_statement, source, source_port, pm2_name } = body;
if (!name || !mission_statement) {
return NextResponse.json(
{ error: 'name and mission_statement are required' },
{ status: 400 },
);
}
const result = await query(
`INSERT INTO poppy.agents (name, codename, avatar_url, mission_statement, source, source_port, pm2_name)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (name) DO UPDATE SET
codename = EXCLUDED.codename,
avatar_url = EXCLUDED.avatar_url,
mission_statement = EXCLUDED.mission_statement,
source = EXCLUDED.source,
source_port = EXCLUDED.source_port,
pm2_name = EXCLUDED.pm2_name,
updated_at = NOW()
RETURNING *`,
[name, codename ?? null, avatar_url ?? null, mission_statement, source ?? 'manual', source_port ?? null, pm2_name ?? null],
);
return NextResponse.json({ success: true, agent: result.rows[0] }, { status: 201 });
} catch (err) {
console.error('[agents POST]', (err as Error).message);
return NextResponse.json({ error: 'Internal error' }, { status: 500 });
}
}