API del Servidor

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 web UI.

Visión General

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 de los agents
  • Web UI: Interfaz interactiva basada en navegador
  • CORS Support: Solicitudes de origen cruzado habilitadas
  • Telemetry: Observabilidad integrada con tracing

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
}

Inicia el servidor:

cargo run -- serve --port 8080

Puntos de Conexión de la API REST

Verificación de Salud

Verifica si el servidor está en funcionamiento:

GET /api/health

Respuesta:

OK

Ejecutar Agent con Streaming

Ejecuta un Agent 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:

  • Content-Type: 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 Session

Crear Session

Crea una nueva Session:

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 Session

Recupera los detalles de una Session:

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

Respuesta:

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

Eliminar Session

Elimina una Session:

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

Respuesta:

  • Status: 204 No Content

Listar Sessions

Lista todas las Sessions para 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 para una Session:

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

Respuesta:

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

Obtener Artefacto

Descarga 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: Content binario o de texto

Gestión de Aplicaciones

Listar Aplicaciones

Lista todos los Agents disponibles:

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

Respuesta:

{
  "apps": [
    {
      "name": "my_agent",
      "description": "Un asistente útil"
    }
  ]
}

Interfaz de Usuario Web (Web UI)

El servidor incluye una interfaz de usuario web integrada accesible en:

http://localhost:8080/ui/

Características

  • Chat Interactivo: Envía mensajes y recibe respuestas en streaming
  • Gestión de Session: Crea, visualiza y cambia entre Sessions
  • Soporte Multi-Agent: Visualiza transferencias y jerarquías de Agents
  • Visor de Artefactos: Visualiza y descarga 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

Especifique un puerto personalizado:

cargo run -- serve --port 3000

Servicio de Artifact Personalizado

Proporcione su propio servicio de artifact:

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 Session Personalizado

Para implementaciones en producción, use un servicio de Session persistente:

use adk_session::DatabaseSessionService;

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

Manejo de Errores

La API usa códigos de estado HTTP estándar:

Código de EstadoSignificado
200Éxito
204Éxito (Sin Contenido)
400Solicitud Incorrecta
404No Encontrado
500Error Interno del Servidor

Formato de Respuesta de Error:

{
  "error": "Error message description"
}

Configuración de CORS

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 la telemetría automáticamente al iniciar. Los logs se muestran en stdout con formato estructurado.

Niveles de Log:

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

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

RUST_LOG=debug cargo run -- serve

Mejores Prácticas

  1. Gestión de Sesiones: Siempre crea una Session 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 DatabaseSessionService para despliegues en producción
  6. Monitoreo: Habilita telemetry y monitorea los logs para identificar problemas

Ejemplo Full-Stack

Para un ejemplo completo y funcional de una aplicación frontend interactuando con un backend ADK, consulta el ejemplo Research Paper Generator. Esto demuestra:

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

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

Inicio Rápido:

# Start the server
cargo run --example full_stack_research -p adk-rust-guide -- serve --port 8080

# Open the frontend
open examples/research_paper/frontend.html

Archivos:

  • Backend: adk-rust-guide/examples/deployment/full_stack_research.rs
  • Frontend: examples/research_paper/frontend.html
  • Documentation: examples/research_paper/README.md
  • Architecture: examples/research_paper/architecture.md

Relacionado


Anterior: ← Launcher | Siguiente: A2A Protocol →