@@ -11,8 +11,6 @@ import (
11
11
"fmt"
12
12
"io"
13
13
"io/fs"
14
- "net/http"
15
- url2 "net/url"
16
14
"os"
17
15
"path/filepath"
18
16
"regexp"
@@ -22,20 +20,37 @@ import (
22
20
"github.com/gptscript-ai/gptscript/pkg/builtin"
23
21
"github.com/gptscript-ai/gptscript/pkg/engine"
24
22
"github.com/gptscript-ai/gptscript/pkg/parser"
23
+ "github.com/gptscript-ai/gptscript/pkg/system"
25
24
"github.com/gptscript-ai/gptscript/pkg/types"
26
25
)
27
26
28
- const (
29
- GithubPrefix = "github.com/"
30
- githubRawURL = "https://raw.githubusercontent.com/"
31
- )
32
-
33
27
type source struct {
28
+ // Content The content of the source
34
29
Content io.ReadCloser
35
- Remote bool
36
- Path string
37
- Name string
38
- File string
30
+ // Remote indicates that this file was loaded from a remote source (not local disk)
31
+ Remote bool
32
+ // Path is the path of this source used to find any relative references to this source
33
+ Path string
34
+ // Name is the filename of this source, it does not include the path in it
35
+ Name string
36
+ // Location is a string representation representing the source. It's not assume to
37
+ // be a valid URI or URL, used primarily for display.
38
+ Location string
39
+ // Repo The VCS repo where this tool was found, used to clone and provide the local tool code content
40
+ Repo * Repo
41
+ }
42
+
43
+ type Repo struct {
44
+ // VCS The VCS type, such as "github"
45
+ VCS string
46
+ // The URL where the VCS repo can be found
47
+ Root string
48
+ // The path in the repo of this source. This should refer to a directory and not the actual file
49
+ Path string
50
+ // The filename of the source in the repo, relative to Path
51
+ Name string
52
+ // The revision of this source
53
+ Revision string
39
54
}
40
55
41
56
func (s * source ) String () string {
@@ -67,74 +82,11 @@ func loadLocal(base *source, name string) (*source, bool, error) {
67
82
log .Debugf ("opened %s" , path )
68
83
69
84
return & source {
70
- Content : content ,
71
- Remote : false ,
72
- Path : filepath .Dir (path ),
73
- Name : filepath .Base (path ),
74
- File : path ,
75
- }, true , nil
76
- }
77
-
78
- func githubURL (urlName string ) (string , bool ) {
79
- if ! strings .HasPrefix (urlName , GithubPrefix ) {
80
- return "" , false
81
- }
82
-
83
- url , version , _ := strings .Cut (urlName , "@" )
84
- if version == "" {
85
- version = "HEAD"
86
- }
87
-
88
- parts := strings .Split (url , "/" )
89
- // Must be at least 4 parts github.com/ACCOUNT/REPO/FILE
90
- if len (parts ) < 4 {
91
- return "" , false
92
- }
93
-
94
- url = githubRawURL + parts [1 ] + "/" + parts [2 ] + "/" + version + "/" + strings .Join (parts [3 :], "/" )
95
- return url , true
96
- }
97
-
98
- func loadURL (ctx context.Context , base * source , name string ) (* source , bool , error ) {
99
- url := name
100
- if base .Path != "" {
101
- url = base .Path + "/" + name
102
- }
103
- if githubURL , ok := githubURL (url ); ok {
104
- url = githubURL
105
- }
106
- if ! strings .HasPrefix (url , "http://" ) && ! strings .HasPrefix (url , "https://" ) {
107
- return nil , false , nil
108
- }
109
-
110
- req , err := http .NewRequestWithContext (ctx , http .MethodGet , url , nil )
111
- if err != nil {
112
- return nil , false , err
113
- }
114
-
115
- resp , err := http .DefaultClient .Do (req )
116
- if err != nil {
117
- return nil , false , err
118
- } else if resp .StatusCode != http .StatusOK {
119
- return nil , false , fmt .Errorf ("error loading %s: %s" , url , resp .Status )
120
- }
121
-
122
- log .Debugf ("opened %s" , url )
123
-
124
- parsed , err := url2 .Parse (url )
125
- if err != nil {
126
- return nil , false , err
127
- }
128
-
129
- pathURL := * parsed
130
- pathURL .Path = filepath .Dir (parsed .Path )
131
-
132
- return & source {
133
- Content : resp .Body ,
134
- Remote : true ,
135
- Path : pathURL .String (),
136
- Name : filepath .Base (parsed .Path ),
137
- File : url ,
85
+ Content : content ,
86
+ Remote : false ,
87
+ Path : filepath .Dir (path ),
88
+ Name : filepath .Base (path ),
89
+ Location : path ,
138
90
}, true , nil
139
91
}
140
92
@@ -201,7 +153,7 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN
201
153
202
154
for i , tool := range tools {
203
155
tool .WorkingDir = base .Path
204
- tool .Source .File = base .File
156
+ tool .Source .Location = base .Location
205
157
206
158
// Probably a better way to come up with an ID
207
159
tool .ID = tool .Source .String ()
@@ -211,16 +163,16 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN
211
163
}
212
164
213
165
if i != 0 && tool .Parameters .Name == "" {
214
- return types.Tool {}, parser .NewErrLine (tool .Source .File , tool .Source .LineNo , fmt .Errorf ("only the first tool in a file can have no name" ))
166
+ return types.Tool {}, parser .NewErrLine (tool .Source .Location , tool .Source .LineNo , fmt .Errorf ("only the first tool in a file can have no name" ))
215
167
}
216
168
217
169
if targetToolName != "" && tool .Parameters .Name == targetToolName {
218
170
mainTool = tool
219
171
}
220
172
221
173
if existing , ok := localTools [tool .Parameters .Name ]; ok {
222
- return types.Tool {}, parser .NewErrLine (tool .Source .File , tool .Source .LineNo ,
223
- fmt .Errorf ("duplicate tool name [%s] in %s found at lines %d and %d" , tool .Parameters .Name , tool .Source .File ,
174
+ return types.Tool {}, parser .NewErrLine (tool .Source .Location , tool .Source .LineNo ,
175
+ fmt .Errorf ("duplicate tool name [%s] in %s found at lines %d and %d" , tool .Parameters .Name , tool .Source .Location ,
224
176
tool .Source .LineNo , existing .Source .LineNo ))
225
177
}
226
178
@@ -238,7 +190,7 @@ var (
238
190
func ToolNormalizer (tool string ) string {
239
191
parts := strings .Split (tool , "/" )
240
192
tool = parts [len (parts )- 1 ]
241
- if strings .HasSuffix (tool , ".gpt" ) {
193
+ if strings .HasSuffix (tool , system . Suffix ) {
242
194
tool = strings .TrimSuffix (tool , filepath .Ext (tool ))
243
195
}
244
196
@@ -349,8 +301,8 @@ func ProgramFromSource(ctx context.Context, content, subToolName string) (types.
349
301
ToolSet : types.ToolSet {},
350
302
}
351
303
tool , err := readTool (ctx , & prg , & source {
352
- Content : io .NopCloser (strings .NewReader (content )),
353
- File : "inline" ,
304
+ Content : io .NopCloser (strings .NewReader (content )),
305
+ Location : "inline" ,
354
306
}, subToolName )
355
307
if err != nil {
356
308
return types.Program {}, err
0 commit comments