Commit Graph

34 Commits

Author SHA1 Message Date
egutierrez 8fcbcba39c feat: integrar shared knowledge store en runtime
- Agregar campo sharedKnowledgeStore al Agent struct
- Inicializar shared store si cfg.Tools.SharedKnowledge.Enabled
- Registrar shared tools en buildToolRegistry
- Cerrar shared store en Run defer
- Defaults: dir=knowledges, db=knowledges/data/knowledge.db
- Issue 0018: Shared Knowledge (fase 3)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:56:51 +00:00
egutierrez 1fccae1568 feat: añadir cliente MCP para consumir servidores externos
Implementa el cliente MCP que permite a los agentes conectarse a servidores
MCP externos y usar sus tools como si fueran tools nativas del agente.

Arquitectura implementada:
- shell/mcp/client.go: Cliente MCP con soporte stdio y SSE
- shell/mcp/manager.go: Gestor de múltiples clientes MCP
- tools/mcptools/mcp.go: Bridge que convierte MCP tools → tools.Tool
- shell/mcp/server.go: Movido desde shell/protocols/ para colocación junto al client

Cambios en config:
- MCPServerCfg extendido con campos Transport, Command, Args, Env, Headers,
  Prefix, Timeout para soportar stdio y SSE transport

Integración en runtime:
- agents/runtime.go: Inicializa MCP manager si config.Tools.MCP.Enabled
- buildToolRegistry: Registra tools MCP automáticamente con prefijos configurables
- Agent: Campo mcpManager que se cierra en shutdown

Transportes soportados:
- stdio: Lanza subproceso (ej: npx -y @anthropic/mcp-server-brave-search)
- SSE: Se conecta a servidor HTTP MCP

Las tools MCP son indistinguibles de tools nativas desde el punto de vista
del LLM. Auto-discovery via ListTools(), conversión de JSON Schema a tools.Param.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-08 21:22:33 +00:00
egutierrez 8811d45fd1 feat: conectar sistema centralizado de seguridad al launcher y runtime
- Migrar admin a security/user-groups.yaml (admins group)
- agents.New() ahora acepta acl.ACL pre-resuelta como parámetro;
  elimina construcción interna desde cfg.Security.Roles
- cmd/launcher: carga shellsecurity.Load("security/") al arranque;
  si falla, WARN + política vacía (open access). Para cada agente
  llama pksecurity.ResolveACL y pasa la ACL a agents.New()
- cmd/launcher/registry.go: stores secPolicy en launchDeps para
  que reload() también resuelva ACL centralmente
- shell/matrix/listener.go: elimina invite gating y allowlist check
  basados en AllowedUsers; el control de acceso lo hace el runtime
- internal/config/schema.go: depreca campos Roles y AllowedUsers
  (backward compat, no eliminados)
