Skip to content

Commit

Permalink
feat: add server URL and token options
Browse files Browse the repository at this point in the history
If the server URL has a path, then the SDK will implicitly disable the
server since the local SDK server cannot have a path.

Signed-off-by: Donnie Adams <[email protected]>
  • Loading branch information
thedadams committed Sep 3, 2024
1 parent c0fb2e8 commit 66dc396
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 26 deletions.
57 changes: 43 additions & 14 deletions gptscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"fmt"
"io"
"log/slog"
"net/url"
"os"
"os/exec"
"path/filepath"
Expand All @@ -28,7 +29,6 @@ var (
const relativeToBinaryPath = "<me>"

type GPTScript struct {
url string
globalOpts GlobalOptions
}

Expand All @@ -38,10 +38,11 @@ func NewGPTScript(opts ...GlobalOptions) (*GPTScript, error) {
defer lock.Unlock()
gptscriptCount++

disableServer := os.Getenv("GPTSCRIPT_DISABLE_SERVER") == "true"

if serverURL == "" {
serverURL = os.Getenv("GPTSCRIPT_URL")
serverURL = opt.URL
if serverURL == "" {
serverURL = os.Getenv("GPTSCRIPT_URL")
}
}

if opt.Env == nil {
Expand All @@ -50,11 +51,31 @@ func NewGPTScript(opts ...GlobalOptions) (*GPTScript, error) {

opt.Env = append(opt.Env, opt.toEnv()...)

if serverProcessCancel == nil && !disableServer {
if serverProcessCancel == nil && os.Getenv("GPTSCRIPT_DISABLE_SERVER") != "true" {
if serverURL != "" {
u, err := url.Parse(serverURL)
if err != nil {
return nil, fmt.Errorf("failed to parse server URL: %w", err)
}

// If the server URL has a path, then this implies that the server is already running.
// In that case, we don't need to start the server.
if u.Path != "" && u.Path != "/" {
opt.URL = serverURL
if !strings.HasPrefix(opt.URL, "http://") && !strings.HasPrefix(opt.URL, "https://") {
opt.URL = "http://" + opt.URL
}

return &GPTScript{
globalOpts: opt,
}, nil
}
}

ctx, cancel := context.WithCancel(context.Background())
in, _ := io.Pipe()

serverProcess = exec.CommandContext(ctx, getCommand(), "sys.sdkserver", "--listen-address", serverURL)
serverProcess = exec.CommandContext(ctx, getCommand(), "sys.sdkserver", "--listen-address", strings.TrimPrefix(serverURL, "http://"))
serverProcess.Env = opt.Env[:]

serverProcess.Stdin = in
Expand Down Expand Up @@ -95,12 +116,14 @@ func NewGPTScript(opts ...GlobalOptions) (*GPTScript, error) {

serverURL = strings.TrimSpace(serverURL)
}
g := &GPTScript{
url: "http://" + serverURL,
globalOpts: opt,
}

return g, nil
opt.URL = serverURL
if !strings.HasPrefix(opt.URL, "http://") && !strings.HasPrefix(opt.URL, "https://") {
opt.URL = "http://" + opt.URL
}
return &GPTScript{
globalOpts: opt,
}, nil
}

func readAddress(stdErr io.Reader) (string, error) {
Expand All @@ -117,6 +140,10 @@ func readAddress(stdErr io.Reader) (string, error) {
return addr, nil
}

func (g *GPTScript) URL() string {
return g.globalOpts.URL
}

func (g *GPTScript) Close() {
lock.Lock()
defer lock.Unlock()
Expand All @@ -131,7 +158,8 @@ func (g *GPTScript) Close() {
func (g *GPTScript) Evaluate(ctx context.Context, opts Options, tools ...ToolDef) (*Run, error) {
opts.GlobalOptions = completeGlobalOptions(g.globalOpts, opts.GlobalOptions)
return (&Run{
url: g.url,
url: opts.URL,
token: opts.Token,
requestPath: "evaluate",
state: Creating,
opts: opts,
Expand All @@ -142,7 +170,8 @@ func (g *GPTScript) Evaluate(ctx context.Context, opts Options, tools ...ToolDef
func (g *GPTScript) Run(ctx context.Context, toolPath string, opts Options) (*Run, error) {
opts.GlobalOptions = completeGlobalOptions(g.globalOpts, opts.GlobalOptions)
return (&Run{
url: g.url,
url: opts.URL,
token: opts.Token,
requestPath: "run",
state: Creating,
opts: opts,
Expand Down Expand Up @@ -309,7 +338,7 @@ func (g *GPTScript) PromptResponse(ctx context.Context, resp PromptResponse) err

func (g *GPTScript) runBasicCommand(ctx context.Context, requestPath string, body any) (string, error) {
run := &Run{
url: g.url,
url: g.globalOpts.URL,
requestPath: requestPath,
state: Creating,
basicCommand: true,
Expand Down
4 changes: 4 additions & 0 deletions opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package gptscript
// GlobalOptions allows specification of settings that are used for every call made.
// These options can be overridden by the corresponding Options.
type GlobalOptions struct {
URL string `json:"url"`
Token string `json:"token"`
OpenAIAPIKey string `json:"APIKey"`
OpenAIBaseURL string `json:"BaseURL"`
DefaultModel string `json:"DefaultModel"`
Expand Down Expand Up @@ -33,6 +35,8 @@ func completeGlobalOptions(opts ...GlobalOptions) GlobalOptions {
var result GlobalOptions
for _, opt := range opts {
result.CacheDir = firstSet(opt.CacheDir, result.CacheDir)
result.URL = firstSet(opt.URL, result.URL)
result.Token = firstSet(opt.Token, result.Token)
result.OpenAIAPIKey = firstSet(opt.OpenAIAPIKey, result.OpenAIAPIKey)
result.OpenAIBaseURL = firstSet(opt.OpenAIBaseURL, result.OpenAIBaseURL)
result.DefaultModel = firstSet(opt.DefaultModel, result.DefaultModel)
Expand Down
34 changes: 22 additions & 12 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import (
var errAbortRun = errors.New("run aborted")

type Run struct {
url, requestPath, toolPath string
tools []ToolDef
opts Options
state RunState
chatState string
cancel context.CancelCauseFunc
err error
wait func()
basicCommand bool
url, token, requestPath, toolPath string
tools []ToolDef
opts Options
state RunState
chatState string
cancel context.CancelCauseFunc
err error
wait func()
basicCommand bool

program *Program
callsLock sync.RWMutex
Expand Down Expand Up @@ -175,18 +175,24 @@ func (r *Run) NextChat(ctx context.Context, input string) (*Run, error) {
run.opts.ChatState = r.chatState
}

var payload any
var (
payload any
options = run.opts
)
// Remove the url and token because they shouldn't be sent with the payload.
options.URL = ""
options.Token = ""
if len(r.tools) != 0 {
payload = requestPayload{
ToolDefs: r.tools,
Input: input,
Options: run.opts,
Options: options,
}
} else if run.toolPath != "" {
payload = requestPayload{
File: run.toolPath,
Input: input,
Options: run.opts,
Options: options,
}
}

Expand Down Expand Up @@ -228,6 +234,10 @@ func (r *Run) request(ctx context.Context, payload any) (err error) {
return r.err
}

if r.opts.Token != "" {
req.Header.Set("Authorization", "Bearer "+r.opts.Token)
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
r.state = Error
Expand Down

0 comments on commit 66dc396

Please sign in to comment.