Compare commits

...

1 Commits

Author SHA1 Message Date
Michael Yang
50b9aff713 fix pasting slash commands
there is a bug in paste where the pasted content is written directly to
the prompt buffer instead of being processed. for most content, this is
fine but slash commands are processed line-by-line.

aggregate status updates, e.g. "Set 'verbose' mode.", "Set system
message.", to the end for aesthetics. the status message shouldn't
display while in paste mode
2024-01-17 16:58:55 -08:00

View File

@ -138,7 +138,7 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
fmt.Print(readline.StartBracketedPaste) fmt.Print(readline.StartBracketedPaste)
defer fmt.Printf(readline.EndBracketedPaste) defer fmt.Printf(readline.EndBracketedPaste)
var sb strings.Builder var sb, status strings.Builder
var multiline MultilineState var multiline MultilineState
opts.Messages = make([]api.Message, 0) opts.Messages = make([]api.Message, 0)
@ -174,11 +174,11 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
switch multiline { switch multiline {
case MultilineSystem: case MultilineSystem:
opts.System = sb.String() opts.System = sb.String()
fmt.Println("Set system message.") fmt.Fprintln(&status, "Set system message.")
sb.Reset() sb.Reset()
case MultilineTemplate: case MultilineTemplate:
opts.Template = sb.String() opts.Template = sb.String()
fmt.Println("Set prompt template.") fmt.Fprintln(&status, "Set prompt template.")
sb.Reset() sb.Reset()
} }
@ -195,9 +195,6 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
scanner.Prompt.UseAlt = true scanner.Prompt.UseAlt = true
break break
} }
case scanner.Pasting:
fmt.Fprintln(&sb, line)
continue
case strings.HasPrefix(line, "/list"): case strings.HasPrefix(line, "/list"):
args := strings.Fields(line) args := strings.Fields(line)
if err := ListHandler(cmd, args[1:]); err != nil { if err := ListHandler(cmd, args[1:]); err != nil {
@ -213,26 +210,26 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
scanner.HistoryDisable() scanner.HistoryDisable()
case "wordwrap": case "wordwrap":
opts.WordWrap = true opts.WordWrap = true
fmt.Println("Set 'wordwrap' mode.") fmt.Fprintln(&status, "Set 'wordwrap' mode.")
case "nowordwrap": case "nowordwrap":
opts.WordWrap = false opts.WordWrap = false
fmt.Println("Set 'nowordwrap' mode.") fmt.Fprintln(&status, "Set 'nowordwrap' mode.")
case "verbose": case "verbose":
cmd.Flags().Set("verbose", "true") cmd.Flags().Set("verbose", "true")
fmt.Println("Set 'verbose' mode.") fmt.Fprintln(&status, "Set 'verbose' mode.")
case "quiet": case "quiet":
cmd.Flags().Set("verbose", "false") cmd.Flags().Set("verbose", "false")
fmt.Println("Set 'quiet' mode.") fmt.Fprintln(&status, "Set 'quiet' mode.")
case "format": case "format":
if len(args) < 3 || args[2] != "json" { if len(args) < 3 || args[2] != "json" {
fmt.Println("Invalid or missing format. For 'json' mode use '/set format json'") fmt.Fprintln(&status, "Invalid or missing format. For 'json' mode use '/set format json'")
} else { } else {
opts.Format = args[2] opts.Format = args[2]
fmt.Printf("Set format to '%s' mode.\n", args[2]) fmt.Printf("Set format to '%s' mode.\n", args[2])
} }
case "noformat": case "noformat":
opts.Format = "" opts.Format = ""
fmt.Println("Disabled format.") fmt.Fprintln(&status, "Disabled format.")
case "parameter": case "parameter":
if len(args) < 4 { if len(args) < 4 {
usageParameters() usageParameters()
@ -241,10 +238,10 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
params := args[3:] params := args[3:]
fp, err := api.FormatParams(map[string][]string{args[2]: params}) fp, err := api.FormatParams(map[string][]string{args[2]: params})
if err != nil { if err != nil {
fmt.Printf("Couldn't set parameter: %q\n", err) fmt.Fprintf(&status, "Couldn't set parameter: %q\n", err)
continue continue
} }
fmt.Printf("Set parameter '%s' to '%s'\n", args[2], strings.Join(params, ", ")) fmt.Fprintf(&status, "Set parameter '%s' to '%s'\n", args[2], strings.Join(params, ", "))
opts.Options[args[2]] = fp[args[2]] opts.Options[args[2]] = fp[args[2]]
case "system", "template": case "system", "template":
if len(args) < 3 { if len(args) < 3 {
@ -278,10 +275,10 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
if args[1] == "system" { if args[1] == "system" {
opts.System = sb.String() opts.System = sb.String()
fmt.Println("Set system message.") fmt.Fprintln(&status, "Set system message.")
} else if args[1] == "template" { } else if args[1] == "template" {
opts.Template = sb.String() opts.Template = sb.String()
fmt.Println("Set prompt template.") fmt.Fprintln(&status, "Set prompt template.")
} }
sb.Reset() sb.Reset()
@ -297,7 +294,7 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
if len(args) > 1 { if len(args) > 1 {
client, err := api.ClientFromEnvironment() client, err := api.ClientFromEnvironment()
if err != nil { if err != nil {
fmt.Println("error: couldn't connect to ollama server") fmt.Fprintln(&status, "error: couldn't connect to ollama server")
return err return err
} }
req := &api.ShowRequest{ req := &api.ShowRequest{
@ -308,13 +305,13 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
} }
resp, err := client.Show(cmd.Context(), req) resp, err := client.Show(cmd.Context(), req)
if err != nil { if err != nil {
fmt.Println("error: couldn't get model") fmt.Fprintln(&status, "error: couldn't get model")
return err return err
} }
switch args[1] { switch args[1] {
case "info": case "info":
fmt.Println("Model details:") fmt.Fprintln(&status, "Model details:")
if len(resp.Details.Families) > 0 { if len(resp.Details.Families) > 0 {
fmt.Printf("Family %s\n", strings.Join(resp.Details.Families, ", ")) fmt.Printf("Family %s\n", strings.Join(resp.Details.Families, ", "))
} else if resp.Details.Family != "" { } else if resp.Details.Family != "" {
@ -322,27 +319,28 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
} }
fmt.Printf("Parameter Size %s\n", resp.Details.ParameterSize) fmt.Printf("Parameter Size %s\n", resp.Details.ParameterSize)
fmt.Printf("Quantization Level %s\n", resp.Details.QuantizationLevel) fmt.Printf("Quantization Level %s\n", resp.Details.QuantizationLevel)
fmt.Println("") fmt.Fprintln(&status, "")
case "license": case "license":
if resp.License == "" { if resp.License == "" {
fmt.Println("No license was specified for this model.") fmt.Fprintln(&status, "No license was specified for this model.")
} else { } else {
fmt.Println(resp.License) status.WriteString(resp.License)
fmt.Fprintln(&status)
} }
case "modelfile": case "modelfile":
fmt.Println(resp.Modelfile) fmt.Println(resp.Modelfile)
case "parameters": case "parameters":
if resp.Parameters == "" { if resp.Parameters == "" {
fmt.Println("No parameters were specified for this model.") fmt.Fprintln(&status, "No parameters were specified for this model.")
} else { } else {
if len(opts.Options) > 0 { if len(opts.Options) > 0 {
fmt.Println("User defined parameters:") fmt.Fprintln(&status, "User defined parameters:")
for k, v := range opts.Options { for k, v := range opts.Options {
fmt.Printf("%-*s %v\n", 30, k, v) fmt.Printf("%-*s %v\n", 30, k, v)
} }
fmt.Println() fmt.Println()
} }
fmt.Println("Model defined parameters:") fmt.Fprintln(&status, "Model defined parameters:")
fmt.Println(resp.Parameters) fmt.Println(resp.Parameters)
} }
case "system": case "system":
@ -352,7 +350,7 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
case resp.System != "": case resp.System != "":
fmt.Println(resp.System + "\n") fmt.Println(resp.System + "\n")
default: default:
fmt.Println("No system message was specified for this model.") fmt.Fprintln(&status, "No system message was specified for this model.")
} }
case "template": case "template":
switch { switch {
@ -361,7 +359,7 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
case resp.Template != "": case resp.Template != "":
fmt.Println(resp.Template) fmt.Println(resp.Template)
default: default:
fmt.Println("No prompt template was specified for this model.") fmt.Fprintln(&status, "No prompt template was specified for this model.")
} }
default: default:
fmt.Printf("Unknown command '/show %s'. Type /? for help\n", args[1]) fmt.Printf("Unknown command '/show %s'. Type /? for help\n", args[1])
@ -408,6 +406,15 @@ func generateInteractive(cmd *cobra.Command, opts runOptions) error {
sb.WriteString(line) sb.WriteString(line)
} }
if scanner.Pasting {
continue
}
if status.Len() > 0 {
fmt.Println(status.String())
status.Reset()
}
if sb.Len() > 0 && multiline == MultilineNone { if sb.Len() > 0 && multiline == MultilineNone {
newMessage := api.Message{Role: "user", Content: sb.String()} newMessage := api.Message{Role: "user", Content: sb.String()}