Skip to content

Commit 474eab5

Browse files
committed
fix: auto allow/deny tool run requests on dynamic tool add/remove
When tools are added or removed, the socket server runs the script to regenerate tool definitions. Now that the gateway-provider has been incorporated as the default model provider, this logic gets stuck waiting for user confirmation, and leads to the user getting stuck on a loading screen. This same logic also means that if the LLM attempts to call any other tool -- which is prone to doing without being asked to -- we run into the same problem (e.g. the second tool add hangs forever bug). To fix this, add a handler to the tool run that auto-approves providers and auto-denies requests to run any other tool. Signed-off-by: Nick Hale <[email protected]>
1 parent e7bb77a commit 474eab5

File tree

1 file changed

+52
-5
lines changed

1 file changed

+52
-5
lines changed

server/app.mjs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ const mount = async (location, tool, args, scriptWorkspace, socket, threadID, gp
178178
await runningScript.close();
179179
runningScript = null;
180180
}
181-
181+
182182
// find the root tool and then add the new tool
183183
for (let block of script) {
184184
if (block.type === "tool") {
@@ -203,10 +203,33 @@ const mount = async (location, tool, args, scriptWorkspace, socket, threadID, gp
203203
socket.emit("addingTool");
204204

205205
const currentState = JSON.parse(state.chatState);
206-
207-
opts.chatState = undefined; // clear the chat state so we can get the new tool mappings
206+
207+
opts.chatState = undefined; // Clear the chat state so that we can get the new tool mappings
208+
opts.input = 'do nothing' // Ensure the LLM doesn't try to call tools without input
208209
const newStateRun = await gptscript.evaluate(script, opts)
210+
211+
newStateRun.on(RunEventType.CallConfirm, (frame) => {
212+
let response
213+
if (!frame.error && frame.toolCategory === "provider") {
214+
// Auto-confirm gateway provider
215+
response = {
216+
id: frame.id,
217+
accept: true,
218+
};
219+
} else {
220+
// Deny all other tool run requests
221+
response = {
222+
id: frame.id,
223+
accept: false,
224+
message: 'do nothing'
225+
};
226+
}
227+
228+
gptscript.confirm(response);
229+
});
230+
209231
await newStateRun.text();
232+
await newStateRun.close()
210233

211234
const newState = JSON.parse(newStateRun.currentChatState());
212235
currentState.continuation.state.completion.tools = newState.continuation.state.completion.tools;
@@ -256,10 +279,33 @@ const mount = async (location, tool, args, scriptWorkspace, socket, threadID, gp
256279
socket.emit("removingTool");
257280

258281
const currentState = JSON.parse(state.chatState);
259-
260-
opts.chatState = undefined; // clear the chat state so we can get the new tool mappings
282+
283+
opts.chatState = undefined; // Clear the chat state so that we can get the new tool mappings
284+
opts.input = 'do nothing' // Ensure the LLM doesn't try to call tools without input
261285
const newStateRun = await gptscript.evaluate(script, opts)
286+
287+
newStateRun.on(RunEventType.CallConfirm, (frame) => {
288+
let response
289+
if (!frame.error && frame.toolCategory === "provider") {
290+
// Auto-confirm gateway provider
291+
response = {
292+
id: frame.id,
293+
accept: true,
294+
};
295+
} else {
296+
// Deny all other tool run requests
297+
response = {
298+
id: frame.id,
299+
accept: false,
300+
message: 'do nothing'
301+
};
302+
}
303+
304+
gptscript.confirm(response);
305+
});
306+
262307
await newStateRun.text();
308+
await newStateRun.close();
263309

264310
const newState = JSON.parse(newStateRun.currentChatState());
265311
currentState.continuation.state.completion.tools = newState.continuation.state.completion.tools;
@@ -353,6 +399,7 @@ const initGPTScriptConfig = async (gptscript) => {
353399
instructions: '#!sys.echo noop'
354400
})
355401
await run.text()
402+
await run.close()
356403

357404
const configPath = gptscriptConfigPath();
358405

0 commit comments

Comments
 (0)