Skip to content

chore: add --save-chat-state-file #439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.6.0
github.com/gptscript-ai/chat-completion-client v0.0.0-20240515050533-bdef9f2226a9
github.com/gptscript-ai/tui v0.0.0-20240604045848-e01b0b7aab9f
github.com/gptscript-ai/tui v0.0.0-20240604233332-4a5ff43cdc58
github.com/hexops/autogold/v2 v2.2.1
github.com/hexops/valast v1.4.4
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
Expand Down Expand Up @@ -62,7 +62,7 @@ require (
github.com/gookit/color v1.5.4 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gptscript-ai/go-gptscript v0.0.0-20240604030145-39497c0575b3 // indirect
github.com/gptscript-ai/go-gptscript v0.0.0-20240604231423-7a845df843b1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hexops/autogold v1.3.1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gptscript-ai/chat-completion-client v0.0.0-20240515050533-bdef9f2226a9 h1:s6nL/aokB1sJTqVXEjN0zFI5CJa66ubw9g68VTMzEw0=
github.com/gptscript-ai/chat-completion-client v0.0.0-20240515050533-bdef9f2226a9/go.mod h1:7P/o6/IWa1KqsntVf68hSnLKuu3+xuqm6lYhch1w4jo=
github.com/gptscript-ai/go-gptscript v0.0.0-20240604030145-39497c0575b3 h1:mXLpCzEg4DoOeFZt6w99QFh9n60UwpRGGG0c+aaT+5k=
github.com/gptscript-ai/go-gptscript v0.0.0-20240604030145-39497c0575b3/go.mod h1:h1yYzC0rgB5Kk7lwdba+Xs6cWkuJfLq6sPRna45OVG0=
github.com/gptscript-ai/tui v0.0.0-20240604045848-e01b0b7aab9f h1:7dCE0E/y3y3p1BPSQGQ4mtsz5cWWl0FbXfCCDCf57SI=
github.com/gptscript-ai/tui v0.0.0-20240604045848-e01b0b7aab9f/go.mod h1:ybD/8QfwaMiK2QUSnnTxgzrIaXRgipowU4pW1qxgNJ8=
github.com/gptscript-ai/go-gptscript v0.0.0-20240604231423-7a845df843b1 h1:SHoqsU8Ne2V4zfrFve9kQn4vcv4N4TItD6Oju+pzKV8=
github.com/gptscript-ai/go-gptscript v0.0.0-20240604231423-7a845df843b1/go.mod h1:h1yYzC0rgB5Kk7lwdba+Xs6cWkuJfLq6sPRna45OVG0=
github.com/gptscript-ai/tui v0.0.0-20240604233332-4a5ff43cdc58 h1:kbr6cY4VdvxAfJf+xk6x/gxDzmgZMkX2ZfLcyskGYsw=
github.com/gptscript-ai/tui v0.0.0-20240604233332-4a5ff43cdc58/go.mod h1:At6zmCk0XrJ2J1yo95fzbEDOGwaPPEMwxxcQGJx7IGE=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
Expand Down
17 changes: 14 additions & 3 deletions pkg/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chat

import (
"context"
"os"

"github.com/fatih/color"
"github.com/gptscript-ai/gptscript/pkg/runner"
Expand Down Expand Up @@ -30,7 +31,7 @@ func getPrompt(prg types.Program, resp runner.ChatResponse) string {
return color.GreenString("%s> ", name)
}

func Start(ctx context.Context, prevState runner.ChatState, chatter Chatter, prg GetProgram, env []string, startInput string) error {
func Start(ctx context.Context, prevState runner.ChatState, chatter Chatter, prg GetProgram, env []string, startInput, chatStateSaveFile string) error {
var (
prompter Prompter
)
Expand Down Expand Up @@ -60,7 +61,7 @@ func Start(ctx context.Context, prevState runner.ChatState, chatter Chatter, prg
if startInput != "" {
input = startInput
startInput = ""
} else if targetTool := prg.ToolSet[prg.EntryToolID]; !(prevState == nil && targetTool.Arguments == nil && targetTool.Instructions != "") {
} else if targetTool := prg.ToolSet[prg.EntryToolID]; !((prevState == nil || prevState == "") && targetTool.Arguments == nil && targetTool.Instructions != "") {
// The above logic will skip prompting if this is the first loop and the chat expects no args
input, ok, err = prompter.Readline()
if !ok || err != nil {
Expand All @@ -69,9 +70,15 @@ func Start(ctx context.Context, prevState runner.ChatState, chatter Chatter, prg
}

resp, err = chatter.Chat(ctx, prevState, prg, env, input)
if err != nil || resp.Done {
if err != nil {
return err
}
if resp.Done {
if chatStateSaveFile != "" {
_ = os.Remove(chatStateSaveFile)
}
return nil
}

if resp.Content != "" {
_, err := prompter.Printf("%s", color.RedString("< %s\n", resp.Content))
Expand All @@ -80,6 +87,10 @@ func Start(ctx context.Context, prevState runner.ChatState, chatter Chatter, prg
}
}

if chatStateSaveFile != "" {
_ = os.WriteFile(chatStateSaveFile, []byte(resp.Content), 0600)
}

prevState = resp.State
prevResp = resp
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (e *Eval) Run(cmd *cobra.Command, args []string) error {
if e.Chat {
return chat.Start(cmd.Context(), nil, runner, func() (types.Program, error) {
return prg, nil
}, os.Environ(), toolInput)
}, os.Environ(), toolInput, "")
}

toolOutput, err := runner.Run(cmd.Context(), prg, opts.Env, toolInput)
Expand Down
27 changes: 20 additions & 7 deletions pkg/cli/gptscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ type GPTScript struct {
Ports string `usage:"The port range to use for ephemeral daemon ports (ex: 11000-12000)" hidden:"true"`
CredentialContext string `usage:"Context name in which to store credentials" default:"default"`
CredentialOverride string `usage:"Credentials to override (ex: --credential-override github.com/example/cred-tool:API_TOKEN=1234)"`
ChatState string `usage:"The chat state to continue, or null to start a new chat and return the state"`
ForceChat bool `usage:"Force an interactive chat session if even the top level tool is not a chat tool"`
ForceSequential bool `usage:"Force parallel calls to run sequentially"`
ChatState string `usage:"The chat state to continue, or null to start a new chat and return the state" local:"true"`
ForceChat bool `usage:"Force an interactive chat session if even the top level tool is not a chat tool" local:"true"`
ForceSequential bool `usage:"Force parallel calls to run sequentially" local:"true"`
Workspace string `usage:"Directory to use for the workspace, if specified it will not be deleted on exit"`
UI bool `usage:"Launch the UI" local:"true" name:"ui"`
DisableTUI bool `usage:"Don't use chat TUI but instead verbose output" local:"true" name:"disable-tui"`
SaveChatStateFile string `usage:"A file to save the chat state to so that a conversation can be resumed with --chat-state" local:"true"`

readData []byte
}
Expand Down Expand Up @@ -425,8 +426,18 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) (retErr error) {
return err
}

if r.ChatState != "" {
resp, err := gptScript.Chat(cmd.Context(), r.ChatState, prg, gptOpt.Env, toolInput)
var chatState string
if r.ChatState != "" && r.ChatState != "null" && !strings.HasPrefix(r.ChatState, "{") {
data, err := os.ReadFile(r.ChatState)
if err != nil {
return fmt.Errorf("reading %s: %w", r.ChatState, err)
}
chatState = string(data)
}

// This chat in a stateless mode
if r.SaveChatStateFile == "-" || r.SaveChatStateFile == "stdout" {
resp, err := gptScript.Chat(cmd.Context(), chatState, prg, gptOpt.Env, toolInput)
if err != nil {
return err
}
Expand All @@ -446,11 +457,13 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) (retErr error) {
CacheDir: r.CacheDir,
SubTool: r.SubTool,
Workspace: r.Workspace,
SaveChatStateFile: r.SaveChatStateFile,
ChatState: chatState,
})
}
return chat.Start(cmd.Context(), nil, gptScript, func() (types.Program, error) {
return chat.Start(cmd.Context(), chatState, gptScript, func() (types.Program, error) {
return r.readProgram(ctx, gptScript, args)
}, gptOpt.Env, toolInput)
}, gptOpt.Env, toolInput, r.SaveChatStateFile)
}

s, err := gptScript.Run(cmd.Context(), prg, gptOpt.Env, toolInput)
Expand Down
2 changes: 1 addition & 1 deletion pkg/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (r *Runner) Chat(ctx context.Context, prevState ChatState, prg types.Progra
case *State:
state = v
case string:
if v != "null" {
if v != "null" && v != "" {
state = &State{}
if err := json.Unmarshal([]byte(v), state); err != nil {
return resp, fmt.Errorf("failed to unmarshal chat state: %w", err)
Expand Down