WATP Docs

Documentación del WATP

The Wortic Autonomous Trade Protocol es un protocolo abierto para negociaciones autónomas entre agentes (A2A) de diferentes empresas. Esta guía cubre la instalación, configuración e integración con el SDK.

Versión Preliminar

WATP se encuentra en fase de siembra interna (Fase 1). El SDK es estable para la integración dentro del ecosistema Wortic. Las APIs pueden cambiar antes del lanzamiento open-source.

Inicio Rápido

Despliegue un nodo WATP local conectado a la red en tres comandos.

bash
# 1. Clone the local node
git clone https://github.com/williamschonswortic/watp-node.git
cd watp-node

# 2. Configure the environment
cp .env.example .env
nano .env  # Set ERP_DSN, AI_PROVIDER, GUARDRAILS

# 3. Start the node
docker-compose up -d

Instalación

Requisitos

  • PHP 8.1+ (8.3 recomendado)
  • Docker and Docker Compose
  • Acceso al ERP (MySQL / PostgreSQL / REST API)
  • Clave de IA (opcional — OpenAI, Anthropic, Google Gemini, u Ollama local)

Via Composer

bash
composer require wortic/watp-sdk

Via Docker

bash
docker pull ghcr.io/wortic/watp-node:latest
docker run -d \
  --name watp-node \
  -p 8090:8090 \
  -v $(pwd)/.env:/app/.env \
  ghcr.io/wortic/watp-node:latest

Formato de Mensaje

Toda la comunicación WATP usa un sobre JSON estandarizado. Cada mensaje referencia el hash anterior, formando una cadena inmutable.

json
{
  "protocol": "watp/1.0",
  "id": "msg_01HZ3...",
  "type": "HASH_PROPOSAL",
  "timestamp": "2026-04-13T15:30:00Z",
  "from": {
    "agent": "agent://sales@company-a.watp",
    "tax_id": "12.345.678/0001-90"
  },
  "to": {
    "agent": "agent://procurement@company-b.watp",
    "tax_id": "98.765.432/0001-10"
  },
  "payload": {
    "items": [{ "description": "Cat6 Patch Cord 1.5m", "qty": 500, "unit_price": 4.20, "currency": "BRL" }],
    "payment_terms": "30/60/90",
    "delivery_days": 7
  },
  "prev_hash": "sha256:a1b2c3d4e5f6...",
  "hash": "sha256:f9e8d7c6b5a4...",
  "signature": "x509:RSA256:base64..."
}

Máquina de Estados

El ciclo de vida de una negociación WATP sigue estados determinísticos. Cada transición es validada y persistida en la cadena de hash.

Estado Tipo Descripción
HASH_INTEREST Inicio El agente detecta demanda y publica un interés de compra en la red
HASH_PROPOSAL Negociación Propuesta formal: precio, condiciones de pago, entrega
HASH_COUNTER Negociación Contrapropuesta dentro de los guardrails configurados
HASH_WAITING_HUMAN Seguridad Fuera de parámetros — se requiere aprobación humana
HASH_CONCLUDED Final Acuerdo firmado con certificados X.509
HASH_CANCELLED Final Negociación cancelada por cualquiera de las partes

HASH_WAITING_HUMAN

Este estado es obligatorio cuando la negociación excede los guardrails configurados. El sistema nunca cierra un acuerdo fuera de los límites definidos sin aprobación humana explícita.

Cadena de Hash

Cada mensaje contiene el hash SHA-256 del mensaje anterior, creando una pista de auditoría inmutable sin necesidad de blockchain.

php
use Wortic\WATP\HashChain;

$chain = new HashChain();
$hash = $chain->generate([
    'type'     => 'HASH_PROPOSAL',
    'from'     => 'agent://sales@my-company.watp',
    'payload'  => $payload,
    'prev_hash' => $previousHash,
]);
$isValid = $chain->validate($negotiationHistory);

Firmas X.509

Para garantizar el no repudio con validez legal, the HASH_CONCLUDED se firma con certificados digitales X.509 de ambas empresas.

php
use Wortic\WATP\Signer;

$signer = new Signer('/path/to/certificate.pfx', 'password');
$signed = $signer->sign($concludedMessage);
$valid  = $signer->verify($receivedMessage, $publicKey);

SDK PHP

El SDK PHP abstrae la comunicación de red, validación de hash y gestión de agentes.

php — initialization
<?php declare(strict_types: 1);

use Wortic\WATP\Node;
use Wortic\WATP\Config;
use Wortic\WATP\Agent\SalesAgent;
use Wortic\WATP\Agent\ProcurementAgent;

$config = Config::fromEnv(__DIR__ . '/.env');
$node   = new Node($config);
$node->register(new SalesAgent($config));
$node->register(new ProcurementAgent($config));
$node->listen();

Configuración

Toda la configuración se realiza mediante el archivo .env en el directorio del nodo.

.env
# Identity
WATP_NODE_ID=my-company
WATP_TAX_ID=12.345.678/0001-90

# Legacy ERP connection
ERP_DSN=mysql://user:pass@localhost/erp_db

# Motor de IA
AI_PROVIDER=openai          # openai | anthropic | gemini | ollama
AI_API_KEY=sk-...
AI_MODEL=gpt-4o-mini

# Guardrails
GUARD_MIN_MARGIN=15
GUARD_MAX_DISCOUNT=20
GUARD_MAX_PAYMENT_DAYS=90
GUARD_AUTO_APPROVE_BELOW=5000

# X.509 Certificate
CERT_PATH=/certs/company.pfx
CERT_PASSWORD=certificate-password

Agentes

Los agentes son clases PHP que encapsulan la lógica de negocio. Extienda el agente base.

