X-Git-Url: http://git.giacomolli.uk/onechat/blobdiff_plain/6d96a69d33eb634f61f809001aca19ae57113180:/layout.go..7b6d0a81e0f3c8e33b1b76d5ecbc5bdb25a87249:/view_layout.go?ds=inline diff --git a/layout.go b/view_layout.go similarity index 74% rename from layout.go rename to view_layout.go index c5e9ac3..0d4e756 100644 --- a/layout.go +++ b/view_layout.go @@ -10,36 +10,14 @@ import ( "strings" ) -// layoutFileName is the file of the view layout in the directory of an agent. -const layoutFileName = "layout.json" - -// viewLayout splits the view of a turn request into user messages that only -// grow between batches. The view goes out as the same messages as in the -// request before, while their lines give the same text, and the new lines -// follow as one new message. So the end of the view of each earlier turn stays -// a message end. On the ChatGPT backend, the first request of a turn with this -// layout read the view of the turn before from the prompt cache in each of 10 -// turns, and with the view in one message it missed once in 5. -// -// The first message starts with "\n". The closing tag goes into the -// state message after the view, so that no view message changes when lines -// come. The layout keeps the line count and a hash of the text of each message -// in layout.json, so it outlives a restart. -type viewLayout struct { - path string - Messages []layoutMessage `json:"messages"` -} - -// layoutMessage is one view message: its number of lines and the hash of its -// text. -type layoutMessage struct { - Lines int `json:"lines"` - Hash string `json:"hash"` -} - -// loadLayout reads the layout at path. A missing file gives an empty layout. -func loadLayout(path string) (*viewLayout, error) { - layout := &viewLayout{ +// viewLayoutFileName is the file of the view layout in the directory of an +// agent. +const viewLayoutFileName = "layout.json" + +// loadViewLayout reads the layout at path. A missing file gives an empty +// layout. +func loadViewLayout(path string) (*ViewLayout, error) { + layout := &ViewLayout{ path: path, } @@ -60,12 +38,29 @@ func loadLayout(path string) (*viewLayout, error) { return layout, nil } +// ViewLayout splits the view of a turn request into user messages that only +// grow between batches. The view goes out as the same messages as in the +// request before, while their lines give the same text, and the new lines +// follow as one new message. So the end of the view of each earlier turn stays +// a message end. On the ChatGPT backend, the first request of a turn with this +// layout read the view of the turn before from the prompt cache in each of 10 +// turns, and with the view in one message it missed once in 5. +// +// The first message starts with "\n". The closing tag goes into the +// state message after the view, so that no view message changes when lines +// come. The layout keeps the line count and a hash of the text of each message +// in layout.json, so it outlives a restart. +type ViewLayout struct { + path string + Messages []ViewLayoutMessage `json:"messages"` +} + // Split returns the view messages for lines and saves the layout. It keeps the // earlier messages up to the first one whose text differs, and puts the rest // of the lines into one new message. -func (l *viewLayout) Split(lines []string) ([]string, error) { +func (l *ViewLayout) Split(lines []string) ([]string, error) { var texts []string - var kept []layoutMessage + var kept []ViewLayoutMessage start := 0 for _, message := range l.Messages { if start+message.Lines > len(lines) { @@ -73,7 +68,7 @@ func (l *viewLayout) Split(lines []string) ([]string, error) { } text := viewMessage(len(texts) == 0, lines[start:start+message.Lines]) - if textHash(text) != message.Hash { + if viewTextHash(text) != message.Hash { break } @@ -85,9 +80,9 @@ func (l *viewLayout) Split(lines []string) ([]string, error) { if start < len(lines) || len(texts) == 0 { text := viewMessage(len(texts) == 0, lines[start:]) texts = append(texts, text) - kept = append(kept, layoutMessage{ + kept = append(kept, ViewLayoutMessage{ Lines: len(lines) - start, - Hash: textHash(text), + Hash: viewTextHash(text), }) } @@ -105,6 +100,13 @@ func (l *viewLayout) Split(lines []string) ([]string, error) { return texts, nil } +// ViewLayoutMessage is one view message: its number of lines and the hash of +// its text. +type ViewLayoutMessage struct { + Lines int `json:"lines"` + Hash string `json:"hash"` +} + // viewMessage returns the text of a view message with lines. The first one // opens the chat. func viewMessage(first bool, lines []string) string { @@ -116,8 +118,8 @@ func viewMessage(first bool, lines []string) string { return text } -// textHash returns a short hash of text. -func textHash(text string) string { +// viewTextHash returns a short hash of text. +func viewTextHash(text string) string { sum := sha256.Sum256([]byte(text)) return hex.EncodeToString(sum[:16]) }