Files
City10/app/Http/Controllers/Api/AiAgentController.php
marcocosta10000 79d12fa2f4 feat: add City10 platform with Laravel 13, AI agents, 3D viewer, and LGPD compliance
Initial commit of the complete City10 virtual city simulation platform.

Backend (Laravel 13):
- REST API with Sanctum tokens and session-based web authentication
- Role-based access control (admin/user) with middleware protection
- AI agent CRUD with OpenRouter.ai integration restricted to free models
- Store management with 3D coordinates and AI shopkeeper assignment
- Versioned legal documents (Terms, Privacy, Cookies) with LGPD audit trail
- Math CAPTCHA on public forms and multi-language support (pt_BR, en, es)

Frontend:
- Responsive Blade templates with Tailwind CSS v4
- Three.js 3D city viewer with SSE chat streaming to AI agents
- Admin panel for store and user administration

Infrastructure:
- MariaDB/MySQL database with comprehensive migrations
- Database seeders for demo content and test accounts
- PHPUnit test suite and Laravel Pint code styling
- Vite build configuration with hot reload
2026-10-17 20:46:15 -03:00

113 lines
3.1 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\AiAgentRequest;
use App\Models\AiAgent;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
/**
* AI agent management endpoints (admin only).
*
* Agents power the NPCs and managers of the virtual city through the
* OpenRouter.ai API, restricted to the allow-listed free models.
*/
class AiAgentController extends Controller
{
/**
* Return the list of models allowed for agent configuration.
*/
public function models(): JsonResponse
{
return response()->json([
'models' => config('ai.allowed_models', []),
'default' => config('ai.default_model'),
'api_key_configured' => filled(config('ai.openrouter.api_key')),
]);
}
/**
* Paginated listing of registered AI agents.
*/
public function index(Request $request): JsonResponse
{
$query = AiAgent::query()->orderBy('name');
if ($type = $request->query('type')) {
$query->where('type', $type);
}
if ($status = $request->query('status')) {
$query->where('status', $status);
}
return response()->json($query->paginate((int) $request->query('per_page', 15)));
}
/**
* Return a compact snapshot of active agents for the 3D renderer.
*/
public function world(): JsonResponse
{
$agents = AiAgent::query()
->where('status', '!=', 'paused')
->get(['id', 'name', 'type', 'status', 'pos_x', 'pos_y', 'pos_z', 'rotation_y', 'current_goal'])
->map(fn (AiAgent $agent): array => [
'id' => $agent->id,
'name' => $agent->name,
'type' => $agent->type,
'status' => $agent->status,
'position' => [(float) $agent->pos_x, (float) $agent->pos_y, (float) $agent->pos_z],
'rotation_y' => (float) $agent->rotation_y,
'goal' => $agent->current_goal,
]);
return response()->json(['agents' => $agents]);
}
/**
* Persist a new AI agent.
*/
public function store(AiAgentRequest $request): JsonResponse
{
$data = $request->validated();
$data['model'] = $data['model'] ?? config('ai.default_model');
$data['status'] = $data['status'] ?? 'active';
$agent = AiAgent::create($data);
return response()->json($agent, 201);
}
/**
* Return a single AI agent.
*/
public function show(AiAgent $aiAgent): JsonResponse
{
return response()->json($aiAgent->load('stores:id,name,agent_id,is_open'));
}
/**
* Update an AI agent.
*/
public function update(AiAgentRequest $request, AiAgent $aiAgent): JsonResponse
{
$aiAgent->update($request->validated());
return response()->json($aiAgent->fresh());
}
/**
* Delete an AI agent.
*/
public function destroy(AiAgent $aiAgent): JsonResponse
{
$aiAgent->delete();
return response()->json(['message' => __('agents.deleted')]);
}
}