Skip to content

Commit c624844

Browse files
chore: look for agent.gpt and then tool.gpt when referencing folders
1 parent 172dfb0 commit c624844

File tree

5 files changed

+161
-13
lines changed

5 files changed

+161
-13
lines changed

pkg/loader/github/github.go

+31-10
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import (
77
"io"
88
"net/http"
99
"os"
10-
"path/filepath"
10+
gpath "path"
1111
"regexp"
1212
"strings"
1313

1414
"github.com/gptscript-ai/gptscript/pkg/cache"
1515
"github.com/gptscript-ai/gptscript/pkg/loader"
1616
"github.com/gptscript-ai/gptscript/pkg/mvl"
1717
"github.com/gptscript-ai/gptscript/pkg/repos/git"
18-
"github.com/gptscript-ai/gptscript/pkg/system"
1918
"github.com/gptscript-ai/gptscript/pkg/types"
2019
)
2120

@@ -108,23 +107,45 @@ func Load(ctx context.Context, _ *cache.Client, urlName string) (string, *types.
108107
account, repo := parts[1], parts[2]
109108
path := strings.Join(parts[3:], "/")
110109

111-
if path == "" || path == "/" {
112-
path = "tool.gpt"
113-
} else if !strings.HasSuffix(path, system.Suffix) && !strings.Contains(parts[len(parts)-1], ".") {
114-
path += "/tool.gpt"
115-
}
116-
117110
ref, err := getCommit(ctx, account, repo, ref)
118111
if err != nil {
119112
return "", nil, false, err
120113
}
121114

122115
downloadURL := fmt.Sprintf(githubDownloadURL, account, repo, ref, path)
116+
if path == "" || path == "/" || !strings.Contains(parts[len(parts)-1], ".") {
117+
var (
118+
testPath string
119+
testURL string
120+
)
121+
for i, ext := range types.DefaultFiles {
122+
if strings.HasSuffix(path, "/") {
123+
testPath = path + ext
124+
} else {
125+
testPath = path + "/" + ext
126+
}
127+
testURL = fmt.Sprintf(githubDownloadURL, account, repo, ref, testPath)
128+
if i == len(types.DefaultFiles)-1 {
129+
// no reason to test the last one, we are just going to use it. Being that the default list is only
130+
// two elements this loop could have been one check, but hey over-engineered code ftw.
131+
break
132+
}
133+
if resp, err := http.Head(testURL); err == nil {
134+
_ = resp.Body.Close()
135+
if resp.StatusCode == 200 {
136+
break
137+
}
138+
}
139+
}
140+
downloadURL = testURL
141+
path = testPath
142+
}
143+
123144
return downloadURL, &types.Repo{
124145
VCS: "git",
125146
Root: fmt.Sprintf(githubRepoURL, account, repo),
126-
Path: filepath.Dir(path),
127-
Name: filepath.Base(path),
147+
Path: gpath.Dir(path),
148+
Name: gpath.Base(path),
128149
Revision: ref,
129150
}, true, nil
130151
}

pkg/loader/github/github_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/gptscript-ai/gptscript/pkg/types"
8+
"github.com/hexops/autogold/v2"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestLoad(t *testing.T) {
14+
url, repo, ok, err := Load(context.Background(), nil, "github.com/gptscript-ai/gptscript/pkg/loader/testdata/tool@172dfb0")
15+
require.NoError(t, err)
16+
assert.True(t, ok)
17+
autogold.Expect("https://raw.githubusercontent.com/gptscript-ai/gptscript/172dfb00b48c6adbbaa7e99270933f95887d1b91/pkg/loader/testdata/tool/tool.gpt").Equal(t, url)
18+
autogold.Expect(&types.Repo{
19+
VCS: "git", Root: "https://github.com/gptscript-ai/gptscript.git",
20+
Path: "pkg/loader/testdata/tool",
21+
Name: "tool.gpt",
22+
Revision: "172dfb00b48c6adbbaa7e99270933f95887d1b91",
23+
}).Equal(t, repo)
24+
25+
url, repo, ok, err = Load(context.Background(), nil, "github.com/gptscript-ai/gptscript/pkg/loader/testdata/agent@172dfb0")
26+
require.NoError(t, err)
27+
assert.True(t, ok)
28+
autogold.Expect("https://raw.githubusercontent.com/gptscript-ai/gptscript/172dfb00b48c6adbbaa7e99270933f95887d1b91/pkg/loader/testdata/agent/agent.gpt").Equal(t, url)
29+
autogold.Expect(&types.Repo{
30+
VCS: "git", Root: "https://github.com/gptscript-ai/gptscript.git",
31+
Path: "pkg/loader/testdata/agent",
32+
Name: "agent.gpt",
33+
Revision: "172dfb00b48c6adbbaa7e99270933f95887d1b91",
34+
}).Equal(t, repo)
35+
36+
url, repo, ok, err = Load(context.Background(), nil, "github.com/gptscript-ai/gptscript/pkg/loader/testdata/bothtoolagent@172dfb0")
37+
require.NoError(t, err)
38+
assert.True(t, ok)
39+
autogold.Expect("https://raw.githubusercontent.com/gptscript-ai/gptscript/172dfb00b48c6adbbaa7e99270933f95887d1b91/pkg/loader/testdata/bothtoolagent/agent.gpt").Equal(t, url)
40+
autogold.Expect(&types.Repo{
41+
VCS: "git", Root: "https://github.com/gptscript-ai/gptscript.git",
42+
Path: "pkg/loader/testdata/bothtoolagent",
43+
Name: "agent.gpt",
44+
Revision: "172dfb00b48c6adbbaa7e99270933f95887d1b91",
45+
}).Equal(t, repo)
46+
}

