mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
117 lines
3.8 KiB
Go
117 lines
3.8 KiB
Go
package agent
|
||
|
||
import (
|
||
"context"
|
||
"log/slog"
|
||
"path/filepath"
|
||
"strings"
|
||
"testing"
|
||
|
||
"nofx/store"
|
||
)
|
||
|
||
func TestClearRemovesActiveAndPendingConversationState(t *testing.T) {
|
||
dbPath := filepath.Join(t.TempDir(), "agent-clear.db")
|
||
st, err := store.New(dbPath)
|
||
if err != nil {
|
||
t.Fatalf("create store: %v", err)
|
||
}
|
||
|
||
a := New(nil, st, DefaultConfig(), slog.Default())
|
||
userID := int64(42)
|
||
|
||
a.history.Add(userID, "assistant", "之前的回复")
|
||
_ = a.saveTaskState(userID, TaskState{CurrentGoal: "配置模型"})
|
||
a.saveActiveSkillSession(ActiveSkillSession{
|
||
SessionID: "as_test",
|
||
UserID: userID,
|
||
SkillName: "model_management",
|
||
ActionName: "create",
|
||
PendingHint: &PendingHint{
|
||
Prompt: "请选择 provider",
|
||
HintType: "question",
|
||
},
|
||
})
|
||
a.savePendingProposalSession(PendingProposalSession{
|
||
UserID: userID,
|
||
SourceUserText: "帮我配置模型",
|
||
ProposalText: "推荐 claw402,你要继续吗?",
|
||
})
|
||
a.saveSetupState(userID, &SetupState{
|
||
Step: "await_ai_model",
|
||
AIProvider: "claw402",
|
||
})
|
||
if err := st.SetSystemConfig(skillSessionConfigKey(userID), `{"name":"model_management","action":"create"}`); err != nil {
|
||
t.Fatalf("seed skill session: %v", err)
|
||
}
|
||
a.saveWorkflowSession(userID, WorkflowSession{
|
||
Tasks: []WorkflowTask{{
|
||
ID: "task_1",
|
||
Skill: "model_management",
|
||
Action: "create",
|
||
Request: "帮我配置模型",
|
||
Status: workflowTaskPending,
|
||
}},
|
||
})
|
||
if err := st.SetSystemConfig(ExecutionStateConfigKey(userID), `{"user_id":42,"session_id":"exec_1"}`); err != nil {
|
||
t.Fatalf("seed execution state: %v", err)
|
||
}
|
||
a.saveReferenceMemory(userID, &CurrentReferences{
|
||
Model: &EntityReference{ID: "m1", Name: "claw402", Source: "context"},
|
||
}, nil)
|
||
a.SnapshotManager(userID).Save(SuspendedTask{ResumeHint: "旧任务"})
|
||
|
||
reply, err := a.HandleMessage(context.Background(), userID, "/clear")
|
||
if err != nil {
|
||
t.Fatalf("clear returned error: %v", err)
|
||
}
|
||
if reply == "" {
|
||
t.Fatalf("expected clear reply")
|
||
}
|
||
|
||
if got := a.history.Get(userID); len(got) != 0 {
|
||
t.Fatalf("history not cleared: %+v", got)
|
||
}
|
||
if got := a.buildRecentConversationContext(userID, "你好"); got != "" {
|
||
t.Fatalf("recent conversation context not cleared: %q", got)
|
||
}
|
||
if got := a.currentPendingHintText(userID); got != "" {
|
||
t.Fatalf("pending hint not cleared: %q", got)
|
||
}
|
||
if got := a.buildCurrentTurnContext(userID, "zh", "你好"); got != "" {
|
||
if strings.Contains(got, "Previous assistant reply:") || strings.Contains(got, "Recent conversation:") {
|
||
t.Fatalf("current turn context still contains prior chat memory: %q", got)
|
||
}
|
||
}
|
||
if got := a.buildActiveTaskStateContext(userID, "zh"); got != "" {
|
||
t.Fatalf("active task state context not cleared: %q", got)
|
||
}
|
||
if state := a.getTaskState(userID); state.CurrentGoal != "" || state.ActiveFlow != "" {
|
||
t.Fatalf("task state not cleared: %+v", state)
|
||
}
|
||
if _, ok := a.getActiveSkillSession(userID); ok {
|
||
t.Fatalf("active skill session not cleared")
|
||
}
|
||
if _, ok := a.getPendingProposalSession(userID); ok {
|
||
t.Fatalf("pending proposal session not cleared")
|
||
}
|
||
if session := a.getSkillSession(userID); session.Name != "" {
|
||
t.Fatalf("legacy skill session not cleared: %+v", session)
|
||
}
|
||
if session := a.getWorkflowSession(userID); len(session.Tasks) != 0 {
|
||
t.Fatalf("workflow session not cleared: %+v", session)
|
||
}
|
||
if state := a.getExecutionState(userID); state.SessionID != "" {
|
||
t.Fatalf("execution state not cleared: %+v", state)
|
||
}
|
||
if memory := a.getReferenceMemory(userID); memory.CurrentReferences != nil || len(memory.ReferenceHistory) != 0 {
|
||
t.Fatalf("reference memory not cleared: %+v", memory)
|
||
}
|
||
if stack := a.SnapshotManager(userID).List(); len(stack) != 0 {
|
||
t.Fatalf("snapshots not cleared: %+v", stack)
|
||
}
|
||
if setup := a.getSetupState(userID); setup.Step != "" || setup.AIProvider != "" {
|
||
t.Fatalf("setup state not cleared: %+v", setup)
|
||
}
|
||
}
|