package store import ( "context" "errors" "path/filepath" "testing" "github.com/crypto/byteclaw/internal/llm" ) func TestStoreRoundTrip(t *testing.T) { s, err := Open(filepath.Join(t.TempDir(), "t.db")) if err != nil { t.Fatal(err) } defer s.Close() ctx := context.Background() ss, err := s.CreateSession(ctx, "first") if err != nil { t.Fatal(err) } s.AppendMessage(ctx, ss.ID, llm.Message{Role: llm.RoleUser, Content: "hi"}) s.AppendMessage(ctx, ss.ID, llm.Message{Role: llm.RoleAssistant, ToolCalls: []llm.ToolCall{{ID: "c1", Name: "time_now", Arguments: "{}"}}}) s.AppendMessage(ctx, ss.ID, llm.Message{Role: llm.RoleTool, ToolCallID: "c1", Name: "time_now", Content: "now"}) all, _ := s.Messages(ctx, ss.ID, 0) if len(all) != 3 || all[1].ToolCalls[0].Name != "time_now" || all[2].ToolCallID != "c1" { t.Fatalf("%+v", all) } last, _ := s.Messages(ctx, ss.ID, 2) if len(last) != 2 || last[0].Role != llm.RoleAssistant { t.Fatalf("limit: %+v", last) } if err := s.RenameSession(ctx, ss.ID, "renamed"); err != nil { t.Fatal(err) } list, _ := s.ListSessions(ctx, 10) if len(list) != 1 || list[0].Title != "renamed" { t.Fatalf("%+v", list) } if err := s.DeleteSession(ctx, ss.ID); err != nil { t.Fatal(err) } if _, err := s.GetSession(ctx, ss.ID); !errors.Is(err, ErrNotFound) { t.Fatal(err) } if m, _ := s.Messages(ctx, ss.ID, 0); len(m) != 0 { t.Fatal("cascade delete failed") } } func TestSummariesSettingsProviderAndCancelled(t *testing.T) { s, err := Open(filepath.Join(t.TempDir(), "t.db")) if err != nil { t.Fatal(err) } defer s.Close() ctx := context.Background() ss, _ := s.CreateSession(ctx, "x") if _, err := s.LatestSummary(ctx, ss.ID); !errors.Is(err, ErrNotFound) { t.Fatal(err) } id1, _ := s.AppendMessage(ctx, ss.ID, llm.Message{Role: llm.RoleUser, Content: "a"}) s.AppendMessage(ctx, ss.ID, llm.Message{Role: llm.RoleAssistant, Content: "part", Cancelled: true}) s.AddSummary(ctx, ss.ID, id1, "old") s.AddSummary(ctx, ss.ID, id1, "new") sm, _ := s.LatestSummary(ctx, ss.ID) if sm.Content != "new" || sm.UptoMessageID != id1 { t.Fatalf("%+v", sm) } after, _ := s.MessagesAfter(ctx, ss.ID, id1, 0) if len(after) != 1 || !after[0].Cancelled || after[0].Content != "part" { t.Fatalf("%+v", after) } if all, _ := s.Messages(ctx, ss.ID, 0); len(all) != 2 { t.Fatal("original messages must be kept") } if err := s.SetSessionProvider(ctx, ss.ID, "dahl", "m"); err != nil { t.Fatal(err) } got, _ := s.GetSession(ctx, ss.ID) if got.Provider != "dahl" || got.Model != "m" { t.Fatalf("%+v", got) } s.SetSetting(ctx, "k", "v1") s.SetSetting(ctx, "k", "v2") if v, _ := s.GetSetting(ctx, "k"); v != "v2" { t.Fatal(v) } }