Cmd changes (#541)

This commit is contained in:
Patrick Devine 2023-09-18 12:26:56 -07:00 committed by GitHub
parent 94e1d96b29
commit 80dd44e80a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 67 deletions

View file

@ -33,6 +33,17 @@ import (
"github.com/jmorganca/ollama/version" "github.com/jmorganca/ollama/version"
) )
type Painter struct{}
func (p Painter) Paint(line []rune, l int) []rune {
termType := os.Getenv("TERM")
if termType == "xterm-256color" && len(line) == 0 {
prompt := "Send a message (/? for help)"
return []rune(fmt.Sprintf("\033[38;5;245m%s\033[%dD\033[0m", prompt, len(prompt)))
}
return line
}
func CreateHandler(cmd *cobra.Command, args []string) error { func CreateHandler(cmd *cobra.Command, args []string) error {
filename, _ := cmd.Flags().GetString("file") filename, _ := cmd.Flags().GetString("file")
filename, err := filepath.Abs(filename) filename, err := filepath.Abs(filename)
@ -387,71 +398,71 @@ func RunGenerate(cmd *cobra.Command, args []string) error {
type generateContextKey string type generateContextKey string
func generate(cmd *cobra.Command, model, prompt string) error { func generate(cmd *cobra.Command, model, prompt string) error {
if len(strings.TrimSpace(prompt)) > 0 { client, err := api.FromEnv()
client, err := api.FromEnv() if err != nil {
if err != nil { return err
return err
}
spinner := NewSpinner("")
go spinner.Spin(60 * time.Millisecond)
var latest api.GenerateResponse
generateContext, ok := cmd.Context().Value(generateContextKey("context")).([]int)
if !ok {
generateContext = []int{}
}
request := api.GenerateRequest{Model: model, Prompt: prompt, Context: generateContext}
fn := func(response api.GenerateResponse) error {
if !spinner.IsFinished() {
spinner.Finish()
}
latest = response
fmt.Print(response.Response)
return nil
}
if err := client.Generate(context.Background(), &request, fn); err != nil {
if strings.Contains(err.Error(), "failed to load model") {
// tell the user to check the server log, if it exists locally
home, nestedErr := os.UserHomeDir()
if nestedErr != nil {
// return the original error
return err
}
logPath := filepath.Join(home, ".ollama", "logs", "server.log")
if _, nestedErr := os.Stat(logPath); nestedErr == nil {
err = fmt.Errorf("%w\nFor more details, check the error logs at %s", err, logPath)
}
}
return err
}
fmt.Println()
fmt.Println()
if !latest.Done {
return errors.New("unexpected end of response")
}
verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
return err
}
if verbose {
latest.Summary()
}
ctx := cmd.Context()
ctx = context.WithValue(ctx, generateContextKey("context"), latest.Context)
cmd.SetContext(ctx)
} }
spinner := NewSpinner("")
go spinner.Spin(60 * time.Millisecond)
var latest api.GenerateResponse
generateContext, ok := cmd.Context().Value(generateContextKey("context")).([]int)
if !ok {
generateContext = []int{}
}
request := api.GenerateRequest{Model: model, Prompt: prompt, Context: generateContext}
fn := func(response api.GenerateResponse) error {
if !spinner.IsFinished() {
spinner.Finish()
}
latest = response
fmt.Print(response.Response)
return nil
}
if err := client.Generate(context.Background(), &request, fn); err != nil {
if strings.Contains(err.Error(), "failed to load model") {
// tell the user to check the server log, if it exists locally
home, nestedErr := os.UserHomeDir()
if nestedErr != nil {
// return the original error
return err
}
logPath := filepath.Join(home, ".ollama", "logs", "server.log")
if _, nestedErr := os.Stat(logPath); nestedErr == nil {
err = fmt.Errorf("%w\nFor more details, check the error logs at %s", err, logPath)
}
}
return err
}
if prompt != "" {
fmt.Println()
fmt.Println()
}
if !latest.Done {
return errors.New("unexpected end of response")
}
verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
return err
}
if verbose {
latest.Summary()
}
ctx := cmd.Context()
ctx = context.WithValue(ctx, generateContextKey("context"), latest.Context)
cmd.SetContext(ctx)
return nil return nil
} }
@ -461,6 +472,11 @@ func generateInteractive(cmd *cobra.Command, model string) error {
return err return err
} }
// load the model
if err := generate(cmd, model, ""); err != nil {
return err
}
completer := readline.NewPrefixCompleter( completer := readline.NewPrefixCompleter(
readline.PcItem("/help"), readline.PcItem("/help"),
readline.PcItem("/list"), readline.PcItem("/list"),
@ -492,6 +508,7 @@ func generateInteractive(cmd *cobra.Command, model string) error {
} }
config := readline.Config{ config := readline.Config{
Painter: Painter{},
Prompt: ">>> ", Prompt: ">>> ",
HistoryFile: filepath.Join(home, ".ollama", "history"), HistoryFile: filepath.Join(home, ".ollama", "history"),
AutoComplete: completer, AutoComplete: completer,
@ -621,8 +638,10 @@ func generateInteractive(cmd *cobra.Command, model string) error {
return nil return nil
} }
if err := generate(cmd, model, line); err != nil { if len(line) > 0 && line[0] != '/' {
return err if err := generate(cmd, model, line); err != nil {
return err
}
} }
} }
} }

View file

@ -218,8 +218,12 @@ func GenerateHandler(c *gin.Context) {
ch <- r ch <- r
} }
if err := loaded.llm.Predict(c.Request.Context(), req.Context, prompt, fn); err != nil { if req.Prompt == "" {
ch <- gin.H{"error": err.Error()} ch <- api.GenerateResponse{Model: req.Model, Done: true}
} else {
if err := loaded.llm.Predict(c.Request.Context(), req.Context, prompt, fn); err != nil {
ch <- gin.H{"error": err.Error()}
}
} }
}() }()