Files
agents_and_robots/agents/devops/agent.go
T
2026-03-03 23:19:23 +00:00

112 lines
3.0 KiB
Go

// Package devops defines the rules and composition for the devops agent.
package devops
import (
"github.com/enmanuel/agents/pkg/decision"
"github.com/enmanuel/agents/pkg/tools"
)
// Rules returns the decision rules for the devops agent.
// These are pure data — no side effects.
func Rules() []decision.Rule {
return []decision.Rule{
{
Name: "help",
Match: decision.MatchCommand("help"),
Actions: []decision.Action{{
Kind: decision.ActionKindReply,
Reply: &decision.ReplyAction{
Content: "**DevOps Agent** — comandos disponibles:\n" +
"- `!status <target>` — estado del target\n" +
"- `!deploy <env>` — deployment en el environment\n" +
"- `!rollback <env>` — rollback del último deploy\n" +
"- `!logs <target>` — últimas líneas de log\n" +
"- `!healthcheck` — health check de producción",
},
}},
},
{
Name: "healthcheck",
Match: decision.MatchCommand("healthcheck"),
Actions: []decision.Action{{
Kind: decision.ActionKindSSH,
SSH: &tools.SSHCommandSpec{
Target: "production",
Command: "/opt/scripts/healthcheck.sh",
Timeout: "30s",
},
}},
},
{
Name: "status",
Match: decision.MatchCommand("status"),
Actions: []decision.Action{{
Kind: decision.ActionKindSSH,
SSH: &tools.SSHCommandSpec{
Target: "monitoring",
Command: "systemctl status --no-pager",
Timeout: "15s",
},
}},
},
{
Name: "deploy-staging",
Match: decision.And(decision.MatchCommand("deploy"), func(ctx decision.MessageContext) bool {
return len(ctx.Args) > 0 && ctx.Args[0] == "staging"
}),
Actions: []decision.Action{{
Kind: decision.ActionKindSSH,
SSH: &tools.SSHCommandSpec{
Target: "staging",
Command: "cd /app && git pull origin main && systemctl restart app",
Timeout: "60s",
},
}},
},
{
Name: "deploy-production",
Match: decision.And(
decision.MatchCommand("deploy"),
decision.MatchMinPowerLevel(50),
func(ctx decision.MessageContext) bool {
return len(ctx.Args) > 0 && ctx.Args[0] == "production"
},
),
Actions: []decision.Action{{
Kind: decision.ActionKindSSH,
SSH: &tools.SSHCommandSpec{
Target: "production",
Command: "cd /app && git pull origin main && systemctl restart app",
Timeout: "120s",
},
}},
},
{
Name: "logs",
Match: decision.MatchCommand("logs"),
Actions: []decision.Action{{
Kind: decision.ActionKindSSH,
SSH: &tools.SSHCommandSpec{
Target: "production",
Command: "journalctl -u app -n 50 --no-pager",
Timeout: "15s",
},
}},
},
// Fallback: anything else goes to LLM
{
Name: "llm-fallback",
Match: decision.And(
decision.MatchAny(),
func(ctx decision.MessageContext) bool {
return ctx.Command == "" && (ctx.IsMention || ctx.IsDirectMsg)
},
),
Actions: []decision.Action{{
Kind: decision.ActionKindLLM,
LLM: &decision.LLMAction{},
}},
},
}
}