@@ -13,6 +13,7 @@ import (
1313 "github.com/gptscript-ai/gptscript/pkg/env"
1414 "github.com/gptscript-ai/gptscript/pkg/types"
1515 "github.com/tidwall/gjson"
16+ "golang.org/x/exp/maps"
1617)
1718
1819var (
@@ -35,6 +36,45 @@ type SecurityInfo struct {
3536 In string `json:"in"` // header, query, or cookie, for type==apiKey
3637}
3738
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+
3878type OpenAPIInstructions struct {
3979 Server string `json:"server"`
4080 Path string `json:"path"`
@@ -83,8 +123,8 @@ func (e *Engine) runOpenAPI(tool types.Tool, input string) (*Return, error) {
83123 return nil , fmt .Errorf ("failed to create request: %w" , err )
84124 }
85125
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" {
88128 if len (instructions .SecurityInfos ) > 0 {
89129 if err := handleAuths (req , envMap , instructions .SecurityInfos ); err != nil {
90130 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
181221 for _ , infoSet := range infoSets {
182222 var missing []string // Keep track of any missing environment variables
183223 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 ())
191225
192- for _ , envName := range envNames {
226+ for _ , envName := range vars {
193227 if _ , ok := envMap [envName ]; ! ok {
194228 missing = append (missing , envName )
195229 }
@@ -203,28 +237,28 @@ func handleAuths(req *http.Request, envMap map[string]string, infoSets [][]Secur
203237 // We're using this info set, because no environment variables were missing.
204238 // Set up the request as needed.
205239 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 ()))
207241 switch info .Type {
208242 case "apiKey" :
209243 switch info .In {
210244 case "header" :
211- req .Header .Set (info .APIKeyName , envMap [envName ])
245+ req .Header .Set (info .APIKeyName , envMap [envNames [ 0 ] ])
212246 case "query" :
213247 v := url.Values {}
214- v .Add (info .APIKeyName , envMap [envName ])
248+ v .Add (info .APIKeyName , envMap [envNames [ 0 ] ])
215249 req .URL .RawQuery = v .Encode ()
216250 case "cookie" :
217251 req .AddCookie (& http.Cookie {
218252 Name : info .APIKeyName ,
219- Value : envMap [envName ],
253+ Value : envMap [envNames [ 0 ] ],
220254 })
221255 }
222256 case "http" :
223257 switch info .Scheme {
224258 case "bearer" :
225- req .Header .Set ("Authorization" , "Bearer " + envMap [envName ])
259+ req .Header .Set ("Authorization" , "Bearer " + envMap [envNames [ 0 ] ])
226260 case "basic" :
227- req .SetBasicAuth (envMap [envName + "_USERNAME" ] , envMap [envName + "_PASSWORD" ])
261+ req .SetBasicAuth (envMap [envNames [ 0 ]] , envMap [envNames [ 1 ] ])
228262 }
229263 }
230264 }
0 commit comments