Show waiting animation while waiting for LLM response
This commit is contained in:
parent
200ec57f29
commit
a28a7a0054
@ -2,7 +2,6 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -89,7 +88,9 @@ var newCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = CreateChatCompletionStream("You are a helpful assistant.", messages, os.Stdout)
|
receiver := make(chan string)
|
||||||
|
go HandleDelayedResponse(receiver)
|
||||||
|
err = CreateChatCompletionStream("You are a helpful assistant.", messages, receiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal("%v\n", err)
|
Fatal("%v\n", err)
|
||||||
return
|
return
|
||||||
@ -117,7 +118,9 @@ var promptCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := CreateChatCompletionStream("You are a helpful assistant.", messages, os.Stdout)
|
receiver := make(chan string)
|
||||||
|
go HandleDelayedResponse(receiver)
|
||||||
|
err := CreateChatCompletionStream("You are a helpful assistant.", messages, receiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal("%v\n", err)
|
Fatal("%v\n", err)
|
||||||
return
|
return
|
||||||
|
@ -3,7 +3,6 @@ package cli
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
openai "github.com/sashabaranov/go-openai"
|
openai "github.com/sashabaranov/go-openai"
|
||||||
@ -48,13 +47,17 @@ func CreateChatCompletion(system string, messages []Message) (string, error) {
|
|||||||
return resp.Choices[0].Message.Content, nil
|
return resp.Choices[0].Message.Content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateChatCompletionStream(system string, messages []Message, output io.Writer) error {
|
// CreateChatCompletionStream submits an streaming Chat Completion API request
|
||||||
|
// and sends the received data to the output channel.
|
||||||
|
func CreateChatCompletionStream(system string, messages []Message, output chan string) error {
|
||||||
client := openai.NewClient(config.OpenAI.APIKey)
|
client := openai.NewClient(config.OpenAI.APIKey)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
req := CreateChatCompletionRequest(system, messages)
|
req := CreateChatCompletionRequest(system, messages)
|
||||||
req.Stream = true
|
req.Stream = true
|
||||||
|
|
||||||
|
defer close(output)
|
||||||
|
|
||||||
stream, err := client.CreateChatCompletionStream(ctx, *req)
|
stream, err := client.CreateChatCompletionStream(ctx, *req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -69,10 +72,9 @@ func CreateChatCompletionStream(system string, messages []Message, output io.Wri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//fmt.Printf("\nStream error: %v\n", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(output, response.Choices[0].Delta.Content)
|
output <- response.Choices[0].Delta.Content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
51
pkg/cli/tty.go
Normal file
51
pkg/cli/tty.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShowWaitAnimation "draws" an animated ellipses to stdout until something is
|
||||||
|
// received on the signal channel. An empty string sent to the channel to
|
||||||
|
// noftify the caller that the animation has completed (carriage returned).
|
||||||
|
func ShowWaitAnimation(signal chan any) {
|
||||||
|
animationStep := 0
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case _ = <-signal:
|
||||||
|
fmt.Print("\r")
|
||||||
|
signal <- ""
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
modSix := animationStep % 6
|
||||||
|
if modSix == 3 || modSix == 0 {
|
||||||
|
fmt.Print("\r")
|
||||||
|
}
|
||||||
|
if modSix < 3 {
|
||||||
|
fmt.Print(".")
|
||||||
|
} else {
|
||||||
|
fmt.Print(" ")
|
||||||
|
}
|
||||||
|
animationStep++
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandledDelayedResponse writes a waiting animation (abusing \r) and the
|
||||||
|
// content received on the response channel to stdout. Blocks until the channel
|
||||||
|
// is closed.
|
||||||
|
func HandleDelayedResponse(response chan string) {
|
||||||
|
waitSignal := make(chan any)
|
||||||
|
go ShowWaitAnimation(waitSignal)
|
||||||
|
|
||||||
|
firstChunk := true
|
||||||
|
for chunk := range response {
|
||||||
|
if firstChunk {
|
||||||
|
waitSignal <- ""
|
||||||
|
<-waitSignal
|
||||||
|
firstChunk = false
|
||||||
|
}
|
||||||
|
fmt.Print(chunk)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user