n24q02m/agent-chat-plugin

Agentes de IA pares conversan en una carpeta compartida — sin relevo humano, sin orquestador, funciona en Windows, espera sin consumir tokens.

¿Qué es agent-chat-plugin?

Este plugin de chat entre agentes permite que múltiples sesiones de agentes de IA (por ejemplo, Claude Code, Codex, etc.) se comuniquen de forma asíncrona intercambiando archivos Markdown en carpetas de canal compartidas, sin necesidad de un supervisor central, un agente orquestador o un middleware de mensajería. Cada canal representa una conversación grupal independiente, con su propio espacio de secuencias, metadatos y estado. Almacena mensajes, tareas estructuradas, leases (concesiones), bloqueos de rutas de archivos y eventos de capacidad/estado como archivos de texto plano, lo que los hace legibles por humanos, commiteables en Git y totalmente recuperables incluso tras un fallo del agente. Es compatible con Windows, WSL y Linux, y su mecanismo de espera (wait) no realiza llamadas a modelos, consumiendo cero tokens. Es útil para equipos de agentes que colaboran en el mismo problema, para solicitar trabajo a otro agente y esperar su resultado, o para mantener un registro auditable de negociaciones entre agentes. No debe usarse cuando un único agente con subagentes baratos es suficiente, ya que este patrón intercambia tokens por paralelismo, tolerancia a fallos y auditabilidad.

Compatible con✓Claude Code~Codex CLI✓Cursor
npx skills add n24q02m/agent-chat-plugin

Installed? Explore more Investigación y análisis de datos skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

agent-chat

Resumen

Las sesiones de agentes pares se coordinan intercambiando archivos Markdown en carpetas de canal compartidas — sin supervisor, sin intermediario de mensajes, sin RAM compartida entre ellas. Cada canal es un "chat grupal". Todo el hilo es Markdown plano: commiteable en Git, legible por humanos, reproducible. Una sesión que falla no pierde nada — los archivos son el estado.

La CLI basada únicamente en la stdlib (chat.py más el paquete agent_chat/) funciona en Windows, WSL y Linux. wait duerme entre comprobaciones del sistema de archivos y no realiza llamadas a modelos.

Principio fundamental: hablar a través de archivos, no a través del otro. Resúmenes como artefactos, no transcripciones completas enviadas de un lado a otro.

Esta es una capa de datos de coordinación local, no un servidor MCP ni un ejecutor de agentes. Los mensajes, tareas, leases, bloqueos de rutas, eventos de capacidad/estado y estado derivado no realizan llamadas de completado, embedding, rerank, servicio de grafos ni de relay/proveedor.

Cuándo usarlo

  • Varias sesiones de agentes compatibles con OMP (u otros) que trabajan en el mismo problema como iguales.
  • Una sesión necesita que otra haga algo y luego espera el resultado.
  • Deseas un registro auditable de una negociación entre agentes.
  • Necesitas varios chats grupales independientes (uno por tema/equipo) — crea un canal para cada uno.

Cuándo NO usarlo: un solo agente con subagentes baratos es más económico y simple — este patrón intercambia tokens por paralelismo, tolerancia a fallos y auditabilidad. Si el presupuesto de tokens es ajustado, usa solo la ruta asíncrona/traspaso (publica un resumen al final de la sesión; la siguiente sesión lo lee) — ese modo cuesta casi nada.

Referencia rápida

Usa agent-chat <cmd> después de pipx install agent-chat-plugin, o uvx --from agent-chat-plugin agent-chat <cmd> para cada invocación única. uvx no instala un comando persistente. Con una habilidad independiente, mantén SKILL.md, chat.py y todo el directorio agent_chat/ juntos y ejecuta python "/ruta/a/la/habilidad/chat.py" <cmd>. Los ejemplos abreviarán esto como chat.py.

El plugin de Claude Code usa python "${CLAUDE_PLUGIN_ROOT}/chat.py" <cmd>. Otros hosts usan una ruta de checkout real, no una variable de plugin asumida. La precedencia de raíz es --root > $AGENT_CHAT_ROOT > ~/agent-chat; pon --root antes del subcomando. Las raíces predeterminadas de máquinas separadas no están sincronizadas.

