Files
AetherForge/server/internal/ai/seer_memory.go
AetherForge f0fe34698c
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Implement fleet topology epidemiology tracker and strain plague map.
Adds epidemiology package, auth epidemiology_fix push, strain-based 3D map, and Vitest coverage.
2026-06-07 09:20:12 -07:00

111 lines
3.4 KiB
Go

package ai
import (
"encoding/json"
"regexp"
"strings"
)
// SeerBridge supplies persisted notes and streams LLM payloads to The Seer UI.
type SeerBridge interface {
NotesForPrompt(agentID string) string
AppendNote(agentID, content, promptHash string) error
EmitEvent(agentID, direction string, payload interface{})
}
// SeerNoteInstruction is appended to the system prompt when Seer memory is active.
var SeerNoteInstruction string
// SeerToolCatalog documents fleet tool endpoints the model may invoke via tool-call JSON.
var SeerToolCatalog string
func init() {
SeerNoteInstruction = strings.TrimSpace(`
Seer memory: after your JSON commands block, append exactly one line:
SEER_NOTE: <one concise sentence summarizing what you learned this turn for future cycles>.
The server persists SEER_NOTE lines and replays them on the next turn — this is your only cross-turn memory.`)
SeerToolCatalog = strings.TrimSpace(`
Available Seer tool endpoints (POST /api/v1/seer/tools/{name}):
- spread_route: BGP-style minimum-clearance spread routing — body {"session_id","target_subnets":[],"join_lane"}
- graft_strain: clone winning spread strain onto sibling subnet — body {"source_agent_id","target_subnet","strain"}
- fork_onion: split LOTL tier chain for A/B recovery — body {"agent_id","tier_order":[],"skip_tiers":[]}
Stub handlers return {"ok":true,"stub":true} until live orchestration ships.`)
}
var seerNoteLineRe = regexp.MustCompile(`(?m)^SEER_NOTE:\s*(.+)$`)
// AugmentUserPromptWithNotes prepends replayed Seer notes before the fresh snapshot.
func AugmentUserPromptWithNotes(basePrompt, notesBlock string) string {
notesBlock = strings.TrimSpace(notesBlock)
if notesBlock == "" {
return basePrompt
}
var b strings.Builder
b.WriteString("Seer notes (server memory — replayed from prior turns):\n")
b.WriteString(notesBlock)
b.WriteString("\n\n--- current snapshot ---\n")
b.WriteString(basePrompt)
return b.String()
}
// FormatSeerNotesBlock renders DB notes for prompt injection.
func FormatSeerNotesBlock(notes []string) string {
if len(notes) == 0 {
return ""
}
var b strings.Builder
for i, n := range notes {
n = strings.TrimSpace(n)
if n == "" {
continue
}
if i > 0 {
b.WriteByte('\n')
}
b.WriteString("- ")
b.WriteString(n)
}
return b.String()
}
// ExtractSeerNote pulls the SEER_NOTE line from an LLM response.
func ExtractSeerNote(response string) (note string, ok bool) {
m := seerNoteLineRe.FindStringSubmatch(response)
if len(m) < 2 {
return "", false
}
note = strings.TrimSpace(m[1])
if note == "" {
return "", false
}
if len(note) > 2000 {
note = note[:2000]
}
return note, true
}
// BuildChatCompletionPayload mirrors the exact OpenAI-compatible body sent to the LLM.
func BuildChatCompletionPayload(model, systemPrompt, userPrompt string) map[string]interface{} {
if strings.TrimSpace(model) == "" {
model = "llama3.2"
}
return map[string]interface{}{
"model": model,
"messages": []map[string]string{
{"role": "system", "content": systemPrompt},
{"role": "user", "content": userPrompt},
},
"stream": false,
}
}
// SeerStreamEvent is one request/response frame for The Seer terminal.
type SeerStreamEvent struct {
ID int64 `json:"id"`
AgentID string `json:"agent_id"`
Direction string `json:"direction"`
Payload json.RawMessage `json:"payload"`
Ts string `json:"ts"`
}