diff --git a/go.mod b/go.mod index f0213f7e..1e379045 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/gptscript-ai/broadcaster v0.0.0-20240625175512-c43682019b86 github.com/gptscript-ai/chat-completion-client v0.0.0-20240531200700-af8e7ecf0379 github.com/gptscript-ai/cmd v0.0.0-20240625175447-4250b42feb7d - github.com/gptscript-ai/tui v0.0.0-20240716053605-ecddbcf60eac + github.com/gptscript-ai/tui v0.0.0-20240722014329-d50b5ac5db74 github.com/hexops/autogold/v2 v2.2.1 github.com/hexops/valast v1.4.4 github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 @@ -63,7 +63,7 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/gookit/color v1.5.4 // indirect github.com/gorilla/css v1.0.0 // indirect - github.com/gptscript-ai/go-gptscript v0.9.3-0.20240715172623-8176fb20c5cb // indirect + github.com/gptscript-ai/go-gptscript v0.9.3-0.20240722014125-d757d09f606b // 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 diff --git a/go.sum b/go.sum index 598a161e..881c5073 100644 --- a/go.sum +++ b/go.sum @@ -171,10 +171,10 @@ github.com/gptscript-ai/chat-completion-client v0.0.0-20240531200700-af8e7ecf037 github.com/gptscript-ai/chat-completion-client v0.0.0-20240531200700-af8e7ecf0379/go.mod h1:7P/o6/IWa1KqsntVf68hSnLKuu3+xuqm6lYhch1w4jo= github.com/gptscript-ai/cmd v0.0.0-20240625175447-4250b42feb7d h1:sKf7T7twhGXs6AVbvD9pKDVewykkwSAPwEpmIEQIR/4= github.com/gptscript-ai/cmd v0.0.0-20240625175447-4250b42feb7d/go.mod h1:DJAo1xTht1LDkNYFNydVjTHd576TC7MlpsVRl3oloVw= -github.com/gptscript-ai/go-gptscript v0.9.3-0.20240715172623-8176fb20c5cb h1:xeSbO4mLYnoTg7diNW0tpxY/0yDSSdgjohMzwE4Za6k= -github.com/gptscript-ai/go-gptscript v0.9.3-0.20240715172623-8176fb20c5cb/go.mod h1:Dh6vYRAiVcyC3ElZIGzTvNF1FxtYwA07BHfSiFKQY7s= -github.com/gptscript-ai/tui v0.0.0-20240716053605-ecddbcf60eac h1:zZ993dp2mx/63JD4THwMeBcn3C8SogcLeQRJUZsMSM4= -github.com/gptscript-ai/tui v0.0.0-20240716053605-ecddbcf60eac/go.mod h1:Ex2xQMzTMfb5UgLz9rctATPps8DnfPeJQh8o/AiQCoE= +github.com/gptscript-ai/go-gptscript v0.9.3-0.20240722014125-d757d09f606b h1:Hxu8oPE43uQ2sZ7P+9yGSX9bXh0RoJfOgvY/SlCwFlM= +github.com/gptscript-ai/go-gptscript v0.9.3-0.20240722014125-d757d09f606b/go.mod h1:Dh6vYRAiVcyC3ElZIGzTvNF1FxtYwA07BHfSiFKQY7s= +github.com/gptscript-ai/tui v0.0.0-20240722014329-d50b5ac5db74 h1:69BENZCN2y4BCxmPjMRp+ZQ47ay4i5gRgREKZatu5oE= +github.com/gptscript-ai/tui v0.0.0-20240722014329-d50b5ac5db74/go.mod h1:sP/9g7+nLq65aGef5F30AEG+Cuu4BwlglUYv1Pzps4Y= 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= diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go index e0ea5e3a..9e4b94fc 100644 --- a/pkg/engine/cmd.go +++ b/pkg/engine/cmd.go @@ -96,7 +96,7 @@ func (e *Engine) runCommand(ctx Context, tool types.Tool, input string, toolCate instructions = append(instructions, inputContext.Content) } var extraEnv = []string{ - strings.TrimSpace(fmt.Sprintf("GPTSCRIPT_CONTEXT=%s", strings.Join(instructions, "\n"))), + strings.TrimSpace("GPTSCRIPT_CONTEXT=" + strings.Join(instructions, "\n")), } cmd, stop, err := e.newCommand(ctx.Ctx, extraEnv, tool, input) diff --git a/pkg/env/env.go b/pkg/env/env.go index 7c8bd7c7..bedd5f9d 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -60,6 +60,10 @@ func AppendPath(env []string, binPath string) []string { // Lookup will try to find bin in the PATH in env. It will refer to PATHEXT for Windows support. // If bin can not be resolved to anything the original bin string is returned. func Lookup(env []string, bin string) string { + if strings.Contains(bin, string(filepath.Separator)) { + return bin + } + for _, env := range env { for _, prefix := range []string{"PATH=", "Path="} { suffix, ok := strings.CutPrefix(env, prefix) diff --git a/pkg/llm/registry.go b/pkg/llm/registry.go index ba648f58..c568b43c 100644 --- a/pkg/llm/registry.go +++ b/pkg/llm/registry.go @@ -7,6 +7,7 @@ import ( "sort" "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/remote" "github.com/gptscript-ai/gptscript/pkg/types" ) @@ -41,11 +42,39 @@ func (r *Registry) ListModels(ctx context.Context, providers ...string) (result return result, nil } +func (r *Registry) fastPath(modelName string) Client { + // This is optimization hack to avoid doing List Models + if len(r.clients) != 2 { + return nil + } + + _, modelFromProvider := types.SplitToolRef(modelName) + if modelFromProvider != "" { + return nil + } + + _, ok := r.clients[0].(*openai.Client) + if !ok { + return nil + } + + _, ok = r.clients[1].(*remote.Client) + if !ok { + return nil + } + + return r.clients[0] +} + func (r *Registry) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- types.CompletionStatus) (*types.CompletionMessage, error) { if messageRequest.Model == "" { return nil, fmt.Errorf("model is required") } + if c := r.fastPath(messageRequest.Model); c != nil { + return c.Call(ctx, messageRequest, status) + } + var errs []error var oaiClient *openai.Client for _, client := range r.clients { diff --git a/pkg/loader/url.go b/pkg/loader/url.go index 2035469e..41400790 100644 --- a/pkg/loader/url.go +++ b/pkg/loader/url.go @@ -7,6 +7,7 @@ import ( "net/http" url2 "net/url" "path" + "regexp" "strings" "time" @@ -33,6 +34,14 @@ type cacheValue struct { Time time.Time } +func (c *cacheKey) isStatic() bool { + return c.Repo != nil && + c.Repo.Revision != "" && + stableRef.MatchString(c.Repo.Revision) +} + +var stableRef = regexp.MustCompile("^([a-f0-9]{7,40}$|v[0-9]|[0-9])") + func loadURL(ctx context.Context, cache *cache.Client, base *source, name string) (*source, bool, error) { var ( repo *types.Repo @@ -47,9 +56,17 @@ func loadURL(ctx context.Context, cache *cache.Client, base *source, name string cachedValue cacheValue ) + if cachedKey.Repo == nil { + if _, rev, ok := strings.Cut(name, "@"); ok && stableRef.MatchString(rev) { + cachedKey.Repo = &types.Repo{ + Revision: rev, + } + } + } + if ok, err := cache.Get(ctx, cachedKey, &cachedValue); err != nil { return nil, false, err - } else if ok && time.Since(cachedValue.Time) < CacheTimeout { + } else if ok && (cachedKey.isStatic() || time.Since(cachedValue.Time) < CacheTimeout) { return cachedValue.Source, true, nil } diff --git a/pkg/types/tool.go b/pkg/types/tool.go index ad483984..82effad4 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -660,10 +660,12 @@ func (t Tool) addContextExportedTools(prg Program, result *toolRefSet) error { func (t Tool) getCompletionToolRefs(prg Program, agentGroup []ToolReference) ([]ToolReference, error) { result := toolRefSet{} - for _, agent := range agentGroup { - // don't add yourself - if agent.ToolID != t.ID { - result.Add(agent) + if t.Chat { + for _, agent := range agentGroup { + // don't add yourself + if agent.ToolID != t.ID { + result.Add(agent) + } } }