---
title: "Conectar DeepSeek Harness a Buzz: Pasarela de Nostr"
description: "Integre DeepSeek Harness con Block Buzz mediante un puente Nostr. Configure auth NIP-42, streaming de mensajes in situ y espacios de trabajo para agentes IA."
canonical_url: "https://techvoyage.dev/es/article/bringing-buzz-to-deepseek-harness"
last_updated: "2026-10-20T09:53:44.971Z"
---

![Vista general de la pasarela de mensajes DeepSeek Harness conectada a un canal de Block Buzz](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-nostr-gateway-overview.webp)

El plugin de DeepSeek Harness (DSH), **dsh-message-gateway**, extiende el asistente de DeepSeek Harness a múltiples plataformas de mensajería como Discord, Telegram y WeChat. El repositorio del plugin fue bifurcado y ampliado para incorporar la plataforma **Cómo autoalojar Buzz de Block: Espacio de trabajo para agentes IA** a la lista. El repositorio bifurcado está disponible en GitHub en [https://github.com/Tech-Voyage-Dev/dsh-message-gateway](https://github.com/Tech-Voyage-Dev/dsh-message-gateway).

<article-card description="Aprenda a autoalojar el relay de Buzz en un VPS con Ubuntu detrás de Cloudflare. Crea un espacio de trabajo seguro donde humanos y agentes de IA colaboran." image="https://inimages.techvoyage.dev/articles/Self-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues/ES-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp" image-alt="Tarjeta tecnológica premium de 16:9 con detalles en azul profundo y naranja que ilustra cómo autoalojar el relay de Buzz de Block en un VPS Ubuntu, con un panel de estilo glassmorphic limpio con tipografía centrada." label="Guía de requisitos previos" min-read="12" title="Cómo autoalojar Buzz de Block: Espacio de trabajo para agentes IA" to="/article/self-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues">



</article-card>

El asistente de DSH se une a un relay de Buzz como miembro, recibe mensajes directos (DM) y mensajes de canal en los que se le @menciona, y responde mediante el mismo pipeline de agentes por chat que utiliza la interfaz web.

## Arquitectura del plugin dsh-message-gateway

La arquitectura del plugin **dsh-message-gateway** se divide en dos componentes principales:

- **Host** (Node): `gateway-store` (credenciales, `~/.dsh/gateway.json`), `platforms.ts` (definiciones de plataformas y pruebas de conectividad), `routes.ts` (endpoints `/gateway/*`) y `bridge-manager.ts` (los puentes residentes: sesiones de agentes independientes por chat y respuestas en streaming).
- **Cliente** (navegador): la página "**Message platforms**" en la barra lateral, donde se guardan credenciales, se prueban conexiones y se monitoriza el estado del servicio.

Añadir una nueva plataforma implica los siguientes pasos:

1. **Una clase de puente (bridge)**: métodos `start/stop/status` junto con un callback `onText(text, frame)`, reflejando la estructura de `wecom-bridge.ts`.
2. **Conexión en bridge-manager**: reutilizar el pipeline por chat existente (`ensureAgentForKey` + `pendingMap`) e integrar el receptor de respuestas de la plataforma.
3. **Persistencia y rutas**: en `/gateway/save` y `/gateway/delete`: **guardar credenciales inicia el puente, eliminarlas lo detiene**, además de una bandera `autoStartXxx` para que `dsh web` reconecte automáticamente al arrancar.

## Implementación del puente Buzz: Protocolo Nostr y ciclo de vida de eventos

Se utilizó **DeepSeek Harness** para implementar el puente hacia Buzz. La implementación se ajusta a las siguientes especificaciones del protocolo Nostr:

<table>
<thead>
  <tr>
    <th>
      <strong>
        Transporte
      </strong>
    </th>
    
    <th>
      Un WebSocket autenticado mediante NIP-42; por defecto <code>
        ws://localhost:3000
      </code>
      
      ; <code>
        http(s)://
      </code>
      
       se normaliza a <code>
        ws(s)://
      </code>
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        Autenticación
      </strong>
    </td>
    
    <td>
      Evento AUTH <code>
        kind 22242
      </code>
      
      , etiquetas <code>
        [["relay", url], ["challenge", challenge]]
      </code>
      
      , contenido vacío, firmado con la clave privada del agente
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Suscripciones
      </strong>
    </td>
    
    <td>
      <strong>
        Por canal
      </strong>
      
      : <code>
        REQ {"kinds":[9], "#h":[<uuid>]}
      </code>
      
       — un REQ por canal. Un REQ global <code>
        kinds:[9]
      </code>
      
       recibe EOSE pero nunca difunde eventos; el filtro <code>
        #h
      </code>
      
       con múltiples valores <strong>
        no
      </strong>
      
       funciona
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Descubrimiento
      </strong>
    </td>
    
    <td>
      <code>
        REQ {kinds:[39000]}
      </code>
      
       histórico para metadatos de canal (<code>
        type == "dm"
      </code>
      
       identifica canales de mensajes directos)
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Membresía
      </strong>
    </td>
    
    <td>
      <code>
        REQ {kinds:[44100,44101], "#p":[nuestra pubkey], since: now-60s}
      </code>
      
       en tiempo real — 44100 = añadido, 44101 = eliminado, portando <code>
        p
      </code>
      
      +<code>
        h
      </code>
      
      ; actualiza suscripciones <strong>
        sin reconectar
      </strong>
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Eventos de chat
      </strong>
    </td>
    
    <td>
      <code>
        kind 9
      </code>
      
       con etiquetas <code>
        ["h", canal]
      </code>
      
      , opcional <code>
        ["e", replyTo]
      </code>
      
      , <code>
        ["p", mención]
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Ediciones in situ
      </strong>
    </td>
    
    <td>
      <code>
        kind 40003
      </code>
      
       con <code>
        h
      </code>
      
       + <code>
        e
      </code>
      
      →objetivo; sustituye contenido; límite de 64 KB en relay → mantener payloads ≤ 60.000 B; respuestas grandes se fragmentan — el fragmento 0 viaja en la edición y los sobrantes se añaden como mensajes <code>
        kind 9
      </code>
      
       en hilo (<code>
        e
      </code>
      
      →raíz)
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Tramas CLOSED
      </strong>
    </td>
    
    <td>
      <code>
        auth-required
      </code>
      
       antes de AUTH es normal durante el arranque (completar AUTH y reabrir subs); tras AUTH → reintento delimitado (3 intentos, backoff 0/1/2 s); reconectar reconstruye todo
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Límites de relay
      </strong>
    </td>
    
    <td>
      ≤ 2000 eventos históricos por suscripción, ordenados del más reciente al más antiguo incluso usando <code>
        since
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Control de menciones
      </strong>
    </td>
    
    <td>
      Procesa <code>
        kind 9
      </code>
      
       entrantes solo cuando: (a) la etiqueta <code>
        p
      </code>
      
       incluye nuestra pubkey, (b) el canal es DM, o (c) la raíz <code>
        e
      </code>
      
       es nuestro propio evento. Ignora nuestra pubkey (anti-bucle)
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Menciones salientes
      </strong>
    </td>
    
    <td>
      El texto saliente se publica tal cual — el relay no valida tokens <code>
        @
      </code>
      
      ; las etiquetas <code>
        p
      </code>
      
       incluyen al autor entrante más hasta 7 pubkeys adicionales mencionadas (máx. 8)
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Mensajes directos
      </strong>
    </td>
    
    <td>
      Canales de texto plano delimitados al relay (metadatos <code>
        type: "dm"
      </code>
      
      ) — sin cifrado NIP-04/44 en este puente
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Archivos adjuntos
      </strong>
    </td>
    
    <td>
      NIP-92 <code>
        imeta
      </code>
      
       (<code>
        url
      </code>
      
      , <code>
        sha256
      </code>
      
      , <code>
        m
      </code>
      
      ) → descarga http(s) estándar, verificación de SHA-256, límite de 20 MB, máx. 4 por mensaje; las imágenes salientes no están soportadas
    </td>
  </tr>
</tbody>
</table>

El siguiente diagrama ilustra el proceso de inicialización (bootstrap) del puente hacia Buzz:

![Diagrama de secuencia que ilustra el proceso de arranque y autenticación NIP-42 del puente Buzz](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-bootstrap.webp)### Streaming en tiempo real mediante ediciones in situ de Nostr (Kind 40003)

Nostr no cuenta con indicador nativo de escritura y sus eventos son de solo adición. Para ofrecer una experiencia interactiva y dinámica, el puente de Buzz **simula streaming mediante ediciones in situ**:

![Diagrama del flujo de edición in situ que simula respuestas en streaming con eventos kind 40003](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-reply.webp)- *El puente de Buzz publica primero un evento marcador de posición kind 9, luego lo reescribe progresivamente con ediciones in situ kind 40003 limitadas por frecuencia, y finalmente asienta la edición definitiva cuando el agente concluye su respuesta. Este mecanismo reproduce el patrón utilizado en los puentes de Telegram y Discord.*

### Vinculación de espacios de trabajo de DeepSeek Harness mediante comandos de chat

La funcionalidad de "Workspaces" en la interfaz web de DSH está respaldada por el servicio `workspaceRegistry` (`@deepseek-ai/dsh-workspace`):

```typescript
const existing = await ctx.workspaceRegistry.resolveByPath(request.path);
```

El puente de Buzz ofrece el comando de chat `/workspace <carpeta>`, que registra un directorio existente en DSH. Cualquier nueva sesión creada a través de la pasarela se vincula a dicha carpeta y se refleja en la interfaz web.

![Arquitectura del registro de espacios de trabajo de DeepSeek Harness desde comandos de chat](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-workspace.webp)Tres consideraciones de diseño relevantes:

- **Cambiar de carpeta implica una nueva sesión.** El valor `cwd` se fija en la cabecera de la sesión al crearse y no puede modificarse posteriormente.
- **La carpeta debe existir previamente.** El método `create` rechaza rutas inexistentes.
- **Comando sensible a la seguridad.** Cada sesión opera con una directiva de **auto-aprobación**, otorgando acceso de lectura y ejecución en el directorio indicado.

## Guía paso a paso de instalación y configuración

1. Ejecute los siguientes comandos en la terminal:

```bash
dsh plugin --profile web add https://github.com/Tech-Voyage-Dev/dsh-message-gateway.git

# Start DSH web
dsh web
```

1. Una vez que la interfaz web de DSH se abra en el navegador, haga clic en el icono "**Message platforms**":

![Barra lateral de la interfaz web de DeepSeek Harness destacando el menú Message platforms](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-web-ui-message-platforms-sidebar-icon.webp)

1. Seleccione "**Buzz**" en el panel lateral izquierdo:

![Panel de configuración del puente Buzz en la pasarela de mensajes de DeepSeek Harness](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-message-gateway-buzz-config-panel.webp)

1. Haga clic en "**Generate keypair**" para generar un par de claves Nostr. Copie la clave pública `npub` en un lugar seguro para los pasos siguientes.
2. Ingrese la **Relay URL** y los **Channels** (la lista de UUIDs de canales permitidos para suscribirse).
3. Presione el botón "**Save**".

Al guardar el formulario se almacenan las credenciales y **se inicia el puente**. La clave privada `nsec` se trata como un secreto estricto y se guarda exclusivamente en `~/.dsh/gateway.json`.

### Registro del par de claves del agente en el relay Nostr de Buzz

**Añada el asistente de DSH al relay como miembro.** Utilice la clave `npub` generada previamente:

```bash
docker compose exec relay buzz-admin add-member --pubkey npub123123123
```

**Incorpore el asistente a un canal específico.** Registrar un miembro en el relay no lo hace visible ni localizable de forma automática en los canales. Para agregarlo mediante `buzz-cli`, tenga en cuenta que el parámetro `--pubkey` debe especificarse en formato **HEX**, no npub (el comando `buzz-admin add-member` imprime la clave HEX correspondiente):

```bash
buzz channels add-member --channel <CHANNEL_UUID> --pubkey <AGENT_HEX> --role member
```

<article-card description="Instrucciones paso a paso para instalar y configurar buzz-cli para gestionar canales de Nostr, claves de miembros y permisos de agentes de IA." image="https://inimages.techvoyage.dev/articles/Self-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues/ES-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp" image-alt="Tarjeta tecnológica premium de 16:9 con detalles en azul profundo y naranja que ilustra cómo autoalojar el relay de Buzz de Block en un VPS Ubuntu, con un panel de estilo glassmorphic limpio con tipografía centrada." label="Guía de CLI" min-read="5" title="Cómo instalar y usar buzz-cli" to="/article/self-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#install-buzz-cli">



</article-card>

Actualice el perfil del asistente en el relay Nostr asignándole un nombre descriptivo con `buzz-cli`:

![Actualización del nombre del asistente DeepSeek Harness en el relay Nostr mediante buzz-cli](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-assistant-buzz-cli-profile-update.webp)

Envíe un saludo **Wave** (el saludo inicial de Buzz para mensajes directos) al asistente. La respuesta confirma la conexión:

![Prueba de conexión enviando un saludo Wave como DM al asistente DeepSeek Harness en Buzz](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-dm-wave-greeting-reply.webp)

*Envío de un Wave como mensaje directo al asistente de DSH: el puente está operativo.*

### Habilitación del acceso a carpetas locales con `/workspace`

Debido a que el parámetro `allowWorkspace` está deshabilitado (`false`) por defecto, el comando `/workspace` será rechazado inicialmente:

![Notificación de error mostrando el rechazo del comando workspace con allowWorkspace desactivado](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-workspace-command-rejected-error.webp)

Habilítelo en `~/.dsh/profiles/web/cordis.patch.yml` y reinicie `dsh web`:

```yml
- id: ui-message-gateway
  config:
    allowWorkspace: true
```

Tras reiniciar el servicio:

![Mensaje de confirmación exitosa tras ejecutar el comando de registro de workspace en Buzz](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-buzz-workspace-command-success-confirmation.webp)

Nota importante: este comando asume que el directorio del workspace (`TechVoyage` en las capturas) reside dentro del directorio predeterminado del usuario. De lo contrario, indique la ruta absoluta completa. Cualquier nueva sesión creada bajo este workspace desde Buzz aparecerá también en la interfaz web de DeepSeek Harness.

![Interfaz web de DeepSeek Harness mostrando la sesión de workspace sincronizada desde Buzz](https://inimages.techvoyage.dev/articles/Bringing%20Buzz%20to%20DeepSeek%20Harness/dsh-web-ui-synced-workspace-session.webp)

### Comandos disponibles en Buzz

Todas las funcionalidades y comandos disponibles en las demás plataformas están plenamente soportados en Buzz:

<table>
<thead>
  <tr>
    <th>
      Comando
    </th>
    
    <th>
      Descripción
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        /workspace <folder>
      </code>
    </td>
    
    <td>
      Registra una carpeta existente como espacio de trabajo del chat (requiere habilitación en configuración)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /help
      </code>
    </td>
    
    <td>
      Muestra la lista de comandos disponibles
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /time
      </code>
    </td>
    
    <td>
      Informa la hora actual del sistema
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /new
      </code>
    </td>
    
    <td>
      Inicia una nueva sesión de conversación limpia
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /clear
      </code>
    </td>
    
    <td>
      Limpia el historial de la conversación actual
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /status
      </code>
    </td>
    
    <td>
      Muestra el estado operativo del puente
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /stats
      </code>
    </td>
    
    <td>
      Muestra estadísticas de chats activos y estado de puentes en todas las plataformas (incluido Buzz)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /commands
      </code>
    </td>
    
    <td>
      Lista descriptiva de cada comando soportado
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @path/to/file
      </code>
    </td>
    
    <td>
      Funciona como las menciones web de archivos: el modelo lee el archivo relativo al workspace; <code>
        @
      </code>
      
      , <code>
        @prefijo
      </code>
      
       o <code>
        /files <prefijo>
      </code>
      
       devuelven archivos y carpetas coincidentes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /model
      </code>
    </td>
    
    <td>
      <code>
        [provider model effort]
      </code>
      
       — validado frente al catálogo de modelos LLM activos; <code>
        /model
      </code>
      
       lista opciones disponibles y <code>
        /model reset
      </code>
      
       restablece valores predeterminados
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        /effort
      </code>
    </td>
    
    <td>
      <code>
        <id>
      </code>
      
       modifica exclusivamente el esfuerzo de razonamiento del modelo; <code>
        /effort reset
      </code>
      
       restablece el valor por defecto
    </td>
  </tr>
</tbody>
</table>

### Aspectos clave de seguridad

- La clave privada **nsec** reside únicamente en `~/.dsh/gateway.json` (permisos 0600, escritura atómica) — nunca se expone en endpoints como `/gateway/list` ni en registros de depuración.
- Cada evento entrante es **verificado criptográficamente** (`verifyEvent`), deduplicado, filtrado contra mensajes propios y evaluado por reglas de mención antes de llegar al agente.
- **El registro de workspaces está restringido por configuración** (`allowWorkspace: false` por defecto), garantizando control estricto sobre sesiones automáticas con acceso a archivos locales.

## Conclusión: Colaboración descentralizada con agentes IA en Buzz

El desafío central al integrar Buzz en `dsh-message-gateway` radicó en implementar fielmente el contrato de eventos del protocolo Nostr. La arquitectura base del plugin ya ofrecía una sólida gestión de sesiones independientes y enrutamiento de comandos, permitiendo una integración fluida en cuanto se resolvieron el manejo de eventos y el streaming interactivo.

## Referencias:

- [dsh-message-gateway architecture guide](https://github.com/a792883583/dsh-message-gateway/blob/main/docs/architecture.md) — guía de arquitectura, extensiones y notas de seguridad
- [nostr-tools](https://github.com/nbd-wtf/nostr-tools) — librería Nostr utilizada internamente
- [deer-flow IM channel connections](https://github.com/bytedance/deer-flow/blob/main/backend/docs/IM_CHANNEL_CONNECTIONS.md) — patrones de referencia para conexiones de canales de mensajería instantánea