- agents/*/config.yaml: elimina bloques security.roles y allowed_users
- dev/feature_flags.json: activa centralized-security-groups (enabled: true)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:56:21 +00:00
egutierrez 9d1ab2d28e feat: integrar Scheduler en agents/runtime.go
Se instancia shellcron.Scheduler en agents.New() cuando cfg.Schedules tiene
entradas (scheduler queda nil en agentes sin schedules, sin overhead).

En agents.Run() se arranca el scheduler en una goroutine independiente que
termina cuando el ctx del agente es cancelado — el shutdown es limpio gracias
a cron.Stop() que devuelve un contexto que se espera.

La integración no rompe agentes existentes: el campo scheduler es nil por
defecto y todo el código nuevo está tras if a.scheduler != nil.
2026-03-08 19:00:38 +00:00
egutierrez 069f8758b1 feat: hot-reload de agentes individuales via SIGHUP
Implementa el mecanismo de hot-reload descrito en el issue 0013:

- agents/runtime.go: añade Agent.Stop() y Agent.Done() para ciclo de vida
  individual. Run() crea un contexto hijo cancelable y cierra el canal
  done al retornar.

- cmd/launcher/registry.go (nuevo): agentRegistry rastrea agentes vivos
  por ID. Métodos: register, stopAndWait, reload, reloadAll, waitAll,
  cleanupLogs. reload() sigue el flujo completo: stop→wait→unsubscribe
  →reload config→recreate→rewire bus/orch→start nueva goroutine.

- cmd/launcher/main.go: usa agentRegistry en lugar de sync.WaitGroup.
  Añade handler de SIGHUP en goroutine separada que lee run/reload.txt
  para determinar el agente objetivo (* o vacío = todos). Tras leer,
  borra run/reload.txt para no afectar el siguiente SIGHUP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:41:32 +00:00
egutierrez 5d3ab834a7 fix: responder en thread cuando el mensaje viene de un thread
Dos problemas corregidos:

1. Detección de threads con E2EE: después de desencriptar un evento,
   evt.Content.Raw puede no contener m.relates_to. Se añade fallback
   usando el contenido tipado (evt.Content.Parsed) que es más robusto
   tras la desencriptación de mautrix.

2. Notificaciones de tools fuera del thread: la notificación "🔨 tool"
   se enviaba con SendMarkdown directo a la sala, ignorando el contexto
   de thread. Ahora usa sendReply que respeta ThreadID.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:14:21 +00:00
egutierrez 38d11a0b32 feat: soporte de threads de Matrix (m.thread)
Implementa el soporte completo de threads de Matrix:
- Listener extrae ThreadID de m.relates_to con rel_type=m.thread
- Client.SendThreadMarkdown envia mensajes como parte de un thread
  usando SetThread de mautrix con fallback m.in_reply_to
- Runner detecta ThreadID en ReplyAction y rutea a SendThreadMarkdown
- MatrixSender interfaz actualizada con SendThreadMarkdown
- runtime.go propaga ThreadID en todas las respuestas (comandos, LLM, RBAC)
- sendReply helper centraliza la logica de envio con/sin thread
- Auto-thread: si matrix.threads.auto_thread=true, crea thread nuevo
  para cada conversacion que no esta ya en un thread
- Memoria por thread: usa ThreadID como clave de window cuando el mensaje
  esta en un thread, permitiendo conversaciones paralelas independientes
- Config: matrix.threads.enabled y matrix.threads.auto_thread en ThreadsCfg

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:50:34 +00:00
egutierrez 536fa0bc54 feat: storage.base_path configurable para aislar datos de runtime
Añade BasePath a StorageCfg y resolveDataBase() en runtime.go para
centralizar la resolucion del directorio base de datos del agente.

Prioridad: config storage.base_path > $AGENTS_DATA_DIR/<id> > agents/<id>/data

Esto permite mover los datos de runtime fuera del arbol del proyecto,
evitando que herramientas de desarrollo lean bases de datos, logs o
crypto stores por accidente.

Los paths de memory.db y knowledge.db ahora usan el base resuelto.
Los configs existentes no se rompen (fallback al path original).

Tareas 1.1 y 1.2 del issue 0019.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:49:02 +00:00
egutierrez 69efb6ab95 feat: rate limiting de tools por room en registry
Añade rate limiting de tool calls por room usando sliding window:

- tools/ratelimit.go: RateLimiter con sliding window per key (room),
  Allow() para verificar/registrar llamadas, Cleanup() para limpiar
  entries expiradas
- tools/registry.go: SetRateLimiter() y ExecuteForRoom() que verifica
  el rate limit antes de ejecutar, logueando tool_rate_limited si excede
- internal/config/schema.go: ToolRateLimitCfg en SecurityCfg con
  enabled, max_calls_per_min y cleanup_interval_s
- agents/runtime.go: inicializa rate limiter desde config y arranca
  goroutine de cleanup periodico
- agents/commands.go: usa ExecuteForRoom en !tool command

Config YAML:
  security:
    tool_rate_limit:
      enabled: true
      max_calls_per_min: 10

Parte de issue 0019c (prompt injection hardening — rate limiting).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:45:41 +00:00
egutierrez 64d29e5968 feat: integrar sanitizacion de input en runtime y config
- agents/runtime.go: campo sanitizeOpts en Agent, sanitizeInput() que
  llama a sanitize.Sanitize() y loguea warnings. Integrado en
  executeActions() y handleTaskEvent() antes de enviar al LLM.
  En modo reject, responde al usuario y corta el flujo.
- internal/config/schema.go: nuevo tipo SanitizeCfg dentro de SecurityCfg
  con campos enabled, mode, min_severity, disabled_patterns.

Protegido por feature flag prompt-injection-hardening (OFF).
Se activa por agente via security.sanitize.enabled en config.yaml.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:34:33 +00:00
egutierrez 4e7aa95adb feat: hardening de tools — deny-by-default, SSRF, path traversal, allowlists
Cambios de seguridad en las 4 herramientas de agentes:

- tools/file: deny-by-default (AllowedPaths vacío = todo denegado),
  resolución de symlinks con EvalSymlinks, protección contra path
  traversal (../) y confusión de prefijos (/opt vs /opt1234)
- tools/ssh: nuevo AllowedCommands allowlist (complementa ForbiddenCommands),
  validación de sintaxis shell (bloquea pipes, subshells, redirects, chains)
- tools/http: protección SSRF bloqueando IPs privadas, loopback, link-local,
  metadata (169.254.169.254). Validación de dominio case-insensitive.
- tools/matrix: nuevo parámetro AllowedRooms para restringir rooms destino
- internal/config/schema: AllowedCommands en SSHToolCfg, MatrixToolCfg nueva
- agents/runtime: pasa MatrixToolCfg al constructor de matrix_send

Parte de issue 0019 (prompt injection hardening). Feature flag OFF.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:17:00 +00:00
egutierrez b60782959d feat: integrar RBAC y allowlist de usuarios en runtime y listener
Cambios en 3 archivos:
- agents/runtime.go: construye ACL desde config de roles, verifica permisos
  antes de ejecutar comandos (command:<name>), interacción LLM (ask) y
  ejecución de tools (tool:<name>). Mensajes denegados se loguean y
  responden al usuario.
- shell/matrix/listener.go: filtra invites y mensajes de usuarios no
  autorizados cuando se configura allowed_users (allowlist vacía = todos).
- internal/config/schema.go: añade campos AllowedUsers y
  UnauthorizedResponse a FiltersCfg para soportar la allowlist en config.

Esto conecta el paquete pkg/acl con el runtime para dar soporte completo
a control de acceso por rol, sin romper la compatibilidad (ACL vacío
permite todo como antes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:59:09 +00:00
egutierrez bb1e11f456 feat: sistema de prompts externos y mejoras en runtime de agentes
Añade pkg/command/prompts.go para cargar prompts desde archivos .md externos
en el directorio prompts/. Mejoras en agents/runtime.go para el manejo de
herramientas y flujo de ejecución. Nuevos comandos en agents/commands.go.
Ajustes menores en pkg/command/builtins.go para integrar las nuevas capacidades.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:17:00 +00:00
egutierrez 76ff9394d0 feat: respuestas como reply de Matrix + presencia online/offline
Añade soporte para que las respuestas de los bots sean replies nativos
de Matrix (m.in_reply_to) en lugar de mensajes sueltos. Los clientes
Matrix mostrarán el mensaje original citado.

Cambios:
- EventID en MessageContext para capturar el ID del evento entrante
- InReplyTo en ReplyAction para indicar a qué evento responder
- SendReplyMarkdown en el cliente Matrix (shell/matrix/client.go)
- Runner usa SendReplyMarkdown cuando InReplyTo está presente
- runtime.go pasa InReplyTo en todas las respuestas LLM y comandos
- SetPresence online al arrancar, offline al apagar (graceful)

No se tocan: herramientas, TUI, configuración de agentes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 15:46:07 +00:00
egutierrez 0eb9e8741d feat: añadir agente meteorologo con tool get_weather
Nuevo agente Matrix especializado en consultas meteorológicas.
Usa la API pública Open-Meteo (sin API key) para obtener
condiciones actuales y previsión de 3 días para cualquier ciudad.

Incluye:
- agents/meteorologo/ — reglas puras, config.yaml, system prompt
- tools/weather.go — tool get_weather (geocoding + forecast)
- Registro en runtime.go (tool registry) y launcher (rulesRegistry)

El agente responde a DMs y menciones delegando al LLM con tool_use
habilitado. No tiene comandos directos (!xxx).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 13:54:38 +00:00
egutierrez 828eb175fe feat: renderizar Markdown a HTML en mensajes Matrix con goldmark
Se reemplaza SendText por SendMarkdown en todos los puntos donde el agente
envía respuestas: runtime.go (comandos built-in y tareas orquestadas),
effects/runner.go (acciones Reply) y tools/matrix.go (matrix_send tool).

shell/matrix/client.go ahora usa goldmark para convertir Markdown a HTML real
en el campo FormattedBody del evento Matrix, cumpliendo con la spec de Matrix
para mensajes formateados. El Body conserva el markdown raw como fallback.

Se añade dependencia github.com/yuin/goldmark v1.7.16.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:21:06 +00:00
egutierrez 4b72b5ab28 feat: sistema RegisterCommand para comandos por agente
Añade RegisterCommand(spec, handler) al Agent para que cada agente pueda
registrar comandos propios (!xxx) sin modificar built-ins ni usar reglas.

Cambios principales:
- agents/runtime.go: nuevo método RegisterCommand + campo customSpecs
- agents/commands.go: !help muestra comandos del agente en sección separada,
  extrae writeSpec helper, elimina customCommandRules (ya no se usan reglas
  para comandos)
- handleEvent simplificado: los comandos se resuelven por lookup directo
  (built-in + registered), nunca pasan por reglas ni LLM

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 01:39:50 +00:00
egutierrez 33b11a63c8 feat: añadir sistema de comandos directos (!command)
Implementa pkg/command/ como core puro: tipos Spec/ParsedArgs, parser de
args key=value con soporte de comillas, specs de 8 comandos built-in
(help, tools, tool, ping, status, info, clear, version) y BuiltinNames()
para aliases.

En agents/runtime.go: nuevo flujo handleEvent que prioriza comandos sobre
LLM — custom rules del agente → built-in handlers → comando desconocido →
LLM fallback. Handlers en agents/commands.go. El comando !tool ejecuta
tools directamente via Registry con args key=value parseados.

LLM ahora es opcional: si no hay provider configurado, el agente corre
como simple_bot respondiendo solo a comandos.

Se extrae executeActions() como helper reutilizable para ambos flujos
(comando y no-comando).
2026-03-07 01:11:26 +00:00
egutierrez 69607b3a65 feat: añadir sistema de knowledge por agente
Implementa una base de conocimiento persistente por agente siguiendo
el patrón pure core / impure shell:

- pkg/knowledge/: tipos puros (Document, Store interface)
- shell/knowledge/: FileStore con SQLite para indexación y archivos .md
- tools/knowledge.go: 4 tools LLM (search, read, write, list)
- tools/knowledge_test.go: tests unitarios de las tools
- internal/config/schema.go: nuevo KnowledgeToolCfg en ToolsCfg
- agents/runtime.go: inicialización del store y registro de tools
- agents/*/knowledge/about-me.md: documentos semilla para cada agente