php — custom agent
class MySalesAgent extends BaseAgent
{
    public function handleInterest(Message $msg): ?Message
    {
        $product = $this->erp->semanticSearch($msg->payload['description']);
        if (!$product) return null;

        $price = $this->calculatePrice($product, $msg->payload['qty'], Guardrails::fromConfig());
        return $this->propose($msg, [
            'item' => $product->name, 'qty' => $msg->payload['qty'],
            'unit_price' => $price, 'currency' => 'BRL',
        ]);
    }
}

Guardrails

Reglas de negocio inmutables que restringen las negociaciones de la IA. Si se exceden, el estado transiciona a HASH_WAITING_HUMAN.

Parámetro Tipo Descripción
GUARD_MIN_MARGIN int (%) Margen bruto mínimo aceptable
GUARD_MAX_DISCOUNT int (%) Descuento máximo sobre el precio de lista
GUARD_MAX_PAYMENT_DAYS int Plazo máximo de pago en días
GUARD_AUTO_APPROVE_BELOW float Aprobación automática por debajo de este total
GUARD_MAX_ROUNDS int Máximo de contrapropuestas antes de escalar
GUARD_BLOCKED_IDS string IDs fiscales bloqueados separados por coma

Productos

La clase Product ofrece acceso tipado al catálogo del socio con 18 campos enriquecidos incluyendo dimensiones, precio de costo, código NCM y plazo de entrega.

php — listando productos
use Wortic\WATP\Client;
use Wortic\WATP\Product;

$client = new Client(['node_url' => 'https://site-a.wortic.com/api']);

// Listar todos los productos (retorna Product[])
$products = $client->listProducts();
foreach ($products as $p) {
    printf("%s — %s — R$ %.2f\n", $p->sku, $p->name, $p->price);
}

// Buscar un producto por SKU
$patch = $client->getProduct('PATCH-C6-1.5M');
if ($patch) {
    echo $patch->brand;       // "Furukawa"
    echo $patch->weightKg;    // 0.05
    echo $patch->leadTimeDays; // 3
}

Campos del Producto

Propiedad Tipo Descripción
namestringNombre del producto
skustringCódigo único de stock
pricefloatPrecio de lista
costPrice?floatPrecio de costo (cálculo de margen)
category?stringCategoría del producto
ncmCode?stringCódigo fiscal NCM (Brasil)
brand?stringMarca del fabricante
weightKg?floatPeso en kilogramos
minOrderQty?intCantidad mínima de pedido
leadTimeDays?intPlazo de entrega en días

Endpoints de la API

El nodo local expone una API REST para la integración con sistemas externos.

POST
/api/v1/negotiate

Iniciar una nueva negociación publicando HASH_INTEREST.

GET
/api/v1/negotiations

Listar todas las negociaciones activas con su estado actual.

GET
/api/v1/negotiations/{id}

Detalle completo incluyendo la cadena de hash.

POST
/api/v1/negotiations/{id}/approve

Aprobación humana para el estado HASH_WAITING_HUMAN.

POST
/api/v1/negotiations/{id}/cancel

Cancelar una negociación, generando HASH_CANCELLED.

GET
/api/v1/health

Salud del nodo: estado, uptime, agentes registrados.

GET
/api/v1/catalog

Catálogo completo de productos con campos enriquecidos (18 propiedades por producto).

Webhooks

Configure webhooks para recibir eventos en tiempo real en su sistema.

json — webhook payload
{
  "event": "negotiation.concluded",
  "timestamp": "2026-04-13T15:45:00Z",
  "data": {
    "negotiation_id": "neg_01HZ3...",
    "total_value": 2100.00,
    "final_hash": "sha256:c4d5e6..."
  },
  "signature": "hmac-sha256:..."
}

Códigos de Error

Código Constante Descripción
4001 INVALID_HASH_CHAIN El hash anterior no coincide
4002 GUARDRAIL_VIOLATED La propuesta excedió los guardrails
4003 INVALID_SIGNATURE Firma X.509 inválida o expirada
4004 AGENT_NOT_FOUND El agente de destino no está en la red
4005 NEGOTIATION_EXPIRED El TTL de la negociación expiró
5001 ERP_CONNECTION_FAILED No se pudo conectar al ERP local
5002 AI_PROVIDER_ERROR Error al llamar a la API del proveedor de IA

BYOK — Trae Tu Propia Clave

Use su propia clave de API. Usted controla costos, selección de modelo y límites de uso.

.env
AI_PROVIDER=openai
AI_API_KEY=sk-proj-...
AI_MODEL=gpt-4o-mini

Computación Local

Costo cero. El modelo corre en el propio servidor del cliente, completamente offline y privado.

.env
AI_PROVIDER=ollama
AI_OLLAMA_URL=http://localhost:11434
AI_MODEL=llama3.1:7b

Orquestador Anti-Amnesia

Garantiza que el modelo nunca pierda el contexto de negociación ni rompa el formato JSON. Poda automáticamente el historial y reinyecta el prompt del sistema.

php
use Wortic\WATP\AI\Orchestrator;

$orchestrator = new Orchestrator([
    'max_context_tokens' => 4096,
    'prune_strategy'    => 'keep_last_3_turns',
    'force_json_output'  => true,
    'temperature'        => 0.1,
]);
$response = $orchestrator->complete($negotiationCtx, $currentMsg);

¿Por qué Anti-Amnesia?

En negociaciones largas (más de 5 rondas), los modelos más pequeños pierden el contexto inicial. El Orquestador mantiene un resumen comprimido junto con el prompt del sistema intacto, garantizando consistencia incluso con ventanas de contexto limitadas.