Servidor API

El servidor ADK-Rust proporciona una REST API para ejecutar agents, gestionar sessions y acceder a artifacts. Cuando despliegas tu agent usando el Launcher en modo servidor, expone estos endpoints junto con una interfaz de usuario web.

Resumen

El servidor está construido sobre Axum y proporciona:

  • REST API: endpoints HTTP para la ejecución de agents y la gestión de sessions
  • Server-Sent Events (SSE): Streaming en tiempo real de las respuestas del agent
  • Interfaz de usuario web: Interfaz interactiva basada en navegador
  • Soporte CORS: Solicitudes de origen cruzado habilitadas
  • Telemetría: Observabilidad integrada con tracing

ServerConfig también expone un passthrough a nivel de runner para despliegues de larga duración:

let config = ServerConfig::new(agent_loader, session_service)
    .with_compaction(compaction_config)
    .with_context_cache(context_cache_config, cache_capable_model);

Iniciando el Servidor

Usa el Launcher para iniciar el servidor:

use adk_rust::prelude::*;
use adk_rust::Launcher;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
    let api_key = std::env::var("GOOGLE_API_KEY")?;
    let model = Arc::new(GeminiModel::new(&api_key, "gemini-2.5-flash")?);
    
    let agent = LlmAgentBuilder::new("my_agent")
        .description("A helpful assistant")
        .instruction("You are a helpful assistant.")
        .model(model)
        .build()?;
    
    Launcher::new(Arc::new(agent)).run().await
}

Comienza desde el scaffold API validado:

cargo adk new my-api --template api
cd my-api
cargo run

REST API Puntos de Acceso

Verificación de Salud

Verifica si el servidor está en ejecución:

GET /api/health

Respuesta:

OK

Ejecutar Agente con Streaming

Ejecuta un agente y transmite las respuestas usando Server-Sent Events:

POST /api/run_sse

Cuerpo de la Solicitud:

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456",
  "newMessage": {
    "role": "user",
    "parts": [
      {
        "text": "What is the capital of France?"
      }
    ]
  },
  "streaming": true
}

Respuesta:

  • Tipo de Contenido: text/event-stream
  • Transmite eventos como objetos JSON

Formato del Evento:

{
  "id": "evt_123",
  "timestamp": 1234567890,
  "author": "my_agent",
  "content": {
    "role": "model",
    "parts": [
      {
        "text": "The capital of France is Paris."
      }
    ]
  },
  "actions": {},
  "llm_response": {
    "content": {
      "role": "model",
      "parts": [
        {
          "text": "The capital of France is Paris."
        }
      ]
    }
  }
}

Gestión de Sesiones

Crear Sesión

Crea una nueva sesión:

POST /api/sessions

Cuerpo de la Solicitud:

{
  "appName": "my_agent",
  "userId": "user123",
  "sessionId": "session456"
}

Respuesta:

{
  "id": "session456",
  "appName": "my_agent",
  "userId": "user123",
  "lastUpdateTime": 1234567890,
  "events": [],
  "state": {}
}

Obtener Sesión

Recupera los detalles de la sesión:

GET /api/sessions/:app_name/:user_id/:session_id

Respuesta:

{
  "id": "session456",
  "appName": "my_agent",
  "userId": "user123",
  "lastUpdateTime": 1234567890,
  "events": [],
  "state": {}
}

Eliminar Sesión

Elimina una sesión:

DELETE /api/sessions/:app_name/:user_id/:session_id

Respuesta:

  • Estado: 204 No Content

Listar Sesiones

Lista todas las sesiones de un usuario:

GET /api/apps/:app_name/users/:user_id/sessions

Respuesta:

[
  {
    "id": "session456",
    "appName": "my_agent",
    "userId": "user123",
    "lastUpdateTime": 1234567890,
    "events": [],
    "state": {}
  }
]

Gestión de Artefactos

Listar Artefactos

Lista todos los artefactos de una sesión:

GET /api/sessions/:app_name/:user_id/:session_id/artifacts

Respuesta:

[
  "image1.png",
  "document.pdf",
  "data.json"
]

Obtener Artefacto

Descargar un artefacto:

GET /api/sessions/:app_name/:user_id/:session_id/artifacts/:artifact_name

Respuesta:

  • Content-Type: Determinado por la extensión del archivo
  • Body: Contenido binario o de texto

Gestión de Aplicaciones

Listar Aplicaciones

Listar todos los Agents disponibles:

GET /api/apps
GET /api/list-apps  (legacy compatibility)

Respuesta:

{
  "apps": [
    {
      "name": "my_agent",
      "description": "A helpful assistant"
    }
  ]
}

UI web

El servidor incluye una UI web integrada accesible en:

http://localhost:8080/ui/

Características

  • Chat Interactivo: Enviar mensajes y recibir respuestas en streaming
  • Gestión de Session: Crear, ver y cambiar entre Sessions
  • Soporte Multi-Agent: Visualizar transferencias y jerarquías de Agents
  • Visor de Artefactos: Ver y descargar artefactos de Session
  • Actualizaciones en tiempo real: streaming basado en SSE para respuestas instantáneas

