Files
executus/persona/persona_test.go
steve 2260480c81 P4: persona noun — Agent + ToRunnable bridge + Memory store
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>
2026-06-27 00:12:19 -04:00

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))
}
}