Issue 0014 completado: ✅ Fase 1: Sistema de personalidades enriquecido - PersonalityCfg ampliado con role, backstory, expertise, limitations - CommunicationCfg con formality, humor, personality, response_style, quirks - BuildPersonalityPrompt() genera bloque para system prompt - Integrado en runtime con FromConfig + concatenacion automatica ✅ Fase 2: Agente plantilla (_template) - Campo Template bool en AgentMeta (launcher lo filtra) - agents/_template/ completo con todas las secciones documentadas - agent.go + prompts/system.md + config.yaml canonica - new-agent.sh actualizado para copiar desde _template/ ✅ Fase 3: Ejemplos de personalidades - PERSONALITIES.md con 4 perfiles: DevOps pragmatico, Analista meticuloso, Asistente amigable, Guardian de seguridad ✅ Fase 4: Comando !info enriquecido - Metadata completa: identidad, personalidad, LLM, tools, skills, knowledge, memoria, schedules, uptime Fase 5 (estandarizar configs existentes): aplazada — los agentes actuales funcionan correctamente. Los nuevos agentes usaran el template completo. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
20 KiB
014 — Agente plantilla + sistema de personalidades + estandarizacion
Objetivo
Crear un agente plantilla (no lanzable) que sirva como referencia canonica para la configuracion de todos los agentes. Incluir un sistema de personalidades rico que permita definir agentes con caracteres distintos. Enriquecer !info para mostrar metadata completa. Estandarizar los config.yaml existentes integrando las nuevas capacidades del proyecto: skills, shared-knowledge, cron jobs.
Contexto
- El launcher descubre agentes via
agents/*/config.yaml(glob en cmd/launcher/main.go) !infoexiste como built-in enagents/commands.gopero solo muestra: nombre, ID, version, descripcion- No hay herencia de configs ni template base — cada config.yaml es autocontenido
- Agentes actuales: assistant-bot, asistente-2
- La seccion
personalityactual es basica: tone, verbosity, emoji_style, templates, behavior - Nuevas capacidades en desarrollo: skills (016), shared-knowledge (018), cron jobs (005)
Tareas
Fase 1: Sistema de personalidades enriquecido
El sistema actual (pkg/personality/traits.go + PersonalityCfg en schema.go) define tone, verbosity, emoji, error_style, templates y behavior. Esto es funcional pero plano — todos los agentes terminan sonando igual con variaciones menores.
El objetivo es ampliar la personalidad para que cada agente tenga un caracter unico que se refleje en como habla, piensa y actua.
-
1.1 Ampliar
PersonalityCfgeninternal/config/schema.gocon nuevos campos:type PersonalityCfg struct { // --- campos existentes (sin cambios) --- Tone string `yaml:"tone"` Verbosity string `yaml:"verbosity"` Language string `yaml:"language"` LanguagesSupported []string `yaml:"languages_supported"` EmojiStyle string `yaml:"emoji_style"` Prefix string `yaml:"prefix"` ErrorStyle string `yaml:"error_style"` Templates TemplatesCfg `yaml:"templates"` Behavior BehaviorCfg `yaml:"behavior"` // --- NUEVOS campos --- // Identidad narrativa Role string `yaml:"role"` // rol principal: "asistente general", "devops engineer", "analista de datos" Backstory string `yaml:"backstory"` // breve historia/contexto del personaje (1-3 frases) Expertise []string `yaml:"expertise"` // areas de experiencia: ["linux", "docker", "monitoring"] Limitations []string `yaml:"limitations"` // que NO sabe o no debe intentar // Estilo de comunicacion Communication CommunicationCfg `yaml:"communication"` // Directivas de comportamiento en texto libre CustomDirectives []string `yaml:"custom_directives"` // instrucciones adicionales para el system prompt } // CommunicationCfg define como se expresa el agente mas alla del tone basico. type CommunicationCfg struct { Formality string `yaml:"formality"` // formal | semiformal | casual | coloquial Humor string `yaml:"humor"` // none | subtle | moderate | frequent Personality string `yaml:"personality"` // analytical | creative | pragmatic | empathetic | assertive ResponseStyle string `yaml:"response_style"` // structured | conversational | bullet_points | narrative Quirks []string `yaml:"quirks"` // rasgos unicos: ["usa analogias de cocina", "cita a Linus Torvalds"] AvoidTopics []string `yaml:"avoid_topics"` // temas que evita o redirige Catchphrases []string `yaml:"catchphrases"` // frases tipicas que usa ocasionalmente } -
1.2 Ampliar tipos puros en
pkg/personality/traits.go:type Formality string const ( FormalityFormal Formality = "formal" FormalitySemiformal Formality = "semiformal" FormalityCasual Formality = "casual" FormalityColoquial Formality = "coloquial" ) type Humor string const ( HumorNone Humor = "none" HumorSubtle Humor = "subtle" HumorModerate Humor = "moderate" HumorFrequent Humor = "frequent" ) type PersonalityType string const ( PersonalityAnalytical PersonalityType = "analytical" PersonalityCreative PersonalityType = "creative" PersonalityPragmatic PersonalityType = "pragmatic" PersonalityEmpathetic PersonalityType = "empathetic" PersonalityAssertive PersonalityType = "assertive" ) type ResponseStyle string const ( ResponseStructured ResponseStyle = "structured" ResponseConversational ResponseStyle = "conversational" ResponseBulletPoints ResponseStyle = "bullet_points" ResponseNarrative ResponseStyle = "narrative" )Ampliar el struct
Personalitycon los nuevos campos correspondientes. -
1.3 Crear funcion
BuildPersonalityPrompt(cfg PersonalityCfg) stringenpkg/personality/que genere un bloque de system prompt a partir de la config de personalidad. Esta funcion es pura — recibe config, devuelve string. El runtime la usa para inyectar personalidad en el prompt del LLM.El prompt generado debe incluir:
- Rol y backstory
- Expertise y limitaciones
- Estilo de comunicacion (formality, humor, personality, response_style)
- Quirks y catchphrases
- Custom directives
- Todo redactado como instrucciones naturales para el LLM
Ejemplo de output:
## Tu personalidad Eres un ingeniero DevOps senior con 10 anos de experiencia en Linux y containers. **Rol**: DevOps engineer especializado en infraestructura y monitoring. **Expertise**: Linux, Docker, Kubernetes, Prometheus, bash scripting. **Limitaciones**: No das consejos de frontend ni diseno UI. **Como te comunicas**: - Tono semiformal, directo pero amable - Humor sutil — algun comentario ironico cuando algo falla de forma obvia - Estilo pragmatico — siempre priorizas la solucion sobre la teoria - Respuestas estructuradas con comandos claros - A veces citas a Linus Torvalds o usas analogias mecanicas **Directivas especiales**: - Siempre sugiere verificar con un dry-run antes de ejecutar cambios destructivos - Cuando algo falla, muestra el log relevante antes de diagnosticar -
1.4 Integrar
BuildPersonalityPromptenagents/runtime.go— concatenar el bloque de personalidad al system prompt leido del archivo. El orden debe ser: system prompt del archivo + bloque de personalidad generado.
Fase 2: Agente plantilla con personalidades de ejemplo
-
2.1 Anadir campo
Template boolaAgentMetaeninternal/config/schema.go -
2.2 Filtrar agentes template en
cmd/launcher/main.go— skip sicfg.Agent.Template == true -
2.3 Crear
agents/_template/config.yaml— referencia canonica con TODAS las secciones. Incluir:Identidad:
agent: id: "_template" name: "Template Agent" version: "0.0.0" enabled: true template: true # el launcher ignora este agente description: "Agente plantilla. No se lanza. Sirve como referencia para crear nuevos agentes." tags: [template]Personalidad completa (con todos los campos nuevos documentados):
personality: # --- Identidad narrativa --- role: "asistente general" backstory: "Un asistente amigable creado para ayudar con tareas cotidianas." expertise: [general] limitations: [] # --- Estilo basico --- tone: friendly # direct | friendly | formal | casual | technical verbosity: concise # minimal | concise | detailed | verbose language: es languages_supported: [es, en] emoji_style: minimal # none | minimal | moderate | heavy prefix: "" error_style: helpful # terse | helpful | detailed # --- Comunicacion avanzada --- communication: formality: semiformal # formal | semiformal | casual | coloquial humor: none # none | subtle | moderate | frequent personality: pragmatic # analytical | creative | pragmatic | empathetic | assertive response_style: structured # structured | conversational | bullet_points | narrative quirks: [] # rasgos unicos del personaje avoid_topics: [] # temas a evitar catchphrases: [] # frases tipicas # --- Directivas libres --- custom_directives: [] # instrucciones extra para el system prompt # --- Templates de respuesta --- templates: greeting: "Hola, soy {name}. En que puedo ayudarte?" unknown_command: "No entiendo ese comando. Usa !help." permission_denied: "No tienes permiso para eso." error: "Algo salio mal: {{.Error}}" success: "{{.Summary}}" busy: "Estoy procesando otra solicitud, un momento..." # --- Comportamiento --- behavior: proactive: false ask_confirmation: false show_reasoning: false thread_replies: true typing_indicator: true acknowledge_receipt: falseSkills (nueva seccion):
skills: enabled: false path: "skills/" # ruta base de skills (relativa al proyecto) categories: [] # vacio = todas las categorias | ["devops", "system"] = filtradasShared knowledge (nueva seccion):
# Dentro de tools: tools: # ... tools existentes ... shared_knowledge: enabled: false dir: "knowledges" # directorio compartido db_path: "knowledges/data/knowledge.db"Schedules con ejemplos:
schedules: # - name: "buenos-dias" # cron: "0 9 * * 1-5" # action: # kind: llm_prompt # target: "Buenos dias equipo. Dame un resumen rapido del estado de los servicios." # output_room: "!roomid:server.com" # on_failure: # notify_room: "" # escalate_to: ""Incluir TODAS las demas secciones (llm, matrix, agents, ssh, security, observability, resilience, storage, memory) con valores por defecto documentados.
-
2.4 Crear
agents/_template/agent.gominimo conRules()retornando slice vacio -
2.5 Crear
agents/_template/prompts/system.mdcon un system prompt plantilla que muestre donde va cada seccion (instrucciones base, personalidad inyectada automaticamente, tools disponibles, etc.) -
2.6 Actualizar
dev-scripts/agent/new-agent.shpara copiar desde_template/en lugar de generar inline
Fase 3: Ejemplos de personalidades distintas
Para demostrar que el sistema funciona, definir perfiles de personalidad que se puedan usar como punto de partida. Estos van como comentarios/documentacion en el template, NO como agentes reales.
-
3.1 Documentar en
agents/_template/PERSONALITIES.mdal menos 4 perfiles de ejemplo:Perfil: DevOps pragmatico
personality: role: "ingeniero DevOps senior" backstory: "Veterano de infraestructura con cicatrices de guerra de incidentes en produccion." expertise: [linux, docker, kubernetes, monitoring, bash, networking] limitations: ["no da consejos de frontend", "no hace diseno UI"] tone: direct verbosity: concise communication: formality: semiformal humor: subtle personality: pragmatic response_style: structured quirks: ["usa analogias mecanicas", "siempre pide ver los logs primero"] catchphrases: ["primero los logs, despues las teorias", "en produccion no se experimenta"] custom_directives: - "Siempre sugiere dry-run antes de cambios destructivos" - "Incluye el comando exacto, no solo la descripcion"Perfil: Analista meticuloso
personality: role: "analista de datos" backstory: "Obsesionado con los patrones y las anomalias. Nada escapa a su atencion." expertise: [analisis de logs, metricas, estadistica, patrones de errores] limitations: ["no ejecuta cambios en produccion", "no toma decisiones operativas"] tone: technical verbosity: detailed communication: formality: formal humor: none personality: analytical response_style: structured quirks: ["siempre cuantifica", "pide rango de fechas antes de analizar"] catchphrases: ["los datos no mienten", "correlacion no implica causalidad"]Perfil: Asistente amigable
personality: role: "asistente personal" backstory: "Siempre dispuesto a ayudar, paciente y claro en sus explicaciones." expertise: [tareas generales, redaccion, organizacion, resumen] limitations: ["no tiene acceso a servidores", "no ejecuta codigo"] tone: friendly verbosity: concise communication: formality: casual humor: subtle personality: empathetic response_style: conversational quirks: ["pregunta si quieres mas detalle", "celebra cuando termina una tarea"] catchphrases: ["listo!", "algo mas en lo que pueda ayudar?"]Perfil: Guardian de seguridad
personality: role: "especialista en seguridad" backstory: "Paranoico profesional. Asume que todo esta comprometido hasta demostrar lo contrario." expertise: [seguridad, auditoria, permisos, CVEs, hardening] limitations: ["no implementa features", "no optimiza performance"] tone: formal verbosity: detailed communication: formality: formal humor: none personality: assertive response_style: bullet_points quirks: ["siempre menciona el principio de minimo privilegio", "pide MFA para todo"] catchphrases: ["confiar pero verificar", "eso necesita un CVE review"] custom_directives: - "Nunca sugieras deshabilitar firewalls o SELinux como solucion" - "Siempre recomienda rotar credenciales despues de un incidente"
Fase 4: Enriquecer !info
-
4.1 Modificar el handler de
!infoenagents/commands.gopara que devuelva:- Nombre, ID, version, descripcion
- Personalidad: role, tone, formality, personality type, humor
- LLM: provider + modelo
- Tools habilitadas (lista de nombres)
- Skills habilitadas (si/no + categorias + cantidad)
- Knowledge: privado (si/no), compartido (si/no)
- Memoria: si/no + window size
- Schedules: cantidad de cron jobs configurados
- Uptime del agente
-
4.2 Formatear como markdown legible con secciones
-
4.3 No exponer datos sensibles (tokens, API keys, paths internos, passwords)
Fase 5: Estandarizar configs existentes
-
5.1 Definir convenciones estandar obligatorias para todo config.yaml:
agent.versionsiempre presente (semver)agent.tagssiempre presente (al menos un tag)personality.rolesiempre presentepersonality.languageypersonality.languages_supportedsiempre explicitospersonality.communicationsiempre presente (al menos formality y personality)personality.behaviorsiempre con las 6 clavesllm.tool_usesiempre explicito (enabled true/false, max_iterations)tools.memoryytools.knowledgesiempre presentes (enabled true/false)matrix.homeserverymatrix.encryptionsiempre presentesobservability.logging.levelsiempre explicito- Si
skills.enabled: true, al menosskills.pathdefinido - Si
schedulestiene entradas, cada una connameycronvalidos
-
5.2 Actualizar
agents/assistant-bot/config.yaml— anadir personalidad rica:personality: role: "asistente general" backstory: "Asistente polivalente, siempre listo para ayudar con cualquier tarea." expertise: [general, redaccion, resumen, consultas] limitations: [] communication: formality: semiformal humor: subtle personality: empathetic response_style: conversational quirks: [] avoid_topics: [] catchphrases: [] custom_directives: [] # ... mas secciones nuevas (skills, shared_knowledge, etc.) -
5.3 Actualizar
agents/asistente-2/config.yaml— idem, personalidad diferenciada -
5.4 Validar que ambos agentes arrancan correctamente tras los cambios
Fase 6: Integracion con nuevas capacidades en config
Las tasks 005 (cron), 016 (skills) y 018 (shared-knowledge) definen nuevos sistemas. El template debe incluir sus secciones de config para que nuevos agentes ya las tengan disponibles.
-
6.1 Anadir
SkillsCfgalAgentConfigen schema.go (si no lo hizo la task 016):type SkillsCfg struct { Enabled bool `yaml:"enabled"` Path string `yaml:"path"` // default: "skills/" Categories []string `yaml:"categories"` // filtro de categorias } -
6.2 Anadir
SharedKnowledgeCfgalToolsCfgen schema.go (si no lo hizo la task 018):type SharedKnowledgeCfg struct { Enabled bool `yaml:"enabled"` Dir string `yaml:"dir"` // default: "knowledges" DBPath string `yaml:"db_path"` // default: "knowledges/data/knowledge.db" } -
6.3 Verificar que
ScheduleCfgsoporta los 3 tipos de accion (send_message, run_tool, llm_prompt) — el schema actual ya los tiene pero validar completitud -
6.4 Actualizar el template con las secciones de skills, shared_knowledge y schedules de ejemplo
Fase 7: Documentacion y tooling
-
7.1 Anadir validacion en
internal/config/loader.goque emita warnings si faltan secciones recomendadas (no bloquear, solo log):- personality.role vacio
- personality.communication sin definir
- skills.enabled true pero sin path
- schedules con entradas sin name
-
7.2 Actualizar
.claude/rules/create_agent.mdpara:- Referenciar el template como punto de partida
- Incluir paso de definir personalidad rica
- Incluir paso de decidir skills y shared-knowledge
-
7.3 Actualizar
docs/creating-agents.mdcon la seccion de personalidades -
7.4 Actualizar
CLAUDE.md— agregarSkillsCfgySharedKnowledgeCfga la descripcion del schema
Orden de ejecucion recomendado
- Fase 1 (sistema de personalidades) — tipos puros + BuildPersonalityPrompt + integracion runtime
- Fase 2 (template) — config.yaml canonica con todo documentado
- Fase 3 (ejemplos de personalidades) — PERSONALITIES.md como referencia
- Fase 5 (estandarizar configs) — aplicar nuevos campos a agentes existentes
- Fase 4 (info) — mostrar la metadata enriquecida
- Fase 6 (nuevas capacidades) — integrar skills/knowledge/cron en schema si no existen
- Fase 7 (docs) — cuando todo este estable
Dependencias con otras tasks
| Task | Relacion |
|---|---|
| 005 (cron) | El template incluye schedules de ejemplo. Si 005 no esta implementado, los schedules son solo config sin efecto. |
| 016 (skills) | El template incluye skills: config. Si 016 no esta implementado, el runtime ignora la seccion. |
| 018 (shared-knowledge) | El template incluye shared_knowledge: config. Si 018 no esta implementado, el runtime la ignora. |
Esta task puede ejecutarse antes que 005/016/018 — solo define el schema y template. Las otras tasks implementan la funcionalidad real.
Decisiones de diseno
- Personalidad en config, no en codigo: la personalidad se define 100% en YAML y se transforma a prompt via
BuildPersonalityPrompt. Cero logica de personalidad en Go. - BuildPersonalityPrompt es pura: vive en
pkg/personality/, recibe datos, devuelve string. Sin side effects. - Personalidad se concatena al system prompt: no reemplaza el archivo
prompts/system.md, se anade despues. El archivo define instrucciones base, la personalidad anade caracter. - Template parseable: el config.yaml del template es YAML valido con
template: true. Sirve como test de que el schema esta completo. - Backwards compatible: los campos nuevos son opcionales. Agentes existentes sin
communicationorolesiguen funcionando —BuildPersonalityPromptgenera un bloque vacio/minimo si no hay datos. - PERSONALITIES.md como catalogo: no son agentes reales, son perfiles de referencia. Al crear un agente nuevo, se copia un perfil y se ajusta.