From a774c1d2f7dc93fdecf3ccb208e55fb4da47d8b3 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 13 Jun 2024 15:04:07 -0700 Subject: [PATCH 1/2] chore: allow easy embedding on gptscript --- internal/fs.go | 14 ++++++++++++++ main.go | 19 +------------------ pkg/cli/gptscript.go | 2 +- pkg/cli/main.go | 22 ++++++++++++++++++++++ pkg/embedded/embed.go | 31 +++++++++++++++++++++++++++++++ pkg/loader/loader.go | 8 ++++---- pkg/parser/parser.go | 3 ++- pkg/system/bin.go | 6 ++++++ 8 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 internal/fs.go create mode 100644 pkg/cli/main.go create mode 100644 pkg/embedded/embed.go diff --git a/internal/fs.go b/internal/fs.go new file mode 100644 index 00000000..4d02f345 --- /dev/null +++ b/internal/fs.go @@ -0,0 +1,14 @@ +package internal + +import ( + "io/fs" + "os" +) + +var FS fs.FS = defaultFS{} + +type defaultFS struct{} + +func (d defaultFS) Open(name string) (fs.File, error) { + return os.Open(name) +} diff --git a/main.go b/main.go index 8cde4a88..33ab4278 100644 --- a/main.go +++ b/main.go @@ -1,28 +1,11 @@ package main import ( - "os" - - "github.com/acorn-io/cmd" "github.com/gptscript-ai/gptscript/pkg/cli" - "github.com/gptscript-ai/gptscript/pkg/daemon" - "github.com/gptscript-ai/gptscript/pkg/mvl" - // Load all VCS _ "github.com/gptscript-ai/gptscript/pkg/loader/vcs" ) -var log = mvl.Package() - func main() { - if len(os.Args) > 2 && os.Args[1] == "sys.daemon" { - if os.Getenv("GPTSCRIPT_DEBUG") == "true" { - mvl.SetDebug() - } - if err := daemon.SysDaemon(); err != nil { - log.Debugf("failed running daemon: %v", err) - } - os.Exit(0) - } - cmd.Main(cli.New()) + cli.Main() } diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 97e84d0f..924c9218 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -218,7 +218,7 @@ func (r *GPTScript) PersistentPre(*cobra.Command, []string) error { } } - _ = os.Setenv(system.BinEnvVar, system.Bin()) + system.SetBinToSelf() if r.DefaultModel != "" { builtin.SetDefaultModel(r.DefaultModel) diff --git a/pkg/cli/main.go b/pkg/cli/main.go new file mode 100644 index 00000000..b4b55928 --- /dev/null +++ b/pkg/cli/main.go @@ -0,0 +1,22 @@ +package cli + +import ( + "os" + + "github.com/acorn-io/cmd" + "github.com/gptscript-ai/gptscript/pkg/daemon" + "github.com/gptscript-ai/gptscript/pkg/mvl" +) + +func Main() { + if len(os.Args) > 2 && os.Args[1] == "sys.daemon" { + if os.Getenv("GPTSCRIPT_DEBUG") == "true" { + mvl.SetDebug() + } + if err := daemon.SysDaemon(); err != nil { + log.Debugf("failed running daemon: %v", err) + } + os.Exit(0) + } + cmd.Main(New()) +} diff --git a/pkg/embedded/embed.go b/pkg/embedded/embed.go new file mode 100644 index 00000000..de12bec3 --- /dev/null +++ b/pkg/embedded/embed.go @@ -0,0 +1,31 @@ +package embedded + +import ( + "io/fs" + "os" + "strings" + + "github.com/gptscript-ai/gptscript/internal" + "github.com/gptscript-ai/gptscript/pkg/cli" + "github.com/gptscript-ai/gptscript/pkg/system" +) + +type Options struct { + FS fs.FS +} + +func Run(opts ...Options) bool { + for _, opt := range opts { + if opt.FS == nil { + internal.FS = opt.FS + } + } + + system.SetBinToSelf() + if len(os.Args) > 1 && strings.HasPrefix(os.Args[1], "sys.") { + cli.Main() + return true + } + + return false +} diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 7d1142a2..1b119067 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "io/fs" - "os" "path" "path/filepath" "strconv" @@ -19,6 +18,7 @@ import ( "github.com/getkin/kin-openapi/openapi2" "github.com/getkin/kin-openapi/openapi2conv" "github.com/getkin/kin-openapi/openapi3" + "github.com/gptscript-ai/gptscript/internal" "github.com/gptscript-ai/gptscript/pkg/assemble" "github.com/gptscript-ai/gptscript/pkg/builtin" "github.com/gptscript-ai/gptscript/pkg/cache" @@ -61,7 +61,7 @@ func (s *source) String() string { } func openFile(path string) (io.ReadCloser, bool, error) { - f, err := os.Open(path) + f, err := internal.FS.Open(path) if errors.Is(err, fs.ErrNotExist) { return nil, false, nil } else if err != nil { @@ -74,10 +74,10 @@ func loadLocal(base *source, name string) (*source, bool, error) { // We want to keep all strings in / format, and only convert to platform specific when reading filePath := path.Join(base.Path, name) - if s, err := os.Stat(filepath.Clean(filePath)); err == nil && s.IsDir() { + if s, err := fs.Stat(internal.FS, filepath.Clean(filePath)); err == nil && s.IsDir() { for _, def := range types.DefaultFiles { toolPath := path.Join(filePath, def) - if s, err := os.Stat(filepath.Clean(toolPath)); err == nil && !s.IsDir() { + if s, err := fs.Stat(internal.FS, filepath.Clean(toolPath)); err == nil && !s.IsDir() { filePath = toolPath break } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index b5e5269a..cf2f2cf9 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -24,7 +24,8 @@ func normalize(key string) string { } func toBool(line string) (bool, error) { - if line == "true" { + line = normalize(line) + if line == "true" || line == "t" { return true, nil } else if line != "false" { return false, fmt.Errorf("invalid boolean parameter, must be \"true\" or \"false\", got [%s]", line) diff --git a/pkg/system/bin.go b/pkg/system/bin.go index 21bea875..1c34a56f 100644 --- a/pkg/system/bin.go +++ b/pkg/system/bin.go @@ -4,6 +4,12 @@ import "os" const BinEnvVar = "GPTSCRIPT_BIN" +func SetBinToSelf() { + if err := os.Setenv(BinEnvVar, Bin()); err != nil { + panic(err) + } +} + func Bin() string { bin := os.Getenv(BinEnvVar) if bin != "" { From e6123e636f919e1c8588c64facf5d73f291caaec Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 13 Jun 2024 19:24:00 -0700 Subject: [PATCH 2/2] chore: make sys.sdkserver change backwards compatible --- pkg/cli/gptscript.go | 1 + pkg/cli/sdk_server.go | 2 +- pkg/system/currentbin.go | 2 -- pkg/system/currentbin_linux.go | 8 -------- 4 files changed, 2 insertions(+), 11 deletions(-) delete mode 100644 pkg/system/currentbin_linux.go diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 924c9218..2db70c46 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -57,6 +57,7 @@ type GPTScript struct { Assemble bool `usage:"Assemble tool to a single artifact, saved to --output" hidden:"true" local:"true"` ListModels bool `usage:"List the models available and exit" local:"true"` ListTools bool `usage:"List built-in tools and exit" local:"true"` + ListenAddress string `usage:"Server listen address" default:"127.0.0.1:0" hidden:"true"` Chdir string `usage:"Change current working directory" short:"C"` Daemon bool `usage:"Run tool as a daemon" local:"true" hidden:"true"` Ports string `usage:"The port range to use for ephemeral daemon ports (ex: 11000-12000)" hidden:"true"` diff --git a/pkg/cli/sdk_server.go b/pkg/cli/sdk_server.go index 9d860f00..a2ac8488 100644 --- a/pkg/cli/sdk_server.go +++ b/pkg/cli/sdk_server.go @@ -11,12 +11,12 @@ import ( type SDKServer struct { *GPTScript - ListenAddress string `usage:"Server listen address" default:"127.0.0.1:0" local:"true"` } func (c *SDKServer) Customize(cmd *cobra.Command) { cmd.Use = "sys.sdkserver" cmd.Args = cobra.NoArgs + cmd.Aliases = []string{"sdkserver"} cmd.Hidden = true } diff --git a/pkg/system/currentbin.go b/pkg/system/currentbin.go index 8acd2df9..8eb79b24 100644 --- a/pkg/system/currentbin.go +++ b/pkg/system/currentbin.go @@ -1,5 +1,3 @@ -//go:build !linux - package system import ( diff --git a/pkg/system/currentbin_linux.go b/pkg/system/currentbin_linux.go deleted file mode 100644 index df106b11..00000000 --- a/pkg/system/currentbin_linux.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build linux - -package system - -func currentBin() string { - // Linux is simple, always use this path - return "/proc/self/exe" -}