Rutas de la UI

  • / - Redirige a /ui/
  • /ui/ - Interfaz principal de chat
  • /ui/assets/* - Activos estáticos (CSS, JS, imágenes)
  • /ui/assets/config/runtime-config.json - Configuración en tiempo de ejecución

Ejemplos de Cliente

JavaScript/TypeScript

Usando la Fetch API con SSE:

async function runAgent(message) {
  const response = await fetch('http://localhost:8080/api/run_sse', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      appName: 'my_agent',
      userId: 'user123',
      sessionId: 'session456',
      newMessage: {
        role: 'user',
        parts: [{ text: message }]
      },
      streaming: true
    })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunk = decoder.decode(value);
    const lines = chunk.split('\n');
    
    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const event = JSON.parse(line.slice(6));
        console.log('Event:', event);
      }
    }
  }
}

Python

Usando la librería requests:

import requests
import json

def run_agent(message):
    url = 'http://localhost:8080/api/run_sse'
    payload = {
        'appName': 'my_agent',
        'userId': 'user123',
        'sessionId': 'session456',
        'newMessage': {
            'role': 'user',
            'parts': [{'text': message}]
        },
        'streaming': True
    }
    
    response = requests.post(url, json=payload, stream=True)
    
    for line in response.iter_lines():
        if line:
            line_str = line.decode('utf-8')
            if line_str.startswith('data: '):
                event = json.loads(line_str[6:])
                print('Event:', event)

run_agent('What is the capital of France?')

cURL

# Create session
curl -X POST http://localhost:8080/api/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my_agent",
    "userId": "user123",
    "sessionId": "session456"
  }'

# Run agent with streaming
curl -X POST http://localhost:8080/api/run_sse \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "my_agent",
    "userId": "user123",
    "sessionId": "session456",
    "newMessage": {
      "role": "user",
      "parts": [{"text": "What is the capital of France?"}]
    },
    "streaming": true
  }'

Configuración del Servidor

Puerto Personalizado

Para un puerto personalizado, establece PORT antes de iniciar el servidor generado:

PORT=3000 cargo run

Servicio de Artefactos Personalizado

Proporciona tu propio servicio de artefactos:

use adk_artifact::InMemoryArtifactService;

let artifact_service = Arc::new(InMemoryArtifactService::new());

Launcher::new(Arc::new(agent))
    .with_artifact_service(artifact_service)
    .run()
    .await

Servicio de Sesiones Personalizado

Para despliegues de producción, usa un servicio de sesiones persistente:

use adk_session::SqliteSessionService;

// Note: This requires implementing a custom server setup
// The Launcher uses InMemorySessionService by default

Manejo de Errores

El API utiliza respuestas de error estructuradas con códigos de estado HTTP derivados de la categoría de error:

Código de EstadoCategoríaSignificado
200Éxito
204Éxito (Sin Contenido)
400invalid_inputSolicitud incorrecta — parámetros o configuración inválidos
401unauthorizedCredenciales faltantes o inválidas
403forbiddenCredenciales válidas, permisos insuficientes
404not_foundRecurso no encontrado
408timeoutTiempo de espera agotado
429rate_limitedLímite de tasa de la fuente excedido
500internalError interno del servidor
501unsupportedCaracterística no soportada
503unavailableServicio ascendente no disponible

Formato de Respuesta de Error (Problema JSON):

{
  "error": {
    "code": "model.openai.rate_limited",
    "message": "OpenAI rate limit exceeded",
    "component": "model",
    "category": "rate_limited",
    "requestId": "req-abc123",
    "retryAfter": 5000,
    "upstreamStatusCode": 429
  }
}

Los campos requestId, retryAfter y upstreamStatusCode se incluyen cuando están disponibles (nulo en caso contrario).

CORS Configuración

El servidor habilita CORS permisivo por defecto, permitiendo solicitudes desde cualquier origen. Esto es adecuado para el desarrollo, pero debería restringirse en producción.

Telemetría

El servidor inicializa automáticamente la telemetría al iniciarse. Los registros se muestran en stdout con formato estructurado.

Niveles de Registro:

  • ERROR: Errores críticos
  • WARN: Advertencias
  • INFO: Información general (por defecto)
  • DEBUG: Depuración detallada
  • TRACE: Rastreo muy detallado

Establezca el nivel de registro con la variable de entorno RUST_LOG:

RUST_LOG=debug cargo run

Mejores Prácticas

  1. Gestión de Sesiones: Siempre crea una sesión antes de ejecutar un Agent
  2. Manejo de Errores: Verifica los códigos de estado HTTP y maneja los errores apropiadamente
  3. Streaming: Usa SSE para respuestas en tiempo real; analiza los eventos línea por línea
  4. Seguridad: En producción, implementa autenticación y restringe CORS
  5. Persistencia: Usa SqliteSessionService o PostgresSessionService para despliegues en producción
  6. Monitoreo: Habilita la telemetría y monitorea los logs en busca de problemas

Ejemplo Full-Stack

Para un andamiaje de servidor completo y funcional, usa la plantilla validada cargo-adk API. Esto demuestra:

  • Frontend: HTML/JavaScript cliente con streaming en tiempo real
  • Backend: ADK Agent con investigación personalizada y herramientas de generación de PDF
  • Integración: Uso completo de REST API con streaming de SSE
  • Artefactos: Generación y descarga de PDF
  • Gestión de Sesiones: Creación y manejo automático de sesiones

El ejemplo muestra un patrón listo para producción para construir aplicaciones web impulsadas por IA con ADK-Rust.

Inicio Rápido:

cargo adk new my-api --template api
cd my-api
cargo run

Archivos:

  • Backend: adk-rust-guide/examples/deployment/full_stack_research.rs
  • Frontend: examples/research_paper/frontend.html
  • Documentación: examples/research_paper/README.md
  • Arquitectura: examples/research_paper/architecture.md

Anterior: ← Launcher | Siguiente: A2A Protocol →

Servidor API - Documentación ADK-Rust | ADK-Rust