← 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 });
  }
}