| 💾 Saved. d722711 k33g 4h ago | 1 | package session |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "testing" |
| 6 | |
| 7 | "github.com/firebase/genkit/go/ai" |
| 8 | ) |
| 9 | |
| 10 | // The command is recognised as typed at a prompt: surrounding whitespace and |
| 11 | // the trailing newline an editor keeps must not hide it, and anything after |
| 12 | // the word is a question, not the command. |
| 13 | func TestIsNewCommandTrimsButDoesNotGuess(t *testing.T) { |
| 14 | cases := map[string]bool{ |
| 15 | "/new": true, |
| 16 | " /new ": true, |
| 17 | "/new\n": true, |
| 18 | "/new please": false, |
| 19 | "/News": false, |
| 20 | "new": false, |
| 21 | "": false, |
| 22 | "/compact": false, |
| 23 | "/new\tthings": false, |
| 24 | } |
| 25 | for in, want := range cases { |
| 26 | if got := IsNewCommand(in); got != want { |
| 27 | t.Errorf("IsNewCommand(%q) = %v, want %v", in, got, want) |
| 28 | } |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | // A fresh session is the system prompt alone, with the text given. |
| 33 | func TestFreshIsTheSystemPromptAlone(t *testing.T) { |
| 34 | msgs := Fresh("you are bob") |
| 35 | if len(msgs) != 1 { |
| 36 | t.Fatalf("Fresh: %d message(s), want 1", len(msgs)) |
| 37 | } |
| 38 | if msgs[0].Role != ai.RoleSystem { |
| 39 | t.Errorf("Fresh: role %q, want %q", msgs[0].Role, ai.RoleSystem) |
| 40 | } |
| 41 | if got := msgs[0].Text(); got != "you are bob" { |
| 42 | t.Errorf("Fresh: text %q, want %q", got, "you are bob") |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | // Two fresh sessions must not share their backing array: appending to one |
| 47 | // would otherwise leak into the other (one process, several ACP sessions). |
| 48 | func TestFreshReturnsIndependentSlices(t *testing.T) { |
| 49 | a := Fresh("s") |
| 50 | b := Fresh("s") |
| 51 | a = append(a, ai.NewUserTextMessage("hello")) |
| 52 | if len(a) != 2 { |
| 53 | t.Fatalf("appending to a fresh session: %d message(s), want 2", len(a)) |
| 54 | } |
| 55 | if len(b) != 1 { |
| 56 | t.Errorf("appending to one fresh session changed another: %d message(s)", len(b)) |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | // Forgotten counts what a reset drops: every message but the system prompt, |
| 61 | // tool turns included. A fresh session forgets nothing. |
| 62 | func TestForgottenCountsEverythingButTheSystemPrompt(t *testing.T) { |
| 63 | if got := Forgotten(Fresh("s")); got != 0 { |
| 64 | t.Errorf("Forgotten(fresh) = %d, want 0", got) |
| 65 | } |
| 66 | if got := Forgotten(nil); got != 0 { |
| 67 | t.Errorf("Forgotten(nil) = %d, want 0", got) |
| 68 | } |
| 69 | msgs := append(Fresh("s"), |
| 70 | ai.NewUserTextMessage("ls"), |
| 71 | ai.NewModelMessage(ai.NewToolRequestPart(&ai.ToolRequest{Name: "bash", Input: map[string]any{"command": "ls"}})), |
| 72 | ai.NewMessage(ai.RoleTool, nil, ai.NewToolResponsePart(&ai.ToolResponse{Name: "bash", Output: "main.go"})), |
| 73 | ai.NewModelTextMessage("There is one file."), |
| 74 | ) |
| 75 | if got := Forgotten(msgs); got != 4 { |
| 76 | t.Errorf("Forgotten = %d, want 4", got) |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | func ExampleIsNewCommand() { |
| 81 | fmt.Println(IsNewCommand("/new"), IsNewCommand("/new please")) |
| 82 | // Output: true false |
| 83 | } |
| 84 | |
| 85 | func ExampleFresh() { |
| 86 | msgs := Fresh("You are a coding agent.") |
| 87 | fmt.Println(len(msgs), msgs[0].Role, Forgotten(msgs)) |
| 88 | // Output: 1 system 0 |
| 89 | } |