mirror of
https://github.com/aljazceru/goose.git
synced 2026-01-02 22:14:26 +01:00
fix: respond to interrupted tool calls with a ToolResponseMessageContent (#1557)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user