Cada agente puede buscar, leer, crear y actualizar documentos de
conocimiento. Los archivos .md viven en agents/<id>/knowledge/ y se
indexan en SQLite (agents/<id>/data/knowledge.db).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 23:02:39 +00:00
egutierrez 4634ad104b feat: añadir claude-code como proveedor LLM via claude -p
Implementa un nuevo proveedor LLM que ejecuta 'claude -p' como subproceso,
permitiendo usar Claude Code como backend de cualquier agente Matrix.

Cambios:
- pkg/llm/types.go: nueva constante ProviderClaudeCode
- pkg/llm/router.go: routing de 'claude-code' antes de 'claude*' (Anthropic API)
- internal/config/schema.go: nuevo tipo ClaudeCodeCfg con campos para binary,
  timeout, disable_tools, allowed/disallowed tools, permission_mode, model,
  fallback_model, session_id y add_dirs
- shell/llm/claudecode.go: provider completo — buildClaudeArgs(), flattenMessages(),
  parseClaudeOutput() y filterEnv() para limpiar ANTHROPIC_API_KEY del entorno
  y que claude use su propia auth OAuth
- shell/llm/factory.go: case 'claude-code' en FromConfig(), WithFallback() ahora
  recibe fallbackCfg para sobreescribir model/max_tokens al hacer fallback
