fix: respond to interrupted tool calls with a ToolResponseMessageContent (#1557)

This commit is contained in:
Kalvin C
2025-03-06 11:32:55 -08:00
committed by GitHub
parent e52e5474b7
commit 84b1df03b0

View File

@@ -15,7 +15,16 @@ import { askAi } from '../utils/askAI';
import Splash from './Splash';
import 'react-toastify/dist/ReactToastify.css';
import { useMessageStream } from '../hooks/useMessageStream';
import { Message, createUserMessage, getTextContent } from '../types/message';
import {
Message,
createUserMessage,
ToolCall,
ToolCallResult,
ToolRequestMessageContent,
ToolResponseMessageContent,
ToolConfirmationRequestMessageContent,
getTextContent,
} from '../types/message';
export interface ChatType {
id: number;
@@ -182,16 +191,70 @@ export default function ChatView({
// Handle stopping the message stream
const lastMessage = messages[messages.length - 1];
if (lastMessage && lastMessage.role === 'user') {
// isUserMessage also checks if the message is a toolConfirmationRequest
if (lastMessage && isUserMessage(lastMessage)) {
// Remove the last user message if it's the most recent one
if (messages.length > 1) {
setMessages(messages.slice(0, -1));
} else {
setMessages([]);
}
} else if (!isUserMessage(lastMessage)) {
// check if we have any tool requests or tool confirmation requests
const toolRequests: [string, ToolCallResult<ToolCall>][] = lastMessage.content
.filter(
(content): content is ToolRequestMessageContent | ToolConfirmationRequestMessageContent =>
content.type === 'toolRequest' || content.type === 'toolConfirmationRequest'
)
.map((content) => {
if (content.type === 'toolRequest') {
return [content.id, content.toolCall];
} else {
// extract tool call from confirmation
const toolCall: ToolCallResult<ToolCall> = {
status: 'success',
value: {
name: content.toolName,
arguments: content.arguments,
},
};
return [content.id, toolCall];
}
});
if (toolRequests.length !== 0) {
// This means we were interrupted during a tool request
// Create tool responses for all interrupted tool requests
let responseMessage: Message = {
role: 'user',
created: Date.now(),
content: [],
};
// get the last tool's name or just "tool"
const lastToolName = toolRequests.at(-1)?.[1].value?.name ?? 'tool';
const notification = 'Interrupted by the user to make a correction';
// generate a response saying it was interrupted for each tool request
for (const [reqId, _] of toolRequests) {
const toolResponse: ToolResponseMessageContent = {
type: 'toolResponse',
id: reqId,
toolResult: {
status: 'error',
error: notification,
},
};
responseMessage.content.push(toolResponse);
}
// Use an immutable update to add the response message to the messages array
setMessages([...messages, responseMessage]);
}
}
// Note: Tool call interruption handling would need to be implemented
// differently with the new message format
};
// Filter out standalone tool response messages for rendering