La instalación desde PyPI solo incluye los módulos CLI/runtime. Los hooks/*.py opcionales vienen del checkout/plugin y necesitan cableado explícito del ciclo de vida del host. Sus puntos de entrada Python son portables; su registro y contrato de salida no es automáticamente una integración OMP. Los avisos de sesión/prompt son texto; Stop emite systemMessage JSON compatible con Claude. Los hooks miran sin avanzar cursores y siempre salen con 0; CLAUDE_PLUGIN_ROOT no resuelto o raíces de plugin relativas al script se omiten con un diagnóstico de una línea en stderr.

Haz estoComando
Crear un chat grupalchat.py init review --members alice,bob --topic "..."
Listar todos los chats grupaleschat.py channels
Publicar un mensajechat.py post review --from alice --to bob --title "Esquema v0.2" --body-file msg.md
Transmitir al grupochat.py post review --from alice --to all --title "..." (u omite --to)
Leer lo nuevo para míchat.py read review --as bob
Esperar una respuesta (0 tokens)chat.py wait review --as alice --timeout 900
Vislumbrar reciente, mantener cursorchat.py peek review -n 3
Reclamar un marcador de tareachat.py claim work task-12.md --as bob
Bloquear rutas del espacio de trabajochat.py lock review src/main.py --as alice --lease-seconds 300
Verificar conflictos de rutaschat.py check review src/main.py
Liberar bloqueo de rutachat.py unlock review <lock-id-o-ruta> --as alice
Recuperar bloqueo obsoletochat.py recover review <lock-id-o-ruta> --as bob --reason "obsoleto"
Recuperar transacción de ruta pendientechat.py recover-pending review --as alice
Renderizar estado del canalchat.py state review
Compactar estado del canalchat.py compact review --as alice
Publicar evento de capacidad/estadochat.py event post review --from alice --type capability --harness omp
Leer eventos del adaptadorchat.py event read review --type capability

Los eventos neutrales al adaptador usan la versión de esquema 1 y se transportan como cuerpos JSON en mensajes de canal ordinarios. Los eventos de capacidad anuncian solo las primitivas portables messages, cursors, wait, tasks, dependencies, leases, path_locks y state_summary. Los eventos de estado usan ready, busy, idle, blocked o stopped, con detalle opcional. Los campos, primitivas, versiones, marcas de tiempo, identidades y estados desconocidos fallan con errores EVENT_* estables. Este protocolo no reclama MCP, ACP, puente de activación ni ejecución de agentes. Las tareas estructuradas usan la misma raíz de canal y escriben registros JSON autoritativos bajo <raíz>/<canal>/tasks/; los registros de lease activos viven bajo <raíz>/<canal>/claims/<id-tarea>.<propietario>.json. Cada mutación exitosa de tarea o lease también publica un evento de auditoría a través del protocolo de mensajes existente:

chat.py task create <canal> <id-tarea> --from <agente> --title <título>
chat.py task list <canal>
chat.py task show <canal> <id-tarea>
chat.py task update <canal> <id-tarea> --as <agente> [campos...]
chat.py task claim <canal> <id-tarea> --as <agente> --lease-seconds 300
chat.py task renew <canal> <id-tarea> --as <agente> --lease-seconds 300
chat.py task done <canal> <id-tarea> --as <agente>
chat.py task block <canal> <id-tarea> --as <agente>
chat.py task release <canal> <id-tarea> --as <agente>
chat.py task recover <canal> <id-tarea> --as <agente> \
  --reason "sesión obsoleta" --lease-seconds 300
chat.py task recover-pending <canal> --as <agente> \
  [--resolve-publication rollback|published]

claim, renew y recover obsoleto aceptan --lease-seconds, --lease, o --ttl; el valor debe ser una duración finita positiva. claim avanza una tarea lista a in_progress, asigna el propietario y escribe su vencimiento atómicamente con el registro de claim. Solo el propietario puede renovar, liberar o completar un claim no vencido. task done limpia un claim activo atómicamente; cuando no existe ningún claim, preserva la transición directa de Tarea 3. task release preserva de manera similar la transición de Tarea 3 no adquirida. Un claim vencido nunca se roba en silencio: task recover obsoleto requiere un nuevo propietario y una razón no vacía y registra previous_owner, previous_lease_expires_at y recovery_reason. Después de un fallo, task recover-pending <canal> --as <agente> finaliza explícitamente la limpieza/reversión del marcador de transacción duradera; nunca roba ni reasigna en silencio una tarea obsoleta. Los marcadores applied heredados v1 cuya publicación de auditoría no se puede probar fallan cerrados con LEASE_TRANSACTION_PUBLICATION_UNKNOWN; vuelve a ejecutar el comando con --resolve-publication rollback o published después de la inspección del operador.

create acepta --owner, --depends-on, --files-hint, --acceptance y --branch. Repite las opciones de lista para añadir múltiples valores. update acepta --title, --owner, --depends-on, --files-hint, --acceptance, --branch y --status; usa --clear-owner o --clear-branch para establecer campos anulables de vuelta a null. Las actualizaciones genéricas no pueden mutar un lease activo; usa los comandos de lease en su lugar. Los valores de lista también pueden estar separados por comas.

Los estados de tarea son open, in_progress, blocked, done y cancelled. done y cancelled son terminales. Las transiciones permiten open -> in_progress | blocked | cancelled, in_progress -> open | blocked | done | cancelled, y blocked -> open | in_progress | cancelled. Las escrituras del mismo estado son intencionadamente idempotentes. task done mueve in_progress (o done idempotente) a done; task block mueve open, in_progress o blocked a blocked; y task release mueve blocked, in_progress o open a open. Una tarea puede avanzar a in_progress o done solo cuando cada ID en depends_on tiene un registro de tarea cuyo estado es done. La preparación se calcula a partir de los registros JSON de tareas, nunca del texto del mensaje.

Los fallos de tarea y lease son distintos de cero (código de salida 2) e incluyen un código estable. Los códigos de tarea incluyen TASK_INVALID_COMMAND, TASK_INVALID_ARGUMENT, TASK_INVALID_CHANNEL, TASK_CHANNEL_NOT_FOUND, TASK_NOT_FOUND, TASK_ALREADY_EXISTS, TASK_INVALID_STATUS, TASK_INVALID_UPDATE, TASK_INVALID_TRANSITION, TASK_DEPENDENCY_NOT_READY, TASK_UNKNOWN_DEPENDENCY, TASK_DEPENDENCY_CYCLE, TASK_PATH_OUTSIDE_WORKSPACE, TASK_LOCK_TIMEOUT, TASK_IO_ERROR y TASK_AUDIT_FAILED. Los códigos de lease incluyen LEASE_CONFLICT, LEASE_RECOVERY_REQUIRED, LEASE_OWNER_MISMATCH, LEASE_NOT_EXPIRED, LEASE_NOT_FOUND, LEASE_INCONSISTENT, LEASE_MUTATION_REQUIRED, LEASE_INVALID_OWNER, LEASE_INVALID_TASK_ID, LEASE_INVALID_CHANNEL, LEASE_INVALID_REASON, LEASE_INVALID_DURATION, LEASE_INVALID_TIMESTAMP, LEASE_INVALID_RECORD, LEASE_REQUIRED_FIELD_MISSING, LEASE_UNKNOWN_FIELD, LEASE_RECORD_ID_MISMATCH, LEASE_STORAGE_INVALID, LEASE_PATH_OUTSIDE_WORKSPACE, LEASE_TRANSACTION_PENDING, LEASE_TRANSACTION_CLEANUP_FAILED, LEASE_TRANSACTION_PUBLICATION_UNKNOWN, LEASE_TRANSACTION_INVALID, LEASE_TRANSACTION_NOT_FOUND, LEASE_TRANSACTION_RECOVERY_FAILED, LEASE_AUDIT_FAILED y LEASE_AUDIT_ROLLBACK_FAILED. Las escrituras de lease usan un marcador de transacción duradera con fases preparada/aplicada/publicada; después de un fallo o error de limpieza, el acceso falla cerrado hasta que task recover-pending/LeaseStore.recover_pending() explícitamente revierte o finaliza la transacción publicada.

Los bloqueos de ruta coordinan el acceso exclusivo a archivos y directorios relativos al espacio de trabajo:

chat.py lock <canal> <rutas...> --as <agente> [--lease-seconds 300]
chat.py check <canal> <rutas...> [--as <agente>]
chat.py unlock <canal> <id-bloqueo-o-ruta> --as <agente>
chat.py recover <canal> <id-bloqueo-o-ruta> --as <agente> \
  --reason "sesión obsoleta" [--lease-seconds 300]
chat.py recover-pending <canal> --as <agente> \
  [--resolve-publication rollback|published]

lock y recover aceptan --lease-seconds, --lease o --ttl. El objetivo puede ser el ID de bloqueo o la ruta exacta normalizada. La normalización resuelve las rutas relativas al espacio de trabajo, previene la salida de raíz/canal/symlink, aplica reglas de mayúsculas/minúsculas de la plataforma (sin distinción en Windows) y rechaza nombres reservados de Windows, puntos/espacios finales, caracteres de control y suplentes solitarios. Los conflictos de archivo/archivo y las superposiciones de directorio/archivo provocan conflictos. Solo el propietario puede desbloquear un bloqueo activo; los bloqueos vencidos requieren un recover explícito que registre previous_owner, previous_expires_at y recovery_reason. Las mutaciones usan publicación de archivos atómica de contenido, bloqueos de archivos de asesoramiento y diario de transacciones a prueba de fallos. Los errores de bloqueo de ruta salen con código distinto de cero y códigos estables como PATH_LOCK_INVALID_PATH, PATH_LOCK_PATH_OUTSIDE_WORKSPACE, PATH_LOCK_CONFLICT, PATH_LOCK_RECOVERY_REQUIRED, PATH_LOCK_OWNER_MISMATCH, PATH_LOCK_NOT_FOUND, PATH_LOCK_NOT_STALE, PATH_LOCK_INVALID_OWNER, PATH_LOCK_INVALID_LOCK_ID, PATH_LOCK_INVALID_CHANNEL, PATH_LOCK_INVALID_REASON, PATH_LOCK_INVALID_DURATION, PATH_LOCK_INVALID_TIMESTAMP, PATH_LOCK_INVALID_RECORD, PATH_LOCK_STORAGE_INVALID, PATH_LOCK_STORAGE_ERROR, PATH_LOCK_TIMEOUT, PATH_LOCK_TRANSACTION_PENDING, PATH_LOCK_TRANSACTION_CLEANUP_FAILED, PATH_LOCK_TRANSACTION_INVALID, PATH_LOCK_AUDIT_FAILED y PATH_LOCK_AUDIT_ROLLBACK_FAILED.

El resumen del estado del canal y la compactación derivan un artefacto state.md determinista:

chat.py state <canal> [--write] [--json] [--strict]
chat.py compact <canal> [--as <agente>] [--no-audit] [--json] [--strict]

state renderiza o imprime el resumen del canal derivado que contiene:

  • Objetivo / Tema (de _meta.json)
  • Decisiones (extraídas de mensajes y registros estructurados)
  • Tareas abiertas (de tasks/*.json, incluyendo estado, propietario, lease, dependencias)
  • Bloqueadores (bloqueadores de dependencias de tareas, estados de tarea bloqueados y mensajes bloqueadores)
  • Propietarios y Leases (claims activos, propiedades de tareas y bloqueos de ruta)
  • Bloqueos de Ruta (bloqueos de ruta activos de locks/*.json)
  • Última Evidencia de Verificación (criterios de aceptación y mensajes de verificación)

compact escribe el resumen derivado en <raíz>/<canal>/state.md usando un reemplazo atómico de archivo temporal hermano (.state.md.tmp.*) y, por defecto, publica un evento de mensaje state.compacted auditable en el canal.

state.md es estrictamente un artefacto derivado y nunca es autoritativo. La compactación no es destructiva: nunca elimina, muta o trunca ningún archivo de mensaje, registro de tarea, claim activo, bloqueo de ruta o cursor de lectura. Todos los registros fuente permanecen como la verdad fundamental inmutable.

Los errores de estado salen con código distinto de cero y códigos estables como STATE_INVALID_CHANNEL, STATE_CHANNEL_NOT_FOUND, STATE_INVALID_RECORD, STATE_MALFORMED_SOURCE, STATE_RECORD_NOT_FOUND, STATE_IO_ERROR y STATE_AUDIT_FAILED. --reply <seq> enhebra un mensaje a uno anterior. python chat.py <cmd> --help para todas las banderas.

Comandos de eventos neutrales al adaptador:

chat.py event post <canal> --from <agente> --type capability --harness <harness>
chat.py event post <canal> --from <agente> --type status --harness <harness> --status ready
chat.py event read <canal> [--type capability|status]

El cuerpo del evento es JSON versionado validado contra schemas/agent-chat-event.schema.json. Los mensajes Markdown ordinarios permanecen sin cambios y son ignorados por event read.

Estructura de carpetas

<raíz>/
  review/                     # un canal = un chat grupal
    _meta.json                # miembros, tema, creado
    state.md                  # resumen de estado derivado (no autoritativo)
    0001-alice-schema-draft.md # NNNN-<de>-<slug>.md, frontmatter + cuerpo
    0002-bob-schema-review.md
    tasks/                    # registros de tareas estructuradas
    claims/                   # registros de lease activos
    locks/                    # bloqueos de ruta del espacio de trabajo activos
    .cursors/bob.txt          # "último seq leído" por agente
  deploy/                    # un SEGUNDO chat grupal, espacio de secuencia separado
    ...

Skills relacionados