@@ -11,6 +11,8 @@ import (
11
11
"sync"
12
12
"time"
13
13
14
+ cryptorand "crypto/rand"
15
+
14
16
"github.com/gptscript-ai/gptscript/pkg/system"
15
17
"github.com/gptscript-ai/gptscript/pkg/types"
16
18
)
@@ -19,6 +21,7 @@ var ports Ports
19
21
20
22
type Ports struct {
21
23
daemonPorts map [string ]int64
24
+ daemonTokens map [string ]string
22
25
daemonsRunning map [string ]func ()
23
26
daemonLock sync.Mutex
24
27
@@ -119,18 +122,46 @@ func getPath(instructions string) (string, string) {
119
122
return strings .TrimSpace (rest ), strings .TrimSpace (value )
120
123
}
121
124
122
- func (e * Engine ) startDaemon (tool types.Tool ) (string , error ) {
125
+ func getDaemonToken (toolID string ) (string , error ) {
126
+ token , ok := ports .daemonTokens [toolID ]
127
+ if ! ok {
128
+ // Generate a new token.
129
+ tokenBytes := make ([]byte , 50 )
130
+ count , err := cryptorand .Read (tokenBytes )
131
+ if err != nil {
132
+ return "" , fmt .Errorf ("failed to generate daemon token: %w" , err )
133
+ } else if count != len (tokenBytes ) {
134
+ return "" , fmt .Errorf ("failed to generate daemon token" )
135
+ }
136
+
137
+ token = fmt .Sprintf ("%x" , tokenBytes )
138
+
139
+ if ports .daemonTokens == nil {
140
+ ports .daemonTokens = map [string ]string {}
141
+ }
142
+ ports .daemonTokens [toolID ] = token
143
+ }
144
+
145
+ return token , nil
146
+ }
147
+
148
+ func (e * Engine ) startDaemon (tool types.Tool ) (string , string , error ) {
123
149
ports .daemonLock .Lock ()
124
150
defer ports .daemonLock .Unlock ()
125
151
126
152
instructions := strings .TrimPrefix (tool .Instructions , types .DaemonPrefix )
127
153
instructions , path := getPath (instructions )
128
154
tool .Instructions = types .CommandPrefix + instructions
129
155
156
+ token , err := getDaemonToken (tool .ID )
157
+ if err != nil {
158
+ return "" , "" , err
159
+ }
160
+
130
161
port , ok := ports .daemonPorts [tool .ID ]
131
162
url := fmt .Sprintf ("http://127.0.0.1:%d%s" , port , path )
132
163
if ok && ports .daemonsRunning [url ] != nil {
133
- return url , nil
164
+ return url , token , nil
134
165
}
135
166
136
167
if ports .daemonCtx == nil {
@@ -149,18 +180,19 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
149
180
cmd , stop , err := e .newCommand (ctx , []string {
150
181
fmt .Sprintf ("PORT=%d" , port ),
151
182
fmt .Sprintf ("GPTSCRIPT_PORT=%d" , port ),
183
+ fmt .Sprintf ("GPTSCRIPT_DAEMON_TOKEN=%s" , token ),
152
184
},
153
185
tool ,
154
186
"{}" ,
155
187
false ,
156
188
)
157
189
if err != nil {
158
- return url , err
190
+ return url , "" , err
159
191
}
160
192
161
193
r , w , err := os .Pipe ()
162
194
if err != nil {
163
- return "" , err
195
+ return "" , "" , err
164
196
}
165
197
166
198
// Loop back to gptscript to help with process supervision
@@ -178,7 +210,7 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
178
210
log .Infof ("launched [%s][%s] port [%d] %v" , tool .Name , tool .ID , port , cmd .Args )
179
211
if err := cmd .Start (); err != nil {
180
212
stop ()
181
- return url , err
213
+ return url , "" , err
182
214
}
183
215
184
216
if ports .daemonPorts == nil {
@@ -217,20 +249,20 @@ func (e *Engine) startDaemon(tool types.Tool) (string, error) {
217
249
_ , _ = io .ReadAll (resp .Body )
218
250
_ = resp .Body .Close ()
219
251
}()
220
- return url , nil
252
+ return url , token , nil
221
253
}
222
254
select {
223
255
case <- killedCtx .Done ():
224
- return url , fmt .Errorf ("daemon failed to start: %w" , context .Cause (killedCtx ))
256
+ return url , "" , fmt .Errorf ("daemon failed to start: %w" , context .Cause (killedCtx ))
225
257
case <- time .After (time .Second ):
226
258
}
227
259
}
228
260
229
- return url , fmt .Errorf ("timeout waiting for 200 response from GET %s" , url )
261
+ return url , "" , fmt .Errorf ("timeout waiting for 200 response from GET %s" , url )
230
262
}
231
263
232
264
func (e * Engine ) runDaemon (ctx Context , tool types.Tool , input string ) (cmdRet * Return , cmdErr error ) {
233
- url , err := e .startDaemon (tool )
265
+ url , _ , err := e .startDaemon (tool )
234
266
if err != nil {
235
267
return nil , err
236
268
}
0 commit comments