mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 19:41:17 +00:00
Adds detailed architecture documentation for Pulse Patrol and Pulse Assistant. Updates AI.md and PULSE_PRO.md. Also includes additional tests.
142 lines
4.1 KiB
Go
142 lines
4.1 KiB
Go
package chat
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestSessionStore_KnowledgeAndToolSets(t *testing.T) {
|
|
store, err := NewSessionStore(t.TempDir())
|
|
if err != nil {
|
|
t.Fatalf("failed to create session store: %v", err)
|
|
}
|
|
|
|
session, err := store.Create()
|
|
if err != nil {
|
|
t.Fatalf("failed to create session: %v", err)
|
|
}
|
|
|
|
ka1 := store.GetKnowledgeAccumulator(session.ID)
|
|
ka2 := store.NewKnowledgeAccumulatorForRun(session.ID)
|
|
if ka1 == ka2 {
|
|
t.Fatalf("expected new knowledge accumulator for run")
|
|
}
|
|
|
|
toolSet := map[string]bool{"pulse_query": true}
|
|
store.SetToolSet(session.ID, toolSet)
|
|
got := store.GetToolSet(session.ID)
|
|
if got == nil || !got["pulse_query"] {
|
|
t.Fatalf("expected tool set entry")
|
|
}
|
|
got["pulse_query"] = false
|
|
if store.GetToolSet(session.ID)["pulse_query"] != true {
|
|
t.Fatalf("expected tool set to be copied")
|
|
}
|
|
|
|
updated := store.AddToolSet(session.ID, map[string]bool{"pulse_metrics": true})
|
|
if !updated["pulse_metrics"] {
|
|
t.Fatalf("expected tool set to include additions")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_ResolvedContextLifecycle(t *testing.T) {
|
|
store, err := NewSessionStore(t.TempDir())
|
|
if err != nil {
|
|
t.Fatalf("failed to create session store: %v", err)
|
|
}
|
|
|
|
session, err := store.Create()
|
|
if err != nil {
|
|
t.Fatalf("failed to create session: %v", err)
|
|
}
|
|
|
|
res := &ResolvedResource{
|
|
ResourceID: "vm:node1:101",
|
|
ResourceType: "vm",
|
|
Name: "alpha",
|
|
TargetHost: "alpha",
|
|
AllowedActions: []string{"start"},
|
|
}
|
|
store.AddResolvedResource(session.ID, res.Name, res)
|
|
|
|
if _, err := store.ValidateResourceForAction(session.ID, res.ResourceID, "start"); err != nil {
|
|
t.Fatalf("expected action to be allowed: %v", err)
|
|
}
|
|
if _, err := store.ValidateResourceForAction(session.ID, res.ResourceID, "stop"); err == nil {
|
|
t.Fatalf("expected action to be blocked")
|
|
}
|
|
|
|
store.ClearResolvedContext(session.ID)
|
|
if _, err := store.ValidateResourceForAction(session.ID, res.ResourceID, "start"); err == nil {
|
|
t.Fatalf("expected resource to be unresolved after clear")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_ClearSessionState(t *testing.T) {
|
|
store, err := NewSessionStore(t.TempDir())
|
|
if err != nil {
|
|
t.Fatalf("failed to create session store: %v", err)
|
|
}
|
|
|
|
session, err := store.Create()
|
|
if err != nil {
|
|
t.Fatalf("failed to create session: %v", err)
|
|
}
|
|
|
|
// Set up context, FSM, and toolset
|
|
res := &ResolvedResource{ResourceID: "node:node1", Name: "node1", ResourceType: "node"}
|
|
store.AddResolvedResource(session.ID, res.Name, res)
|
|
ctx := store.GetResolvedContext(session.ID)
|
|
ctx.PinResource(res.ResourceID)
|
|
|
|
fsm := store.GetSessionFSM(session.ID)
|
|
fsm.State = StateVerifying
|
|
store.SetToolSet(session.ID, map[string]bool{"pulse_query": true})
|
|
store.GetKnowledgeAccumulator(session.ID)
|
|
|
|
store.ClearSessionState(session.ID, true)
|
|
if !store.GetResolvedContext(session.ID).HasAnyResources() {
|
|
t.Fatalf("expected pinned resources to remain")
|
|
}
|
|
if fsm.State != StateReading {
|
|
t.Fatalf("expected FSM to keep progress when pinned resources remain")
|
|
}
|
|
if store.GetToolSet(session.ID) == nil {
|
|
t.Fatalf("expected toolset to remain when keepPinned=true")
|
|
}
|
|
|
|
store.ClearSessionState(session.ID, false)
|
|
if store.GetToolSet(session.ID) != nil {
|
|
t.Fatalf("expected toolset to be cleared when keepPinned=false")
|
|
}
|
|
}
|
|
|
|
func TestSessionStore_ResetFSMAndCleanupContext(t *testing.T) {
|
|
store, err := NewSessionStore(t.TempDir())
|
|
if err != nil {
|
|
t.Fatalf("failed to create session store: %v", err)
|
|
}
|
|
|
|
session, err := store.Create()
|
|
if err != nil {
|
|
t.Fatalf("failed to create session: %v", err)
|
|
}
|
|
|
|
fsm := store.GetSessionFSM(session.ID)
|
|
fsm.State = StateVerifying
|
|
store.ResetSessionFSM(session.ID, true)
|
|
if fsm.State != StateReading {
|
|
t.Fatalf("expected ResetSessionFSM keep progress to move to READING")
|
|
}
|
|
|
|
fsm.State = StateVerifying
|
|
store.ResetSessionFSM(session.ID, false)
|
|
if fsm.State != StateResolving {
|
|
t.Fatalf("expected ResetSessionFSM full reset to move to RESOLVING")
|
|
}
|
|
|
|
store.AddResolvedResource(session.ID, "node1", &ResolvedResource{ResourceID: "node:node1", Name: "node1"})
|
|
store.cleanupResolvedContext(session.ID)
|
|
if store.GetResolvedContext(session.ID).HasAnyResources() {
|
|
t.Fatalf("expected cleanupResolvedContext to remove resources")
|
|
}
|
|
}
|