@@ -13,6 +13,7 @@ import (
13
13
"github.com/gptscript-ai/gptscript/pkg/env"
14
14
"github.com/gptscript-ai/gptscript/pkg/types"
15
15
"github.com/tidwall/gjson"
16
+ "golang.org/x/exp/maps"
16
17
)
17
18
18
19
var (
@@ -35,6 +36,45 @@ type SecurityInfo struct {
35
36
In string `json:"in"` // header, query, or cookie, for type==apiKey
36
37
}
37
38
39
+ func (i SecurityInfo ) GetCredentialToolStrings (hostname string ) []string {
40
+ vars := i .getCredentialNamesAndEnvVars (hostname )
41
+ var tools []string
42
+
43
+ for cred , v := range vars {
44
+ field := "value"
45
+ switch i .Type {
46
+ case "apiKey" :
47
+ field = i .APIKeyName
48
+ case "http" :
49
+ if i .Scheme == "bearer" {
50
+ field = "bearer token"
51
+ } else {
52
+ if strings .Contains (v , "PASSWORD" ) {
53
+ field = "password"
54
+ } else {
55
+ field = "username"
56
+ }
57
+ }
58
+ }
59
+
60
+ tools = append (tools , fmt .Sprintf ("github.com/gptscript-ai/credential as %s with %s as env and %q as message and %q as field" ,
61
+ cred , v , "Please provide a value for the " + v + " environment variable" , field ))
62
+ }
63
+ return tools
64
+ }
65
+
66
+ func (i SecurityInfo ) getCredentialNamesAndEnvVars (hostname string ) map [string ]string {
67
+ if i .Type == "http" && i .Scheme == "basic" {
68
+ return map [string ]string {
69
+ hostname + i .Name + "Username" : "GPTSCRIPT_" + env .ToEnvLike (hostname ) + "_" + env .ToEnvLike (i .Name ) + "_USERNAME" ,
70
+ hostname + i .Name + "Password" : "GPTSCRIPT_" + env .ToEnvLike (hostname ) + "_" + env .ToEnvLike (i .Name ) + "_PASSWORD" ,
71
+ }
72
+ }
73
+ return map [string ]string {
74
+ hostname + i .Name : "GPTSCRIPT_" + env .ToEnvLike (hostname ) + "_" + env .ToEnvLike (i .Name ),
75
+ }
76
+ }
77
+
38
78
type OpenAPIInstructions struct {
39
79
Server string `json:"server"`
40
80
Path string `json:"path"`
@@ -83,8 +123,8 @@ func (e *Engine) runOpenAPI(tool types.Tool, input string) (*Return, error) {
83
123
return nil , fmt .Errorf ("failed to create request: %w" , err )
84
124
}
85
125
86
- // Check for authentication (only if using HTTPS)
87
- if u .Scheme == "https" {
126
+ // Check for authentication (only if using HTTPS or localhost )
127
+ if u .Scheme == "https" || u . Hostname () == "localhost" || u . Hostname () == "127.0.0.1" {
88
128
if len (instructions .SecurityInfos ) > 0 {
89
129
if err := handleAuths (req , envMap , instructions .SecurityInfos ); err != nil {
90
130
return nil , fmt .Errorf ("error setting up authentication: %w" , err )
@@ -181,15 +221,9 @@ func handleAuths(req *http.Request, envMap map[string]string, infoSets [][]Secur
181
221
for _ , infoSet := range infoSets {
182
222
var missing []string // Keep track of any missing environment variables
183
223
for _ , info := range infoSet {
184
- envNames := []string {"GPTSCRIPT_" + env .ToEnvLike (req .URL .Hostname ()) + "_" + env .ToEnvLike (info .Name )}
185
- if info .Type == "http" && info .Scheme == "basic" {
186
- envNames = []string {
187
- "GPTSCRIPT_" + env .ToEnvLike (req .URL .Hostname ()) + "_" + env .ToEnvLike (info .Name ) + "_USERNAME" ,
188
- "GPTSCRIPT_" + env .ToEnvLike (req .URL .Hostname ()) + "_" + env .ToEnvLike (info .Name ) + "_PASSWORD" ,
189
- }
190
- }
224
+ vars := info .getCredentialNamesAndEnvVars (req .URL .Hostname ())
191
225
192
- for _ , envName := range envNames {
226
+ for _ , envName := range vars {
193
227
if _ , ok := envMap [envName ]; ! ok {
194
228
missing = append (missing , envName )
195
229
}
@@ -203,28 +237,28 @@ func handleAuths(req *http.Request, envMap map[string]string, infoSets [][]Secur
203
237
// We're using this info set, because no environment variables were missing.
204
238
// Set up the request as needed.
205
239
for _ , info := range infoSet {
206
- envName := "GPTSCRIPT_" + env . ToEnvLike ( req .URL .Hostname ()) + "_" + env . ToEnvLike ( info . Name )
240
+ envNames := maps . Values ( info . getCredentialNamesAndEnvVars ( req .URL .Hostname ()))
207
241
switch info .Type {
208
242
case "apiKey" :
209
243
switch info .In {
210
244
case "header" :
211
- req .Header .Set (info .APIKeyName , envMap [envName ])
245
+ req .Header .Set (info .APIKeyName , envMap [envNames [ 0 ] ])
212
246
case "query" :
213
247
v := url.Values {}
214
- v .Add (info .APIKeyName , envMap [envName ])
248
+ v .Add (info .APIKeyName , envMap [envNames [ 0 ] ])
215
249
req .URL .RawQuery = v .Encode ()
216
250
case "cookie" :
217
251
req .AddCookie (& http.Cookie {
218
252
Name : info .APIKeyName ,
219
- Value : envMap [envName ],
253
+ Value : envMap [envNames [ 0 ] ],
220
254
})
221
255
}
222
256
case "http" :
223
257
switch info .Scheme {
224
258
case "bearer" :
225
- req .Header .Set ("Authorization" , "Bearer " + envMap [envName ])
259
+ req .Header .Set ("Authorization" , "Bearer " + envMap [envNames [ 0 ] ])
226
260
case "basic" :
227
- req .SetBasicAuth (envMap [envName + "_USERNAME" ] , envMap [envName + "_PASSWORD" ])
261
+ req .SetBasicAuth (envMap [envNames [ 0 ]] , envMap [envNames [ 1 ] ])
228
262
}
229
263
}
230
264
}
0 commit comments