112 lines
3.0 KiB
Go
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{},
|
|
}},
|
|
},
|
|
}
|
|
}
|