github.com/stevegt/grokker/v3@v3.0.12/core/chat_test.go (about)

     1  package core
     2  
     3  import (
     4  	"flag"
     5  	"os"
     6  	"testing"
     7  
     8  	. "github.com/stevegt/goadapt"
     9  	"github.com/stevegt/grokker/v3/util"
    10  )
    11  
    12  /*
    13  in Go, is there a way of making a test case not run unless a flag is set?
    14  
    15  Yes, you can achieve this in Go by using conditional logic in your test and command-line flags provided by the `flag` package. You declare a flag at the package level, and then in your test function, you use an if statement to check if the flag is set. If the flag is not set, you can call `t.Skip()` to skip the test:
    16  
    17  ```go
    18  package mypackage
    19  
    20  import (
    21  	"flag"
    22  	"testing"
    23  )
    24  
    25  var runMyTest = flag.Bool("runMyTest", false, "run this specific test")
    26  
    27  func TestMyFunction(t *testing.T) {
    28  	if !*runMyTest {
    29  		t.Skip("skipping test; to run, use: -runMyTest=true")
    30  	}
    31      // Your test code here
    32  }
    33  ```
    34  
    35  When running your tests, you can decide to run this test case with the `-runMyTest=true` flag:
    36  
    37  ```bash
    38  go test -runMyTest=true
    39  ```
    40  */
    41  
    42  var runChatSummarization = flag.Bool("runChatSummarization", false, "run chat summarization test")
    43  
    44  // test summarization in a large chat
    45  func TestChatSummarization(t *testing.T) {
    46  	if !*runChatSummarization {
    47  		t.Skip("skipping test; to run, use: -runChatSummarization=true")
    48  	}
    49  
    50  	var match bool
    51  
    52  	// get some test data before changing directories
    53  	teFullBuf, err := os.ReadFile("testdata/te-full.txt")
    54  	Tassert(t, err == nil, "error reading file: %v", err)
    55  	largeChatBuf, err := os.ReadFile("testdata/large-chat")
    56  	Tassert(t, err == nil, "error reading file: %v", err)
    57  
    58  	dir := tmpDir()
    59  	// cd to the tmp dir
    60  	err = os.Chdir(dir)
    61  	Tassert(t, err == nil, "error changing directory: %v", err)
    62  
    63  	// create a new Grokker database
    64  	grok, err := Init(dir, "gpt-4")
    65  	Tassert(t, err == nil, "error creating grokker: %v", err)
    66  	// initialize Tokenizer
    67  	err = InitTokenizer()
    68  	Ck(err)
    69  	defer grok.Save()
    70  
    71  	// start a chat by mentioning something not in GPT-4's global context
    72  	res, err := grok.Chat("", "Pretend a blue widget has a red center.", "chat1", util.ContextAll, nil, nil, 0, 0, false, true, false)
    73  	Tassert(t, err == nil, "error starting chat: %v", err)
    74  	// check that the response contains the expected output
    75  	match = cimatch(res, "red")
    76  	Tassert(t, match, "CLI did not return expected output: %s", res)
    77  
    78  	// copy te-full.txt to the current directory
    79  	err = os.WriteFile("te-full.txt", teFullBuf, 0644)
    80  	Tassert(t, err == nil, "error writing file: %v", err)
    81  	// add the file to the database so we get a large context in
    82  	// subsequent queries
    83  	err = grok.AddDocument("te-full.txt")
    84  	Tassert(t, err == nil, "error adding file: %v", err)
    85  
    86  	// generate a lot of context to cause summarization
    87  	Pl("testing large context")
    88  	history, err := grok.OpenChatHistory("", "chat1")
    89  	Tassert(t, err == nil, "error opening chat history: %v", err)
    90  	res, debug, err := history.continueChat("Talk about complex systems.", util.ContextAll, nil, nil, 0, false)
    91  	Tassert(t, err == nil, "error continuing chat: %v", err)
    92  	err = history.Save(true)
    93  	Tassert(t, err == nil, "error saving chat history: %v", err)
    94  	// should take no more than a few iterations to reach half the token limit
    95  	tokenLimit := grok.tokenLimit
    96  	ok := false
    97  	for i := 0; i < 3; i++ {
    98  		Pf("iteration %d\n", i)
    99  		ctx, err := grok.Context("system", 3000, false, false)
   100  		Tassert(t, err == nil, "error getting context: %v", err)
   101  		prompt := Spf("%s\n\nDiscuss complex systems more.", ctx)
   102  		res, debug, err = history.continueChat(prompt, util.ContextAll, nil, nil, 0, false)
   103  		Tassert(t, err == nil, "error continuing chat: %v", err)
   104  		err = history.Save(true)
   105  		Ck(err)
   106  		// ensure the response contains the expected output
   107  		match = cimatch(res, "system")
   108  		Tassert(t, match, "CLI did not return expected output: %s", res)
   109  		// ensure final token count is less than half the token limit
   110  		Tassert(t, debug["finalCount"] < tokenLimit/2, "final token count is too high: %v", debug)
   111  		// check peak token count
   112  		Pf("final token count: %d\n", debug["finalCount"])
   113  		Pf("peak token count: %d\n", debug["peakCount"])
   114  		if debug["peakCount"] > tokenLimit/2 {
   115  			ok = true
   116  			break
   117  		}
   118  	}
   119  	Tassert(t, ok, "peak token count never exceeded token limit: %v", debug)
   120  
   121  	// check that we still remember the blue widget
   122  	res, err = grok.Chat("", "What color is the center of the blue widget?", "chat1", util.ContextAll, nil, nil, 0, 0, false, true, false)
   123  	match = cimatch(res, "red")
   124  	Tassert(t, match, "CLI did not return expected output: %s", res)
   125  
   126  	// now grow the chat file itself to be larger than the token limit
   127  	Pl("testing large chat file")
   128  	ok = false
   129  	for i := 0; i < 10; i++ {
   130  		if true {
   131  			// use a prebaked chat file to save testing time
   132  			Pl("using prebaked chat file")
   133  			err = os.WriteFile("chat1", largeChatBuf, 0644)
   134  			Tassert(t, err == nil, "error writing file: %v", err)
   135  			// add the file to the database
   136  			err = grok.AddDocument("chat1")
   137  			Tassert(t, err == nil, "error adding file: %v", err)
   138  		} else {
   139  			Pl("generating chat file")
   140  			ctx, err := grok.Context("system", 3000, false, false)
   141  			Tassert(t, err == nil, "error getting context: %v", err)
   142  			prompt := Spf("Discuss this topic more:\n%s\n\n", ctx)
   143  			res, _, err = history.continueChat(prompt, util.ContextAll, nil, nil, 0, false)
   144  			Tassert(t, err == nil, "error continuing chat: %v", err)
   145  			err = history.Save(true)
   146  			Ck(err)
   147  			// ensure the response contains the expected output
   148  			match = cimatch(res, "system")
   149  			Tassert(t, match, "CLI did not return expected output: %s", res)
   150  		}
   151  		// check chat1 file token count
   152  		buf, err := os.ReadFile("chat1")
   153  		Tassert(t, err == nil, "error reading file: %v", err)
   154  		count, err := grok.TokenCount(string(buf))
   155  		Tassert(t, err == nil, "error counting tokens: %v", err)
   156  		if count > tokenLimit {
   157  			ok = true
   158  			break
   159  		}
   160  	}
   161  	Tassert(t, ok, "chat1 file never exceeded token limit: %v", debug)
   162  
   163  	// check that we still remember the blue widget
   164  	res, err = grok.Chat("", "What color is the center of the blue widget?", "chat1", util.ContextAll, nil, nil, 0, 0, false, true, false)
   165  	match = cimatch(res, "red")
   166  	Tassert(t, match, "CLI did not return expected output: %s", res)
   167  
   168  }