- agents/runtime.go: actualizado para pasar fallbackCfg a WithFallback()

No se tocó: los proveedores existentes (anthropic.go, openai.go), el core puro
de decision ni el listener de Matrix.
2026-03-06 22:14:28 +00:00
egutierrez 5697b92ab8 feat: integrar structured logging en todos los componentes del shell
Se propaga *slog.Logger a todos los componentes impuros del shell:
- shell/bus/ — logs de subscribe, send, reply, timeout, unsubscribe
- shell/effects/ — duración y resultado de cada action ejecutada
- shell/llm/ (anthropic, openai, factory) — request/response con tokens, duración, fallback
- shell/memory/sqlite — open, save, recall, close con detalles
- shell/ssh/ — inicio, fin, errores y duración de comandos SSH
- tools/registry — registro, ejecución y errores de herramientas

Se usa el paquete shell/logger para field names consistentes (FieldDurationMS, FieldTokensUsed, etc.).
Cada componente recibe el logger por inyección de dependencias, sin globals.
Las firmas de New/FromConfig se actualizan para aceptar *slog.Logger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:53:31 +00:00
egutierrez 7176afde0a feat: update orchestrator for enhanced multi-bot management and room discovery 2026-03-06 17:03:08 +00:00
egutierrez 2667af52cc feat: implement multi-bot orchestration system with LLM routing
Implementa el sistema de orquestación para salas Matrix con múltiples bots.
El orquestador es un "special agent" sin identidad Matrix que coordina qué bot
responde y cuándo, usando LLM (Claude) para routing y evaluación de calidad.

