refactor: eliminar structs muertos del config schema

Elimina 14 structs nunca referenciados en el codebase:
- ObservabilityCfg y sub-structs (LoggingCfg, MetricsCfg, HealthCfg, TracingCfg)
- ResilienceCfg y sub-structs (CircuitBreakerCfg, RetryCfg, ShutdownCfg, QueueCfg)
- AgentsCfg y sub-structs (PeerCfg, DelegationCfg, ProtocolCfg)

Se eliminan los campos Agents, Observability y Resilience del AgentConfig root.
CommunicationCfg se mantiene porque esta activamente usada por pkg/personality/
y agents/commands.go.

schema.go pasa de 561 lineas / 61 structs a 460 lineas / 47 structs.
El template _template/config.yaml se reduce de 414 a ~220 lineas.
Los configs de assistant-bot y asistente-2 se limpian de secciones muertas.

yaml.v3 ignora campos extra, asi que YAMLs antiguos siguen parseando sin error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 23:01:53 +00:00
parent fc235c71c6
commit 2bf3d289ac
4 changed files with 83 additions and 505 deletions
+79 -231
View File
@@ -1,51 +1,48 @@
# ============================================ # ============================================
# AGENTE PLANTILLA # AGENTE PLANTILLA
# ============================================ # ============================================
# Este archivo sirve como referencia canonica para la configuracion de todos los agentes. # Referencia canonica de configuracion. NO se lanza (template: true).
# NO se lanza (template: true). Copiar y adaptar para crear nuevos agentes. # Copiar y adaptar para nuevos agentes. Solo incluye campos funcionales.
agent: agent:
id: "_template" id: "_template"
name: "Template Agent" name: "Template Agent"
version: "0.0.0" version: "0.0.0"
enabled: true enabled: true
template: true # el launcher ignora este agente template: true # el launcher ignora este agente
description: "Agente plantilla. No se lanza. Sirve como referencia para crear nuevos agentes." description: "Agente plantilla. No se lanza."
tags: [template] tags: [template]
# ============================================ # ============================================
# PERSONALIDAD Y COMPORTAMIENTO # PERSONALIDAD Y COMPORTAMIENTO
# ============================================ # ============================================
personality: personality:
# --- Identidad narrativa --- tone: friendly # direct | friendly | formal | casual | technical
role: "asistente general" verbosity: concise # minimal | concise | detailed | verbose
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 language: es
languages_supported: [es, en] languages_supported: [es, en]
emoji_style: minimal # none | minimal | moderate | heavy emoji_style: minimal # none | minimal | moderate | heavy
prefix: "" prefix: ""
error_style: helpful # terse | helpful | detailed error_style: helpful # terse | helpful | detailed
# --- Comunicacion avanzada --- # Identidad narrativa (opcional)
role: ""
backstory: ""
expertise: []
limitations: []
# Comunicacion avanzada (opcional)
communication: communication:
formality: semiformal # formal | semiformal | casual | coloquial formality: semiformal # formal | semiformal | casual | coloquial
humor: none # none | subtle | moderate | frequent humor: none # none | subtle | moderate | frequent
personality: pragmatic # analytical | creative | pragmatic | empathetic | assertive personality: pragmatic # analytical | creative | pragmatic | empathetic | assertive
response_style: structured # structured | conversational | bullet_points | narrative response_style: structured # structured | conversational | bullet_points | narrative
quirks: [] # rasgos unicos del personaje quirks: []
avoid_topics: [] # temas a evitar avoid_topics: []
catchphrases: [] # frases tipicas catchphrases: []
# --- Directivas libres --- custom_directives: []
custom_directives: [] # instrucciones extra para el system prompt
# --- Templates de respuesta ---
templates: templates:
greeting: "Hola, soy {name}. En que puedo ayudarte?" greeting: "Hola, soy {name}. En que puedo ayudarte?"
unknown_command: "No entiendo ese comando. Usa !help." unknown_command: "No entiendo ese comando. Usa !help."
@@ -54,7 +51,6 @@ personality:
success: "{{.Summary}}" success: "{{.Summary}}"
busy: "Estoy procesando otra solicitud, un momento..." busy: "Estoy procesando otra solicitud, un momento..."
# --- Comportamiento ---
behavior: behavior:
proactive: false proactive: false
ask_confirmation: false ask_confirmation: false
@@ -64,49 +60,45 @@ personality:
acknowledge_receipt: false acknowledge_receipt: false
# ============================================ # ============================================
# LLM — CONEXION Y RAZONAMIENTO # LLM
# ============================================ # ============================================
llm: llm:
primary: primary:
provider: openai # openai | anthropic | claude-code provider: openai # openai | anthropic | claude-code
model: "gpt-4o" model: "gpt-4o"
api_key_env: OPENAI_API_KEY api_key_env: OPENAI_API_KEY
base_url: "" # opcional: custom endpoint base_url: ""
max_tokens: 4096 max_tokens: 4096
temperature: 0.7 temperature: 0.7
# Claude Code: subproceso claude -p (solo si provider: claude-code) # Solo si provider: claude-code
claude_code: claude_code:
binary: "claude" binary: "claude"
timeout: 3m timeout: 3m
disable_tools: false disable_tools: false
allowed_tools: [] # vacio = permitir todas allowed_tools: []
disallowed_tools: [] disallowed_tools: []
working_dir: "" # default: tmpdir aislado working_dir: "" # IMPORTANTE: configurar fuera del repo
permission_mode: "default" # default | acceptEdits | bypassPermissions | plan permission_mode: "default"
model: "sonnet" # sonnet | opus | haiku | full model name model: "sonnet"
fallback_model: "" fallback_model: ""
session_id: "" session_id: ""
add_dirs: [] add_dirs: []
# Fallback LLM (opcional)
fallback: fallback:
provider: "" provider: ""
model: "" model: ""
api_key_env: "" api_key_env: ""
base_url: ""
max_tokens: 0
temperature: 0
reasoning: reasoning:
system_prompt_file: "prompts/system.md" # relativo a agents/<id>/ system_prompt_file: "prompts/system.md"
context_window: 16384 context_window: 16384
memory_messages: 30 # mensajes previos a incluir en el contexto memory_messages: 30
tool_use: tool_use:
enabled: false # habilitar function calling enabled: false
max_iterations: 5 # ciclos tool-call → execute → feedback max_iterations: 5
parallel_calls: false # permitir llamadas paralelas a tools parallel_calls: false
rate_limit: rate_limit:
requests_per_minute: 60 requests_per_minute: 60
@@ -114,89 +106,80 @@ llm:
concurrent_requests: 5 concurrent_requests: 5
# ============================================ # ============================================
# TOOLS — HERRAMIENTAS DISPONIBLES # TOOLS
# ============================================ # ============================================
tools: tools:
ssh: ssh:
enabled: false enabled: false
allowed_targets: [] # lista de targets definidos en ssh.targets allowed_targets: []
allowed_commands: [] # allowlist: si no esta vacio, solo estos comandos allowed_commands: []
forbidden_commands: [] # blocklist forbidden_commands: []
timeout: 30s timeout: 30s
max_concurrent: 3 max_concurrent: 3
require_confirmation: [] # comandos que necesitan confirmacion require_confirmation: []
http: http:
enabled: false enabled: false
allowed_domains: [] # si no esta vacio, solo estos dominios allowed_domains: []
timeout: 10s timeout: 10s
max_retries: 2 max_retries: 2
scripts: scripts:
enabled: false enabled: false
scripts_dir: "./scripts" scripts_dir: "./scripts"
allowed: [] # si no esta vacio, solo estos scripts allowed: []
timeout: 60s timeout: 60s
sandbox: false sandbox: false
file_ops: file_ops:
enabled: false enabled: false
allowed_paths: [] # si no esta vacio, solo estos paths allowed_paths: []
read_only: true read_only: true
matrix_send: matrix_send:
allowed_rooms: [] # si no esta vacio, solo enviar a estos rooms allowed_rooms: []
mcp: mcp:
enabled: false enabled: false
servers: [] # lista de servidores MCP externos servers: []
# Ejemplo:
# - name: "filesystem"
# transport: stdio
# command: "npx"
# args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/data"]
# env: {}
# tools: [] # filtro: solo estas tools (vacio = todas)
# prefix: "fs_" # prefijo para evitar colisiones
# timeout: 30s
expose: expose:
port: 0 # exponer las tools propias via MCP server port: 0
tools: [] # tools a exponer (vacio = todas) tools: []
memory: memory:
enabled: false # tool para acceder a memoria del agente enabled: false
knowledge: knowledge:
enabled: false enabled: false
dir: "./knowledge" # knowledge privado del agente dir: "./knowledge"
shared_knowledge: shared_knowledge:
enabled: false enabled: false
dir: "knowledges" # knowledge compartido entre agentes dir: "knowledges"
db_path: "knowledges/data/knowledge.db" db_path: "knowledges/data/knowledge.db"
skills: skills:
allowed_interpreters: ["bash", "sh"] # interpretes permitidos para skills allowed_interpreters: ["bash", "sh"]
# ============================================ # ============================================
# SKILLS — SISTEMA DE SKILLS # SKILLS
# ============================================ # ============================================
skills: skills:
enabled: false enabled: false
path: "skills/" # ruta base de skills (relativa al proyecto) path: "skills/"
categories: [] # vacio = todas las categorias | ["devops", "system"] = filtradas categories: []
timeout: 60s # timeout para ejecucion de scripts timeout: 60s
# ============================================ # ============================================
# MEMORIA — VENTANA DE CONVERSACION # MEMORIA
# ============================================ # ============================================
memory: memory:
enabled: false enabled: false
window_size: 20 # mensajes por room en ventana deslizante window_size: 20
db_path: "" # default: agents/<id>/data/memory.db db_path: ""
# ============================================ # ============================================
# MATRIX — CONEXION Y ROOMS # MATRIX
# ============================================ # ============================================
matrix: matrix:
homeserver: "https://matrix.example.com" homeserver: "https://matrix.example.com"
@@ -208,51 +191,29 @@ matrix:
enabled: false enabled: false
store_path: "./agents/_template/data/crypto/" store_path: "./agents/_template/data/crypto/"
pickle_key_env: PICKLE_KEY_TEMPLATE pickle_key_env: PICKLE_KEY_TEMPLATE
trust_mode: tofu # tofu | cross-signing | manual trust_mode: tofu
recovery_key_env: "" # SSSS recovery key para cross-signing recovery_key_env: ""
rooms: rooms:
listen: [] # rooms donde escuchar sin responder listen: []
respond: [] # rooms donde responder automaticamente respond: []
admin: [] # rooms de admin (para comandos especiales) admin: []
filters: filters:
command_prefix: "!" command_prefix: "!"
mention_respond: true # responder a menciones mention_respond: true
dm_respond: true # responder a DMs dm_respond: true
ignore_bots: true ignore_bots: true
ignore_users: [] ignore_users: []
unauthorized_response: silent # silent | explicit unauthorized_response: silent
min_power_level: 0 min_power_level: 0
threads: threads:
enabled: true # responder en threads si el mensaje viene de un thread enabled: true
auto_thread: false # crear thread automatico por cada conversacion nueva auto_thread: false
# ============================================ # ============================================
# COMUNICACION INTER-AGENTES # SSH INVENTORY
# ============================================
agents:
peers: []
# Ejemplo:
# - id: other-agent
# capabilities: [devops, monitoring]
# room: "!roomid:server.com"
delegation:
enabled: false
can_delegate_to: []
can_receive_from: []
max_delegation_depth: 1
timeout: 30s
protocol:
format: json # json | protobuf | msgpack
channel: matrix # matrix | grpc | channel
heartbeat_interval: 60s
# ============================================
# SSH — INVENTARIO DE SERVIDORES
# ============================================ # ============================================
ssh: ssh:
defaults: defaults:
@@ -262,152 +223,39 @@ ssh:
known_hosts: "~/.ssh/known_hosts" known_hosts: "~/.ssh/known_hosts"
keepalive_interval: 30s keepalive_interval: 30s
timeout: 60s timeout: 60s
targets: {} targets: {}
# Ejemplo:
# prod-web:
# hosts: ["web01.example.com", "web02.example.com"]
# user: "deploy"
# port: 22
# key_file_env: SSH_KEY_PROD
# bastion:
# hosts: ["bastion.example.com"]
# user: "admin"
# ============================================ # ============================================
# PERMISOS Y SEGURIDAD # SEGURIDAD
# ============================================ # ============================================
security: security:
# Nota: roles/audit/secrets aqui son legacy. Usar security/ centralizado.
audit: audit:
enabled: false enabled: false
log_file: "./agents/_template/data/audit.log" log_file: ""
log_to_room: "" log_to_room: ""
include: [] include: []
secrets: secrets:
provider: env # env | vault | sops provider: env
# Sanitizacion de prompts (deteccion de injection)
sanitize: sanitize:
enabled: false enabled: false
mode: warn # warn | strip | reject mode: warn
min_severity: medium # low | medium | high min_severity: medium
disabled_patterns: [] disabled_patterns: []
# Rate limiting de tools por room
tool_rate_limit: tool_rate_limit:
enabled: false enabled: false
max_calls_per_min: 10 max_calls_per_min: 10
cleanup_interval_s: 60 cleanup_interval_s: 60
# ============================================ # ============================================
# SCHEDULING — AUTOMATIZACIONES CRON # SCHEDULING
# ============================================ # ============================================
schedules: [] schedules: []
# Ejemplo 1: enviar mensaje (send_message)
# - name: "buenos-dias"
# cron: "0 9 * * 1-5" # lunes a viernes a las 9am
# action:
# kind: send_message
# message: "Buenos dias equipo!" # inline
# # template: "prompts/daily.md" # o desde archivo
# output_room: "!roomid:server.com"
# on_failure:
# notify_room: "!admin:server.com"
# escalate_to: ""
# Ejemplo 2: ejecutar tool (run_tool)
# - name: "check-disk"
# cron: "0 */6 * * *" # cada 6 horas
# action:
# kind: run_tool
# target: ssh_exec
# command: "df -h"
# output_room: "!ops:server.com"
# on_failure:
# notify_room: "!admin:server.com"
# Ejemplo 3: prompt LLM (llm_prompt)
# - name: "resumen-logs"
# cron: "0 18 * * *" # diario a las 6pm
# action:
# kind: llm_prompt
# prompt: "Dame un resumen de los logs del dia."
# output_room: "!ops:server.com"
# on_failure:
# notify_room: ""
# ============================================ # ============================================
# OBSERVABILIDAD # STORAGE
# ============================================
observability:
logging:
level: info # debug | info | warn | error
format: json # json | text
output: stdout # stdout | file
file: "./agents/_template/data/template.log"
metrics:
enabled: false
port: 9090
path: /metrics
export: prometheus # prometheus | datadog | ...
health:
enabled: true
port: 8080
path: /healthz
tracing:
enabled: false
provider: "" # jaeger | zipkin | datadog
endpoint: ""
# ============================================
# RESILIENCIA
# ============================================
resilience:
circuit_breaker:
failure_threshold: 5 # abrir tras N fallos consecutivos
timeout: 30s # tiempo en open antes de half-open
half_open_max: 2 # intentos en half-open antes de cerrar
retry:
max_attempts: 2
backoff: exponential # fixed | exponential
initial_delay: 1s
max_delay: 10s
shutdown:
timeout: 10s # tiempo maximo para graceful shutdown
drain_messages: true # procesar mensajes pendientes
save_state: false
state_file: ""
queue:
enabled: true
max_size: 100
priority_users: [] # usuarios con prioridad
# ============================================
# ALMACENAMIENTO Y ESTADO
# ============================================ # ============================================
storage: storage:
base_path: "" # root para datos; default: $AGENTS_DATA_DIR/<id> o agents/<id>/data base_path: ""
state:
backend: sqlite # sqlite | redis | file
path: "./agents/_template/data/template.db"
cache:
enabled: true
backend: memory # memory | redis
ttl: 5m
max_entries: 200
history:
backend: sqlite
path: "./agents/_template/data/history.db"
retention: 168h # 7 dias
+2 -88
View File
@@ -175,27 +175,6 @@ matrix:
enabled: true # responder en threads cuando el mensaje viene de un thread enabled: true # responder en threads cuando el mensaje viene de un thread
auto_thread: false # true para crear thread automático por cada conversación nueva auto_thread: false # true para crear thread automático por cada conversación nueva
# ============================================
# COMUNICACIÓN INTER-AGENTES
# ============================================
agents:
peers:
- id: assistant-bot
capabilities: [general, llm]
room: ""
delegation:
enabled: false
can_delegate_to: []
can_receive_from: [assistant-bot]
max_delegation_depth: 1
timeout: 30s
protocol:
format: json
channel: matrix
heartbeat_interval: 60s
# ============================================ # ============================================
# SSH — no aplica para este bot # SSH — no aplica para este bot
# ============================================ # ============================================
@@ -228,72 +207,7 @@ security:
schedules: [] schedules: []
# ============================================ # ============================================
# OBSERVABILIDAD # STORAGE
# ============================================
observability:
logging:
level: info
format: json
output: stdout
file: "./agents/asistente-2/data/asistente-2.log"
metrics:
enabled: false
port: 9092
path: /metrics
export: prometheus
health:
enabled: true
port: 8082
path: /healthz
tracing:
enabled: false
provider: ""
endpoint: ""
# ============================================
# RESILIENCIA
# ============================================
resilience:
circuit_breaker:
failure_threshold: 5
timeout: 30s
half_open_max: 2
retry:
max_attempts: 2
backoff: exponential
initial_delay: 1s
max_delay: 10s
shutdown:
timeout: 10s
drain_messages: true
save_state: false
state_file: ""
queue:
enabled: true
max_size: 100
priority_users: ["@admin:matrix-af2f3d.organic-machine.com"]
# ============================================
# ALMACENAMIENTO Y ESTADO
# ============================================ # ============================================
storage: storage:
state: base_path: ""
backend: sqlite
path: "./agents/asistente-2/data/asistente-2.db"
cache:
enabled: true
backend: memory
ttl: 5m
max_entries: 200
history:
backend: sqlite
path: "./agents/asistente-2/data/history.db"
retention: 168h # 7 días
+2 -85
View File
@@ -169,24 +169,6 @@ matrix:
enabled: true # responder en threads cuando el mensaje viene de un thread enabled: true # responder en threads cuando el mensaje viene de un thread
auto_thread: false # true para crear thread automático por cada conversación nueva auto_thread: false # true para crear thread automático por cada conversación nueva
# ============================================
# COMUNICACIÓN INTER-AGENTES
# ============================================
agents:
peers: []
delegation:
enabled: false
can_delegate_to: []
can_receive_from: []
max_delegation_depth: 1
timeout: 30s
protocol:
format: json
channel: matrix
heartbeat_interval: 60s
# ============================================ # ============================================
# SSH — no aplica para este bot # SSH — no aplica para este bot
# ============================================ # ============================================
@@ -219,72 +201,7 @@ security:
schedules: [] schedules: []
# ============================================ # ============================================
# OBSERVABILIDAD # STORAGE
# ============================================
observability:
logging:
level: info
format: json
output: stdout
file: "./agents/assistant-bot/data/assistant.log"
metrics:
enabled: false
port: 9091
path: /metrics
export: prometheus
health:
enabled: true
port: 8081
path: /healthz
tracing:
enabled: false
provider: ""
endpoint: ""
# ============================================
# RESILIENCIA
# ============================================
resilience:
circuit_breaker:
failure_threshold: 5
timeout: 30s
half_open_max: 2
retry:
max_attempts: 2
backoff: exponential
initial_delay: 1s
max_delay: 10s
shutdown:
timeout: 10s
drain_messages: true
save_state: false
state_file: ""
queue:
enabled: true
max_size: 100
priority_users: ["@admin:matrix-af2f3d.organic-machine.com"]
# ============================================
# ALMACENAMIENTO Y ESTADO
# ============================================ # ============================================
storage: storage:
state: base_path: ""
backend: sqlite
path: "./agents/assistant-bot/data/assistant.db"
cache:
enabled: true
backend: memory
ttl: 5m
max_entries: 200
history:
backend: sqlite
path: "./agents/assistant-bot/data/history.db"
retention: 168h # 7 días
-101
View File
@@ -10,12 +10,9 @@ type AgentConfig struct {
LLM LLMCfg `yaml:"llm"` LLM LLMCfg `yaml:"llm"`
Tools ToolsCfg `yaml:"tools"` Tools ToolsCfg `yaml:"tools"`
Matrix MatrixCfg `yaml:"matrix"` Matrix MatrixCfg `yaml:"matrix"`
Agents AgentsCfg `yaml:"agents"`
SSH SSHCfg `yaml:"ssh"` SSH SSHCfg `yaml:"ssh"`
Security SecurityCfg `yaml:"security"` Security SecurityCfg `yaml:"security"`
Schedules []ScheduleCfg `yaml:"schedules"` Schedules []ScheduleCfg `yaml:"schedules"`
Observability ObservabilityCfg `yaml:"observability"`
Resilience ResilienceCfg `yaml:"resilience"`
Storage StorageCfg `yaml:"storage"` Storage StorageCfg `yaml:"storage"`
Memory MemoryCfg `yaml:"memory"` Memory MemoryCfg `yaml:"memory"`
Skills SkillsCfg `yaml:"skills"` Skills SkillsCfg `yaml:"skills"`
@@ -276,34 +273,6 @@ type FiltersCfg struct {
MinPowerLevel int `yaml:"min_power_level"` MinPowerLevel int `yaml:"min_power_level"`
} }
// ── Inter-agent ───────────────────────────────────────────────────────────
type AgentsCfg struct {
Peers []PeerCfg `yaml:"peers"`
Delegation DelegationCfg `yaml:"delegation"`
Protocol ProtocolCfg `yaml:"protocol"`
}
type PeerCfg struct {
ID string `yaml:"id"`
Capabilities []string `yaml:"capabilities"`
Room string `yaml:"room"`
}
type DelegationCfg struct {
Enabled bool `yaml:"enabled"`
CanDelegateTo []string `yaml:"can_delegate_to"`
CanReceiveFrom []string `yaml:"can_receive_from"`
MaxDepth int `yaml:"max_delegation_depth"`
Timeout time.Duration `yaml:"timeout"`
}
type ProtocolCfg struct {
Format string `yaml:"format"` // json | protobuf | msgpack
Channel string `yaml:"channel"` // matrix | grpc | channel
HeartbeatInterval time.Duration `yaml:"heartbeat_interval"`
}
// ── SSH Inventory ───────────────────────────────────────────────────────── // ── SSH Inventory ─────────────────────────────────────────────────────────
type SSHCfg struct { type SSHCfg struct {
@@ -398,76 +367,6 @@ type FailureAction struct {
EscalateTo string `yaml:"escalate_to"` EscalateTo string `yaml:"escalate_to"`
} }
// ── Observability ─────────────────────────────────────────────────────────
type ObservabilityCfg struct {
Logging LoggingCfg `yaml:"logging"`
Metrics MetricsCfg `yaml:"metrics"`
Health HealthCfg `yaml:"health"`
Tracing TracingCfg `yaml:"tracing"`
}
type LoggingCfg struct {
Level string `yaml:"level"`
Format string `yaml:"format"` // json | text
Output string `yaml:"output"` // stdout | file
File string `yaml:"file"`
}
type MetricsCfg struct {
Enabled bool `yaml:"enabled"`
Port int `yaml:"port"`
Path string `yaml:"path"`
Export string `yaml:"export"` // prometheus
}
type HealthCfg struct {
Enabled bool `yaml:"enabled"`
Port int `yaml:"port"`
Path string `yaml:"path"`
}
type TracingCfg struct {
Enabled bool `yaml:"enabled"`
Provider string `yaml:"provider"`
Endpoint string `yaml:"endpoint"`
}
// ── Resilience ────────────────────────────────────────────────────────────
type ResilienceCfg struct {
CircuitBreaker CircuitBreakerCfg `yaml:"circuit_breaker"`
Retry RetryCfg `yaml:"retry"`
Shutdown ShutdownCfg `yaml:"shutdown"`
Queue QueueCfg `yaml:"queue"`
}
type CircuitBreakerCfg struct {
FailureThreshold int `yaml:"failure_threshold"`
Timeout time.Duration `yaml:"timeout"`
HalfOpenMax int `yaml:"half_open_max"`
}
type RetryCfg struct {
MaxAttempts int `yaml:"max_attempts"`
Backoff string `yaml:"backoff"` // fixed | exponential
InitialDelay time.Duration `yaml:"initial_delay"`
MaxDelay time.Duration `yaml:"max_delay"`
}
type ShutdownCfg struct {
Timeout time.Duration `yaml:"timeout"`
DrainMessages bool `yaml:"drain_messages"`
SaveState bool `yaml:"save_state"`
StateFile string `yaml:"state_file"`
}
type QueueCfg struct {
Enabled bool `yaml:"enabled"`
MaxSize int `yaml:"max_size"`
PriorityUsers []string `yaml:"priority_users"`
}
// ── Storage ─────────────────────────────────────────────────────────────── // ── Storage ───────────────────────────────────────────────────────────────
type StorageCfg struct { type StorageCfg struct {