package session import ( "fmt" "testing" "github.com/firebase/genkit/go/ai" ) // The command is recognised as typed at a prompt: surrounding whitespace and // the trailing newline an editor keeps must not hide it, and anything after // the word is a question, not the command. func TestIsNewCommandTrimsButDoesNotGuess(t *testing.T) { cases := map[string]bool{ "/new": true, " /new ": true, "/new\n": true, "/new please": false, "/News": false, "new": false, "": false, "/compact": false, "/new\tthings": false, } for in, want := range cases { if got := IsNewCommand(in); got != want { t.Errorf("IsNewCommand(%q) = %v, want %v", in, got, want) } } } // A fresh session is the system prompt alone, with the text given. func TestFreshIsTheSystemPromptAlone(t *testing.T) { msgs := Fresh("you are bob") if len(msgs) != 1 { t.Fatalf("Fresh: %d message(s), want 1", len(msgs)) } if msgs[0].Role != ai.RoleSystem { t.Errorf("Fresh: role %q, want %q", msgs[0].Role, ai.RoleSystem) } if got := msgs[0].Text(); got != "you are bob" { t.Errorf("Fresh: text %q, want %q", got, "you are bob") } } // Two fresh sessions must not share their backing array: appending to one // would otherwise leak into the other (one process, several ACP sessions). func TestFreshReturnsIndependentSlices(t *testing.T) { a := Fresh("s") b := Fresh("s") a = append(a, ai.NewUserTextMessage("hello")) if len(a) != 2 { t.Fatalf("appending to a fresh session: %d message(s), want 2", len(a)) } if len(b) != 1 { t.Errorf("appending to one fresh session changed another: %d message(s)", len(b)) } } // Forgotten counts what a reset drops: every message but the system prompt, // tool turns included. A fresh session forgets nothing. func TestForgottenCountsEverythingButTheSystemPrompt(t *testing.T) { if got := Forgotten(Fresh("s")); got != 0 { t.Errorf("Forgotten(fresh) = %d, want 0", got) } if got := Forgotten(nil); got != 0 { t.Errorf("Forgotten(nil) = %d, want 0", got) } msgs := append(Fresh("s"), ai.NewUserTextMessage("ls"), ai.NewModelMessage(ai.NewToolRequestPart(&ai.ToolRequest{Name: "bash", Input: map[string]any{"command": "ls"}})), ai.NewMessage(ai.RoleTool, nil, ai.NewToolResponsePart(&ai.ToolResponse{Name: "bash", Output: "main.go"})), ai.NewModelTextMessage("There is one file."), ) if got := Forgotten(msgs); got != 4 { t.Errorf("Forgotten = %d, want 4", got) } } func ExampleIsNewCommand() { fmt.Println(IsNewCommand("/new"), IsNewCommand("/new please")) // Output: true false } func ExampleFresh() { msgs := Fresh("You are a coding agent.") fmt.Println(len(msgs), msgs[0].Role, Forgotten(msgs)) // Output: 1 system 0 }