Cambios principales:
- pkg/orchestration/task.go: tipos puros (TaskEvent, BotResponse, QualityScore, RoutingDecision)
- shell/orchestration/: runtime del orquestador (orchestrator.go, router.go, evaluator.go)
- agents/specials/orchestrator/: config + prompts (routing, quality, refinement)
- internal/config/: SpecialConfig, OrchestrationCfg, LoadSpecial()
- shell/bus/bus.go: protocolo request-reply (SendAndWait, Reply) para delegación
- shell/matrix/listener.go: InterceptFunc para interceptar eventos en salas orquestadas
- agents/runtime.go: SetBus, listenBus, handleTaskEvent para recibir tareas del orquestador
- cmd/launcher/main.go: creación de bus compartido, arranque del orquestador antes de bots

Incluye deduplicación para evitar que múltiples listeners en la misma sala
disparen el orquestador más de una vez por mensaje.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 09:05:42 +00:00
egutierrez 6bef4283c6 Remove outdated plans and implement new features for bot tools, memory, interaction, avatar management, and cron scheduling
- Deleted old plan files for bot memory, interaction, avatar, and cron.
- Added new task files for bot tools, memory, interaction, avatar, and cron scheduling with detailed designs and implementation notes.
- Updated `agents/runtime.go` to support memory clearing and message deletion from SQLite.
- Created necessary shell and package files for implementing bot tools and cron scheduling functionalities.
2026-03-06 01:18:53 +00:00
egutierrez cb9489e633 feat: implement memory management system with SQLite persistence, including conversation windows and episodic facts 2026-03-06 00:39:22 +00:00
egutierrez d26be78c46 feat: add rebuild and restart functionality for agents, including build process and status reporting 2026-03-06 00:13:15 +00:00
egutierrez a92fbff801 feat: update access token environment variables and enhance device signing process for E2EE agents; add verification script and system flow documentation 2026-03-05 23:46:07 +00:00
egutierrez 0f900d1560 feat: add recovery key support for E2EE agents, including configuration and documentation updates 2026-03-05 00:56:15 +00:00
egutierrez a7e28b0267 feat: add testing support for crypto initialization and process management, including auto-recovery and filtering of go wrapper processes 2026-03-05 00:28:01 +00:00
egutierrez 54fe479792 feat: implement end-to-end encryption (E2EE) support for agents with configuration and documentation updates 2026-03-05 00:06:32 +00:00
egutierrez dd4a101139 feat: add asistente-2 agent with tool-use and E2EE verification
Nuevo agente asistente-2 con herramienta current_time habilitada para
demostrar el flujo completo de tool-use (LLM → tool call → resultado → respuesta).

Incluye:
- agents/asistente2/: reglas puras, config con tool_use.enabled, system prompt
- tools/time.go: herramienta current_time (siempre disponible para todos los agentes)
- cmd/verify/: comando para subir cross-signing keys y eliminar el warning
  "Encrypted by a device not verified by its owner"
- Registro en runtime.go (current_time) y launcher/main.go (rulesRegistry)

El cmd/verify usa mautrix GenerateAndUploadCrossSigningKeysWithPassword
para configurar cross-signing via UIA con la password del bot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:38:55 +00:00
egutierrez 0f8d2f9ca0 feat: implement tool registry and add various tools for HTTP, file operations, SSH, and Matrix messaging 2026-03-04 21:10:29 +00:00
egutierrez 396fc39b90 bot contesta con e2ee 2026-03-04 00:59:10 +00:00
egutierrez c126187c5a Repo iniciado 2026-03-03 23:19:23 +00:00