Files
unibots/internal/config/schema.go
T
agent fc644ecd6e feat: import agents_and_robots platform as unibots (Matrix-out, unibus transport)
Reemplaza el scaffold del echobot por la plataforma completa de bots traida
desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out:
los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms +
E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client).

- go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths
  relativos reajustados a la nueva ubicacion dentro de fn_registry).
- app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales.
- modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports).

agents_and_robots queda archivado como museo de la era Matrix.
2026-06-07 11:50:13 +02:00

441 lines
20 KiB
Go

// Package config provides the configuration schema and loader for agents.
package config
import "time"
// AgentConfig is the root configuration for a single agent.
type AgentConfig struct {
Agent AgentMeta `yaml:"agent"`
Personality PersonalityCfg `yaml:"personality"`
LLM LLMCfg `yaml:"llm"`
Tools ToolsCfg `yaml:"tools"`
Bus BusCfg `yaml:"bus"`
SSH SSHCfg `yaml:"ssh"`
Security SecurityCfg `yaml:"security"`
Schedules []ScheduleCfg `yaml:"schedules"`
Storage StorageCfg `yaml:"storage"`
Memory MemoryCfg `yaml:"memory"`
Skills SkillsCfg `yaml:"skills"`
}
// ── Identity ──────────────────────────────────────────────────────────────
type AgentMeta struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Version string `yaml:"version"`
Type string `yaml:"type"` // "agent" (default) or "robot" (command-only, no LLM)
Enabled bool `yaml:"enabled"`
Template bool `yaml:"template"` // if true, launcher will skip this agent
Description string `yaml:"description"`
Tags []string `yaml:"tags"`
}
// ── Personality ───────────────────────────────────────────────────────────
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
}
type TemplatesCfg struct {
Greeting string `yaml:"greeting"`
UnknownCommand string `yaml:"unknown_command"`
PermissionDenied string `yaml:"permission_denied"`
Error string `yaml:"error"`
Success string `yaml:"success"`
Busy string `yaml:"busy"`
}
type BehaviorCfg struct {
Proactive bool `yaml:"proactive"`
AskConfirmation bool `yaml:"ask_confirmation"`
ShowReasoning bool `yaml:"show_reasoning"`
ThreadReplies bool `yaml:"thread_replies"`
TypingIndicator bool `yaml:"typing_indicator"`
AcknowledgeReceipt bool `yaml:"acknowledge_receipt"`
}
// 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
}
// ── LLM ───────────────────────────────────────────────────────────────────
type LLMCfg struct {
Primary LLMProviderCfg `yaml:"primary"`
Fallback LLMProviderCfg `yaml:"fallback"`
Reasoning LLMReasoningCfg `yaml:"reasoning"`
ToolUse LLMToolUseCfg `yaml:"tool_use"`
RateLimit LLMRateLimitCfg `yaml:"rate_limit"`
}
type LLMProviderCfg struct {
Provider string `yaml:"provider"`
Model string `yaml:"model"`
APIKeyEnv string `yaml:"api_key_env"`
BaseURL string `yaml:"base_url"`
MaxTokens int `yaml:"max_tokens"`
Temperature float64 `yaml:"temperature"`
// ClaudeCode holds configuration for the claude-code provider (claude -p).
ClaudeCode ClaudeCodeCfg `yaml:"claude_code"`
}
// ClaudeCodeCfg configures the claude -p subprocess provider.
type ClaudeCodeCfg struct {
Binary string `yaml:"binary"` // path to claude binary (default: "claude")
Timeout time.Duration `yaml:"timeout"` // subprocess timeout (default: 5m)
DisableTools bool `yaml:"disable_tools"` // pass --tools "" to disable all internal tools
AllowedTools []string `yaml:"allowed_tools"` // tools claude -p can use internally (e.g. Bash, Read, Edit)
DisallowedTools []string `yaml:"disallowed_tools"` // tools to block
WorkingDir string `yaml:"working_dir"` // working directory for claude -p
PermissionMode string `yaml:"permission_mode"` // default, acceptEdits, bypassPermissions, plan
Model string `yaml:"model"` // inner model: sonnet, opus, haiku, or full name
FallbackModel string `yaml:"fallback_model"` // fallback model if primary is overloaded
SessionID string `yaml:"session_id"` // fixed session ID for continuity
AddDirs []string `yaml:"add_dirs"` // additional directories accessible
}
type LLMReasoningCfg struct {
SystemPromptFile string `yaml:"system_prompt_file"`
ContextWindow int `yaml:"context_window"`
MemoryMessages int `yaml:"memory_messages"`
}
type LLMToolUseCfg struct {
Enabled bool `yaml:"enabled"`
MaxIterations int `yaml:"max_iterations"`
ParallelCalls bool `yaml:"parallel_calls"`
}
type LLMRateLimitCfg struct {
RequestsPerMinute int `yaml:"requests_per_minute"`
TokensPerMinute int `yaml:"tokens_per_minute"`
ConcurrentRequests int `yaml:"concurrent_requests"`
}
// ── Tools ─────────────────────────────────────────────────────────────────
type ToolsCfg struct {
SSH SSHToolCfg `yaml:"ssh"`
HTTP HTTPToolCfg `yaml:"http"`
Scripts ScriptsCfg `yaml:"scripts"`
FileOps FileOpsCfg `yaml:"file_ops"`
Bus BusToolCfg `yaml:"bus_send"`
MCP MCPToolCfg `yaml:"mcp"`
Memory MemoryToolCfg `yaml:"memory"`
Knowledge KnowledgeToolCfg `yaml:"knowledge"`
SharedKnowledge SharedKnowledgeToolCfg `yaml:"shared_knowledge"`
Skills SkillsToolCfg `yaml:"skills"`
IMDb IMDbToolCfg `yaml:"imdb"`
}
// BusToolCfg configures the bus_send tool, which lets the LLM post a message to
// an arbitrary unibus room. AllowedRooms restricts which room IDs can be
// targeted (empty = any room the bot belongs to).
type BusToolCfg struct {
AllowedRooms []string `yaml:"allowed_rooms"` // if non-empty, only these room IDs can be targeted
}
type KnowledgeToolCfg struct {
Enabled bool `yaml:"enabled"`
Dir string `yaml:"dir"` // default: "./knowledge" (relative to agent dir)
}
type SharedKnowledgeToolCfg struct {
Enabled bool `yaml:"enabled"` // default false
Dir string `yaml:"dir"` // default "knowledges" (relative to project root)
DBPath string `yaml:"db_path"` // default "knowledges/data/knowledge.db"
}
type SSHToolCfg struct {
Enabled bool `yaml:"enabled"`
AllowedTargets []string `yaml:"allowed_targets"`
AllowedCommands []string `yaml:"allowed_commands"` // allowlist: if non-empty, only these command prefixes are permitted
ForbiddenCommands []string `yaml:"forbidden_commands"`
Timeout time.Duration `yaml:"timeout"`
MaxConcurrent int `yaml:"max_concurrent"`
RequireConfirmation []string `yaml:"require_confirmation"`
}
type HTTPToolCfg struct {
Enabled bool `yaml:"enabled"`
AllowedDomains []string `yaml:"allowed_domains"`
Timeout time.Duration `yaml:"timeout"`
MaxRetries int `yaml:"max_retries"`
}
type ScriptsCfg struct {
Enabled bool `yaml:"enabled"`
ScriptsDir string `yaml:"scripts_dir"`
Allowed []string `yaml:"allowed"`
Timeout time.Duration `yaml:"timeout"`
Sandbox bool `yaml:"sandbox"`
}
type FileOpsCfg struct {
Enabled bool `yaml:"enabled"`
AllowedPaths []string `yaml:"allowed_paths"`
ReadOnly bool `yaml:"read_only"`
}
type MCPToolCfg struct {
Enabled bool `yaml:"enabled"`
Servers []MCPServerCfg `yaml:"servers"`
Expose MCPExposeCfg `yaml:"expose"`
}
type MCPServerCfg struct {
Name string `yaml:"name"` // nombre logico del servidor
Transport string `yaml:"transport"` // "stdio" | "sse" (default: auto-detect)
Command string `yaml:"command"` // stdio: comando a ejecutar
Args []string `yaml:"args"` // stdio: argumentos del comando
Env map[string]string `yaml:"env"` // stdio: variables de entorno extra
URL string `yaml:"url"` // sse: URL del servidor
Headers map[string]string `yaml:"headers"` // sse: headers HTTP extra (auth, etc.)
Tools []string `yaml:"tools"` // filtro: solo exponer estas tools (vacio = todas)
Prefix string `yaml:"prefix"` // prefijo para nombres de tools (evitar colisiones)
Timeout time.Duration `yaml:"timeout"` // timeout por llamada (default: 30s)
}
type MCPExposeCfg struct {
Port int `yaml:"port"`
Tools []string `yaml:"tools"`
}
// ── Bus ───────────────────────────────────────────────────────────────────
// BusCfg configures the unibus transport: where to reach the NATS data plane
// and the membershipd control plane, the bot's long-term identity, and how it
// detects mentions and commands. It replaces the former MatrixCfg now that the
// ecosystem speaks only over unibus.
type BusCfg struct {
NatsURL string `yaml:"nats_url"` // NATS data plane, e.g. nats://host:4250
CtrlURL string `yaml:"ctrl_url"` // membershipd control plane, e.g. http://host:8470
IdentityPath string `yaml:"identity_path"` // path to the bot's long-term identity file (created if absent)
Handle string `yaml:"handle"` // bot handle used for mention detection (e.g. "meteorologo")
CommandPrefix string `yaml:"command_prefix"` // command marker, default "!"
Threads ThreadsCfg `yaml:"threads"` // thread/reply behavior (transport-neutral)
}
// ThreadsCfg controls threaded-reply behavior (transport-neutral: applies to
// any fabric that carries a thread root id).
type ThreadsCfg struct {
Enabled bool `yaml:"enabled"` // respond in threads when message is in a thread (default true)
AutoThread bool `yaml:"auto_thread"` // auto-create a thread for each new conversation (default false)
}
// ── SSH Inventory ─────────────────────────────────────────────────────────
type SSHCfg struct {
Defaults SSHDefaultsCfg `yaml:"defaults"`
Targets map[string]SSHTargetCfg `yaml:"targets"`
}
type SSHDefaultsCfg struct {
User string `yaml:"user"`
Port int `yaml:"port"`
KeyFileEnv string `yaml:"key_file_env"`
KnownHosts string `yaml:"known_hosts"`
KeepaliveInterval time.Duration `yaml:"keepalive_interval"`
Timeout time.Duration `yaml:"timeout"`
}
type SSHTargetCfg struct {
Hosts []string `yaml:"hosts"`
User string `yaml:"user"`
Port int `yaml:"port"`
JumpHost string `yaml:"jump_host"`
KeyFileEnv string `yaml:"key_file_env"`
}
// ── Security ──────────────────────────────────────────────────────────────
type SecurityCfg struct {
// Deprecated: use security/ centralized groups instead (see security/user-groups.yaml, permissions.yaml).
// Kept for backward compatibility; will be removed in a future issue.
Roles map[string]RoleCfg `yaml:"roles"`
Audit AuditCfg `yaml:"audit"`
Secrets SecretsCfg `yaml:"secrets"`
Sanitize SanitizeCfg `yaml:"sanitize"`
ToolRateLimit ToolRateLimitCfg `yaml:"tool_rate_limit"`
}
// ToolRateLimitCfg controls per-room rate limiting of tool executions.
type ToolRateLimitCfg struct {
Enabled bool `yaml:"enabled"` // enable tool rate limiting (default false)
MaxCallsPerMin int `yaml:"max_calls_per_min"` // max tool calls per room per minute (default 10)
CleanupIntervalS int `yaml:"cleanup_interval_s"` // seconds between stale entry cleanup (default 60)
}
// SanitizeCfg controls prompt injection detection on incoming messages.
type SanitizeCfg struct {
Enabled bool `yaml:"enabled"` // enable sanitization (default false)
Mode string `yaml:"mode"` // warn | strip | reject (default warn)
MinSeverity string `yaml:"min_severity"` // low | medium | high (default medium)
DisabledPatterns []string `yaml:"disabled_patterns"` // pattern names to skip
}
type RoleCfg struct {
Users []string `yaml:"users"`
Actions []string `yaml:"actions"`
}
type AuditCfg struct {
Enabled bool `yaml:"enabled"`
LogFile string `yaml:"log_file"`
LogToRoom string `yaml:"log_to_room"`
Include []string `yaml:"include"`
}
type SecretsCfg struct {
Provider string `yaml:"provider"` // env | vault | sops
}
// ── Scheduling ────────────────────────────────────────────────────────────
type ScheduleCfg struct {
Name string `yaml:"name"`
Cron string `yaml:"cron"`
Action ScheduledAction `yaml:"action"`
OnFailure FailureAction `yaml:"on_failure"`
OutputRoom string `yaml:"output_room"`
}
type ScheduledAction struct {
Kind string `yaml:"kind"`
Target string `yaml:"target"`
Command string `yaml:"command"`
Script string `yaml:"script"`
// Phase 1: send_message and llm_prompt fields
Message string `yaml:"message"` // inline text for send_message
Template string `yaml:"template"` // path to .md file for send_message
Prompt string `yaml:"prompt"` // inline prompt text for llm_prompt
}
type FailureAction struct {
NotifyRoom string `yaml:"notify_room"`
EscalateTo string `yaml:"escalate_to"`
}
// ── Storage ───────────────────────────────────────────────────────────────
type StorageCfg struct {
BasePath string `yaml:"base_path"` // root for all data; default $AGENTS_DATA_DIR/<id> or agents/<id>/data
State StateStorageCfg `yaml:"state"`
Cache CacheStorageCfg `yaml:"cache"`
History HistoryStorageCfg `yaml:"history"`
}
type StateStorageCfg struct {
Backend string `yaml:"backend"` // sqlite | redis | file
Path string `yaml:"path"`
}
type CacheStorageCfg struct {
Enabled bool `yaml:"enabled"`
Backend string `yaml:"backend"` // memory | redis
TTL time.Duration `yaml:"ttl"`
MaxEntries int `yaml:"max_entries"`
}
type HistoryStorageCfg struct {
Backend string `yaml:"backend"`
Path string `yaml:"path"`
Retention time.Duration `yaml:"retention"`
}
// ── Memory ────────────────────────────────────────────────────────────────
type MemoryCfg struct {
Enabled bool `yaml:"enabled"`
WindowSize int `yaml:"window_size"` // sliding window size per room (default 20)
DBPath string `yaml:"db_path"` // SQLite path (default agents/<id>/data/memory.db)
}
type MemoryToolCfg struct {
Enabled bool `yaml:"enabled"`
}
// ── Skills ────────────────────────────────────────────────────────────────
type SkillsCfg struct {
Enabled bool `yaml:"enabled"` // enable skills system (default false)
SkillsPath string `yaml:"path"` // path to skills directory (default: "skills/")
Categories []string `yaml:"categories"` // filter: only load skills from these categories (empty = all)
Timeout time.Duration `yaml:"timeout"` // timeout for script execution (default: 60s)
}
type SkillsToolCfg struct {
AllowedInterpreters []string `yaml:"allowed_interpreters"` // allowlist for skill script execution (default: ["bash", "sh"])
}
type IMDbToolCfg struct {
Enabled bool `yaml:"enabled"`
APIKey string `yaml:"api_key"` // OMDb API key (get from http://www.omdbapi.com/)
APIKeyEnv string `yaml:"api_key_env"` // env var name for API key (e.g., "OMDB_API_KEY")
Timeout time.Duration `yaml:"timeout"` // timeout for API requests (default: 10s)
}
// ── Special Agents ────────────────────────────────────────────────────────
// SpecialConfig is the root configuration for a special agent (no Matrix identity).
type SpecialConfig struct {
Special SpecialMeta `yaml:"special"`
LLM LLMCfg `yaml:"llm"`
Orchestration OrchestrationCfg `yaml:"orchestration"`
}
// SpecialMeta identifies a special agent.
type SpecialMeta struct {
ID string `yaml:"id"`
Type string `yaml:"type"` // "orchestrator", "scheduler", etc.
Enabled bool `yaml:"enabled"`
Description string `yaml:"description"`
}
// OrchestrationCfg configures the multi-bot orchestrator.
type OrchestrationCfg struct {
MaxIterations int `yaml:"max_iterations"`
QualityThreshold float64 `yaml:"quality_threshold"`
DelegationTimeout time.Duration `yaml:"delegation_timeout"`
RepetitionThreshold float64 `yaml:"repetition_threshold"` // 0-1: similarity ratio to detect circular conversations
Rooms []OrchestratedRoomCfg `yaml:"rooms"`
}
// OrchestratedRoomCfg defines a room managed by the orchestrator.
type OrchestratedRoomCfg struct {
RoomID string `yaml:"room_id"`
Participants []string `yaml:"participants"` // bot IDs that participate in this room
}