Updated ChatMessage component to display calledTools
This commit is contained in:
parent
62d34066c9
commit
b222f1fb72
|
|
@ -1676,7 +1676,12 @@ class Agent_Agentflow implements INode {
|
||||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||||
|
|
||||||
if (response.tool_calls) {
|
if (response.tool_calls) {
|
||||||
sseStreamer.streamCalledToolsEvent(chatId, response.tool_calls)
|
const formattedToolCalls = response.tool_calls.map((toolCall: any) => ({
|
||||||
|
tool: toolCall.name || 'tool',
|
||||||
|
toolInput: toolCall.args,
|
||||||
|
toolOutput: ''
|
||||||
|
}))
|
||||||
|
sseStreamer.streamCalledToolsEvent(chatId, flatten(formattedToolCalls))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.usage_metadata) {
|
if (response.usage_metadata) {
|
||||||
|
|
@ -1736,7 +1741,12 @@ class Agent_Agentflow implements INode {
|
||||||
|
|
||||||
// Stream tool calls if available
|
// Stream tool calls if available
|
||||||
if (sseStreamer) {
|
if (sseStreamer) {
|
||||||
sseStreamer.streamCalledToolsEvent(chatId, JSON.stringify(response.tool_calls))
|
const formattedToolCalls = response.tool_calls.map((toolCall: any) => ({
|
||||||
|
tool: toolCall.name || 'tool',
|
||||||
|
toolInput: toolCall.args,
|
||||||
|
toolOutput: ''
|
||||||
|
}))
|
||||||
|
sseStreamer.streamCalledToolsEvent(chatId, flatten(formattedToolCalls))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove tool calls with no id
|
// Remove tool calls with no id
|
||||||
|
|
@ -2045,7 +2055,12 @@ class Agent_Agentflow implements INode {
|
||||||
|
|
||||||
// Stream tool calls if available
|
// Stream tool calls if available
|
||||||
if (sseStreamer) {
|
if (sseStreamer) {
|
||||||
sseStreamer.streamCalledToolsEvent(chatId, JSON.stringify(response.tool_calls))
|
const formattedToolCalls = response.tool_calls.map((toolCall: any) => ({
|
||||||
|
tool: toolCall.name || 'tool',
|
||||||
|
toolInput: toolCall.args,
|
||||||
|
toolOutput: ''
|
||||||
|
}))
|
||||||
|
sseStreamer.streamCalledToolsEvent(chatId, flatten(formattedToolCalls))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove tool calls with no id
|
// Remove tool calls with no id
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {
|
||||||
updateFlowState
|
updateFlowState
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { processTemplateVariables } from '../../../src/utils'
|
import { processTemplateVariables } from '../../../src/utils'
|
||||||
|
import { flatten } from 'lodash'
|
||||||
|
|
||||||
class LLM_Agentflow implements INode {
|
class LLM_Agentflow implements INode {
|
||||||
label: string
|
label: string
|
||||||
|
|
@ -892,7 +893,12 @@ class LLM_Agentflow implements INode {
|
||||||
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
||||||
|
|
||||||
if (response.tool_calls) {
|
if (response.tool_calls) {
|
||||||
sseStreamer.streamCalledToolsEvent(chatId, response.tool_calls)
|
const formattedToolCalls = response.tool_calls.map((toolCall: any) => ({
|
||||||
|
tool: toolCall.name || 'tool',
|
||||||
|
toolInput: toolCall.args,
|
||||||
|
toolOutput: ''
|
||||||
|
}))
|
||||||
|
sseStreamer.streamCalledToolsEvent(chatId, flatten(formattedToolCalls))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.usage_metadata) {
|
if (response.usage_metadata) {
|
||||||
|
|
|
||||||
|
|
@ -687,11 +687,57 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
setMessages((prevMessages) => {
|
setMessages((prevMessages) => {
|
||||||
let allMessages = [...cloneDeep(prevMessages)]
|
let allMessages = [...cloneDeep(prevMessages)]
|
||||||
if (allMessages[allMessages.length - 1].type === 'userMessage') return allMessages
|
if (allMessages[allMessages.length - 1].type === 'userMessage') return allMessages
|
||||||
|
|
||||||
|
// When usedTools are received, check if there are matching calledTools to replace
|
||||||
|
const lastMessage = allMessages[allMessages.length - 1]
|
||||||
|
if (lastMessage.calledTools && lastMessage.calledTools.length > 0) {
|
||||||
|
// Replace calledTools with usedTools for matching tool names
|
||||||
|
const updatedCalledTools = lastMessage.calledTools.map((calledTool) => {
|
||||||
|
const matchingUsedTool = usedTools.find((usedTool) => usedTool.tool === calledTool.tool)
|
||||||
|
return matchingUsedTool || calledTool
|
||||||
|
})
|
||||||
|
|
||||||
|
// Remove calledTools that have been replaced by usedTools
|
||||||
|
const remainingCalledTools = updatedCalledTools.filter(
|
||||||
|
(calledTool) => !usedTools.some((usedTool) => usedTool.tool === calledTool.tool)
|
||||||
|
)
|
||||||
|
|
||||||
|
allMessages[allMessages.length - 1].calledTools = remainingCalledTools.length > 0 ? remainingCalledTools : undefined
|
||||||
|
}
|
||||||
|
|
||||||
allMessages[allMessages.length - 1].usedTools = usedTools
|
allMessages[allMessages.length - 1].usedTools = usedTools
|
||||||
return allMessages
|
return allMessages
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateLastMessageCalledTools = (calledTools) => {
|
||||||
|
setMessages((prevMessages) => {
|
||||||
|
let allMessages = [...cloneDeep(prevMessages)]
|
||||||
|
if (allMessages[allMessages.length - 1].type === 'userMessage') return allMessages
|
||||||
|
allMessages[allMessages.length - 1].calledTools = calledTools
|
||||||
|
return allMessages
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanupCalledTools = () => {
|
||||||
|
setMessages((prevMessages) => {
|
||||||
|
let allMessages = [...cloneDeep(prevMessages)]
|
||||||
|
if (allMessages[allMessages.length - 1].type === 'userMessage') return allMessages
|
||||||
|
|
||||||
|
// Remove any remaining calledTools when the stream ends
|
||||||
|
const lastMessage = allMessages[allMessages.length - 1]
|
||||||
|
if (lastMessage && lastMessage.calledTools && lastMessage.calledTools.length > 0) {
|
||||||
|
// Only remove if there are still calledTools and no matching usedTools
|
||||||
|
const hasUsedTools = lastMessage.usedTools && lastMessage.usedTools.length > 0
|
||||||
|
if (!hasUsedTools) {
|
||||||
|
allMessages[allMessages.length - 1].calledTools = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allMessages
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const updateLastMessageFileAnnotations = (fileAnnotations) => {
|
const updateLastMessageFileAnnotations = (fileAnnotations) => {
|
||||||
setMessages((prevMessages) => {
|
setMessages((prevMessages) => {
|
||||||
let allMessages = [...cloneDeep(prevMessages)]
|
let allMessages = [...cloneDeep(prevMessages)]
|
||||||
|
|
@ -710,6 +756,7 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
if (lastAgentReasoning && lastAgentReasoning.length > 0) {
|
if (lastAgentReasoning && lastAgentReasoning.length > 0) {
|
||||||
allMessages[allMessages.length - 1].agentReasoning = lastAgentReasoning.filter((reasoning) => !reasoning.nextAgent)
|
allMessages[allMessages.length - 1].agentReasoning = lastAgentReasoning.filter((reasoning) => !reasoning.nextAgent)
|
||||||
}
|
}
|
||||||
|
allMessages[allMessages.length - 1].calledTools = undefined
|
||||||
return allMessages
|
return allMessages
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -1038,6 +1085,9 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
case 'usedTools':
|
case 'usedTools':
|
||||||
updateLastMessageUsedTools(payload.data)
|
updateLastMessageUsedTools(payload.data)
|
||||||
break
|
break
|
||||||
|
case 'calledTools':
|
||||||
|
updateLastMessageCalledTools(payload.data)
|
||||||
|
break
|
||||||
case 'fileAnnotations':
|
case 'fileAnnotations':
|
||||||
updateLastMessageFileAnnotations(payload.data)
|
updateLastMessageFileAnnotations(payload.data)
|
||||||
break
|
break
|
||||||
|
|
@ -1085,12 +1135,14 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
handleTTSAbort(payload.data)
|
handleTTSAbort(payload.data)
|
||||||
break
|
break
|
||||||
case 'end':
|
case 'end':
|
||||||
|
cleanupCalledTools()
|
||||||
setLocalStorageChatflow(chatflowid, chatId)
|
setLocalStorageChatflow(chatflowid, chatId)
|
||||||
closeResponse()
|
closeResponse()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async onclose() {
|
async onclose() {
|
||||||
|
cleanupCalledTools()
|
||||||
closeResponse()
|
closeResponse()
|
||||||
},
|
},
|
||||||
async onerror(err) {
|
async onerror(err) {
|
||||||
|
|
@ -1102,6 +1154,7 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeResponse = () => {
|
const closeResponse = () => {
|
||||||
|
cleanupCalledTools()
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
setUserInput('')
|
setUserInput('')
|
||||||
setUploadedFiles([])
|
setUploadedFiles([])
|
||||||
|
|
@ -1202,6 +1255,7 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
}
|
}
|
||||||
if (message.sourceDocuments) obj.sourceDocuments = message.sourceDocuments
|
if (message.sourceDocuments) obj.sourceDocuments = message.sourceDocuments
|
||||||
if (message.usedTools) obj.usedTools = message.usedTools
|
if (message.usedTools) obj.usedTools = message.usedTools
|
||||||
|
if (message.calledTools) obj.calledTools = message.calledTools
|
||||||
if (message.fileAnnotations) obj.fileAnnotations = message.fileAnnotations
|
if (message.fileAnnotations) obj.fileAnnotations = message.fileAnnotations
|
||||||
if (message.agentReasoning) obj.agentReasoning = message.agentReasoning
|
if (message.agentReasoning) obj.agentReasoning = message.agentReasoning
|
||||||
if (message.action) obj.action = message.action
|
if (message.action) obj.action = message.action
|
||||||
|
|
@ -2423,6 +2477,42 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
sessionId={chatId}
|
sessionId={chatId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{message.calledTools && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'block',
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: '100%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{message.calledTools.map((tool, index) => {
|
||||||
|
return tool ? (
|
||||||
|
<Chip
|
||||||
|
size='small'
|
||||||
|
key={`called-${index}`}
|
||||||
|
label={tool.tool}
|
||||||
|
component='a'
|
||||||
|
sx={{
|
||||||
|
mr: 1,
|
||||||
|
mt: 1,
|
||||||
|
borderColor: 'primary.main',
|
||||||
|
color: 'primary.main',
|
||||||
|
backgroundColor: 'rgba(25, 118, 210, 0.1)',
|
||||||
|
opacity: 0.9,
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'rgba(25, 118, 210, 0.2)',
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
variant='outlined'
|
||||||
|
clickable
|
||||||
|
icon={<CircularProgress size={15} color='primary' />}
|
||||||
|
onClick={() => onSourceDialogClick(tool, 'Called Tools')}
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{message.usedTools && (
|
{message.usedTools && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
@ -2435,7 +2525,7 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP
|
||||||
return tool ? (
|
return tool ? (
|
||||||
<Chip
|
<Chip
|
||||||
size='small'
|
size='small'
|
||||||
key={index}
|
key={`used-${index}`}
|
||||||
label={tool.tool}
|
label={tool.tool}
|
||||||
component='a'
|
component='a'
|
||||||
sx={{
|
sx={{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue