2260480c81
The headline P4 piece (clean redesign): the Agent persona noun, decoupled from its Discord shell. - agent.go/storage.go/builtin_loader.go moved from mort's pkg/logic/agents; the Storage seam drops the Discord CommandBindingStorage embedding (a host concern). The host-entangled files (commands, chatbot_provider, command- binding dispatcher, personalization, system) stay in mort. - runnable.go: Agent.ToRunnable() lowers a persona into run.RunnableAgent — the bridge that lets run.Executor run a persona without importing this battery (the inversion of agentexec.Run(*agents.Agent)). - memory.go: NewMemory() — zero-dep in-process persona Storage (all 11 CRUD + trigger-query methods). Tests: ToRunnable field/phase mapping; Memory round-trip. CI invariant: core imports ZERO from persona. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
46 lines
1.3 KiB
Go
46 lines
1.3 KiB
Go
package persona
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestToRunnable(t *testing.T) {
|
|
a := &Agent{
|
|
ID: "id1", Name: "helper", SystemPrompt: "be nice", ModelTier: "fast",
|
|
MaxIterations: 5, MaxRuntime: 30 * time.Second,
|
|
LowLevelTools: []string{"think"}, SkillPalette: []string{"animate"},
|
|
CriticEnabled: true, CriticBackstopMultiplier: 2,
|
|
Phases: []AgentPhase{{Name: "p1", ModelTier: "thinking", MaxIter: 3, Tools: []string{"now"}, Optional: true}},
|
|
}
|
|
r := a.ToRunnable()
|
|
if r.ID != "id1" || r.ModelTier != "fast" || r.MaxIterations != 5 || !r.Critic.Enabled {
|
|
t.Fatalf("ToRunnable mapping wrong: %+v", r)
|
|
}
|
|
if len(r.Phases) != 1 || r.Phases[0].MaxIterations != 3 || !r.Phases[0].Optional {
|
|
t.Fatalf("phase mapping wrong: %+v", r.Phases)
|
|
}
|
|
}
|
|
|
|
func TestMemoryStoreRoundTrip(t *testing.T) {
|
|
ctx := context.Background()
|
|
m := NewMemory()
|
|
a := &Agent{ID: "a1", Name: "n", OwnerID: "o1"}
|
|
if err := m.SaveAgent(ctx, a); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := m.GetAgent(ctx, "a1")
|
|
if err != nil || got.Name != "n" {
|
|
t.Fatalf("GetAgent: %v %+v", err, got)
|
|
}
|
|
byName, err := m.GetAgentByName(ctx, "o1", "n")
|
|
if err != nil || byName.ID != "a1" {
|
|
t.Fatalf("GetAgentByName: %v %+v", err, byName)
|
|
}
|
|
list, _ := m.ListAgents(ctx, "o1")
|
|
if len(list) != 1 {
|
|
t.Fatalf("ListAgents = %d", len(list))
|
|
}
|
|
}
|