Skip to content

Commit c01de74

Browse files
committed
enhance: openapi: better confirmation prompts
Signed-off-by: Grant Linville <[email protected]>
1 parent 56cadbd commit c01de74

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

components/script/messages.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ const Message = ({
3939
noAvatar?: boolean;
4040
restart?: () => void;
4141
}) => {
42+
if (message === undefined) {
43+
return null;
44+
}
45+
4246
switch (message.type) {
4347
case MessageType.User:
4448
return (

components/script/useChatSocket.tsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const useChatSocket = (isEmpty?: boolean) => {
3131
'github.com/gptscript-ai/gateway-provider',
3232
'github.com/gptscript-ai/gateway-creds',
3333
]);
34+
// trustedOpenAPIRef contains a mapping of OpenAPI run tools to OpenAPI operation names that have been trusted.
35+
const trustedOpenAPIRef = useRef<Record<string, Record<string, boolean>>>({});
3436

3537
// update the refs as the state changes
3638
useEffect(() => {
@@ -190,11 +192,16 @@ const useChatSocket = (isEmpty?: boolean) => {
190192
}
191193

192194
let confirmMessage = `Proceed with calling the ${frame.tool.name} tool?`;
193-
if (frame.displayText) {
195+
if (
196+
!frame.tool.instructions?.startsWith('#!sys.openapi') &&
197+
frame.displayText
198+
) {
194199
const tool = frame.tool?.name?.replace('sys.', '');
195200
confirmMessage = frame.tool?.source?.repo
196201
? `Proceed with running the following (or allow all calls from the **${trimRepo(frame.tool?.source.repo!.Root)}** repo)?`
197202
: `Proceed with running the following (or allow all **${tool}** calls)?`;
203+
} else if (frame.tool.instructions?.startsWith('#!sys.openapi')) {
204+
confirmMessage = `Proceed with running the following API operation (or allow all runs of this operation)?`;
198205
}
199206

200207
const form = (
@@ -267,6 +274,28 @@ const useChatSocket = (isEmpty?: boolean) => {
267274
const alreadyAllowed = (frame: CallFrame): boolean => {
268275
if (!frame.tool) return false;
269276

277+
if (frame.tool.instructions?.startsWith('#!sys.openapi')) {
278+
// If the tool is an OpenAPI tool to list operations or get the schema for an operation, allow it.
279+
if (
280+
frame.tool.instructions?.split(' ').length > 2 &&
281+
(frame.tool.instructions?.split(' ')[1] == 'list' ||
282+
frame.tool.instructions?.split(' ')[1] == 'get-schema')
283+
) {
284+
return true;
285+
}
286+
287+
// If the tool is an OpenAPI tool to run an operation, check if it has been trusted.
288+
if (!frame.tool.name) {
289+
return false;
290+
}
291+
292+
const operation = JSON.parse(frame.input as string)['operation'];
293+
return (
294+
trustedOpenAPIRef.current[frame.tool.name] &&
295+
trustedOpenAPIRef.current[frame.tool.name][operation]
296+
);
297+
}
298+
270299
// Check if the tool has already been allowed
271300
if (frame.tool.name && trustedRef.current[frame.tool.name]) return true;
272301

@@ -293,6 +322,22 @@ const useChatSocket = (isEmpty?: boolean) => {
293322
const addTrustedFor = (frame: CallFrame) => {
294323
if (!frame.tool) return () => {};
295324

325+
if (
326+
frame.tool.instructions &&
327+
frame.tool.name &&
328+
frame.tool.instructions.startsWith('#!sys.openapi')
329+
) {
330+
return () => {
331+
const toolName = frame.tool?.name ?? ''; // Not possible for this to be null, but I have to satisfy the type checker.
332+
const operation = JSON.parse(frame.input as string)['operation'];
333+
334+
if (!trustedOpenAPIRef.current[toolName]) {
335+
trustedOpenAPIRef.current[toolName] = {};
336+
}
337+
trustedOpenAPIRef.current[toolName][operation] = true;
338+
};
339+
}
340+
296341
return frame.tool.source?.repo
297342
? () => {
298343
const repo = frame.tool!.source?.repo!.Root;

0 commit comments

Comments
 (0)