pkg/loader/loader.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ func loadLocal(base *source, name string) (*source, bool, error) {
7575
filePath := path.Join(base.Path, name)
7676

7777
if s, err := os.Stat(filepath.Clean(filePath)); err == nil && s.IsDir() {
78-
toolPath := path.Join(filePath, "tool.gpt")
79-
if s, err := os.Stat(filepath.Clean(toolPath)); err == nil && !s.IsDir() {
80-
filePath = toolPath
78+
for _, def := range types.DefaultFiles {
79+
toolPath := path.Join(filePath, def)
80+
if s, err := os.Stat(filepath.Clean(toolPath)); err == nil && !s.IsDir() {
81+
filePath = toolPath
82+
break
83+
}
8184
}
8285
}
8386

pkg/loader/loader_test.go

+74
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,77 @@ func TestHelloWorld(t *testing.T) {
194194
}
195195
}`).Equal(t, toString(prg))
196196
}
197+
198+
func TestDefault(t *testing.T) {
199+
prg, err := Program(context.Background(), "./testdata/tool", "")
200+
require.NoError(t, err)
201+
autogold.Expect(`{
202+
"name": "./testdata/tool",
203+
"entryToolId": "testdata/tool/tool.gpt:tool",
204+
"toolSet": {
205+
"testdata/tool/tool.gpt:tool": {
206+
"name": "tool",
207+
"modelName": "gpt-4o",
208+
"internalPrompt": null,
209+
"instructions": "a tool",
210+
"id": "testdata/tool/tool.gpt:tool",
211+
"localTools": {
212+
"tool": "testdata/tool/tool.gpt:tool"
213+
},
214+
"source": {
215+
"location": "testdata/tool/tool.gpt",
216+
"lineNo": 1
217+
},
218+
"workingDir": "testdata/tool"
219+
}
220+
}
221+
}`).Equal(t, toString(prg))
222+
223+
prg, err = Program(context.Background(), "./testdata/agent", "")
224+
require.NoError(t, err)
225+
autogold.Expect(`{
226+
"name": "./testdata/agent",
227+
"entryToolId": "testdata/agent/agent.gpt:agent",
228+
"toolSet": {
229+
"testdata/agent/agent.gpt:agent": {
230+
"name": "agent",
231+
"modelName": "gpt-4o",
232+
"internalPrompt": null,
233+
"instructions": "an agent",
234+
"id": "testdata/agent/agent.gpt:agent",
235+
"localTools": {
236+
"agent": "testdata/agent/agent.gpt:agent"
237+
},
238+
"source": {
239+
"location": "testdata/agent/agent.gpt",
240+
"lineNo": 1
241+
},
242+
"workingDir": "testdata/agent"
243+
}
244+
}
245+
}`).Equal(t, toString(prg))
246+
247+
prg, err = Program(context.Background(), "./testdata/bothtoolagent", "")
248+
require.NoError(t, err)
249+
autogold.Expect(`{
250+
"name": "./testdata/bothtoolagent",
251+
"entryToolId": "testdata/bothtoolagent/agent.gpt:agent",
252+
"toolSet": {
253+
"testdata/bothtoolagent/agent.gpt:agent": {
254+
"name": "agent",
255+
"modelName": "gpt-4o",
256+
"internalPrompt": null,
257+
"instructions": "an agent",
258+
"id": "testdata/bothtoolagent/agent.gpt:agent",
259+
"localTools": {
260+
"agent": "testdata/bothtoolagent/agent.gpt:agent"
261+
},
262+
"source": {
263+
"location": "testdata/bothtoolagent/agent.gpt",
264+
"lineNo": 1
265+
},
266+
"workingDir": "testdata/bothtoolagent"
267+
}
268+
}
269+
}`).Equal(t, toString(prg))
270+
}

pkg/types/tool.go

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const (
2020
CommandPrefix = "#!"
2121
)
2222

23+
var (
24+
DefaultFiles = []string{"agent.gpt", "tool.gpt"}
25+
)
26+
2327
type ErrToolNotFound struct {
2428
ToolName string
2529
}

0 commit comments

Comments
 (0)