Skip to content

Commit 3b7fc9a

Browse files
committed
Fix tool call ordering
1 parent ab1205e commit 3b7fc9a

File tree

5 files changed

+361
-986
lines changed

5 files changed

+361
-986
lines changed

apps/sim/app/api/mothership/chat/route.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,26 @@ export async function POST(req: NextRequest) {
191191
if (result.toolCalls.length > 0) {
192192
assistantMessage.toolCalls = result.toolCalls
193193
}
194+
if (result.contentBlocks.length > 0) {
195+
assistantMessage.contentBlocks = result.contentBlocks.map((block) => {
196+
const stored: Record<string, unknown> = { type: block.type }
197+
if (block.content) stored.content = block.content
198+
if (block.type === 'tool_call' && block.toolCall) {
199+
stored.toolCall = {
200+
id: block.toolCall.id,
201+
name: block.toolCall.name,
202+
state:
203+
block.toolCall.result?.success !== undefined
204+
? block.toolCall.result.success
205+
? 'success'
206+
: 'error'
207+
: block.toolCall.status,
208+
result: block.toolCall.result,
209+
}
210+
}
211+
return stored
212+
})
213+
}
194214

195215
try {
196216
const [row] = await db

apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,21 @@ function mapStoredMessage(msg: TaskStoredMessage): ChatMessage {
9999
content: msg.content,
100100
}
101101

102-
if (Array.isArray(msg.toolCalls) && msg.toolCalls.length > 0) {
103-
const blocks: ContentBlock[] = msg.toolCalls.map(mapStoredToolCall)
104-
if (msg.content?.trim()) {
102+
const hasContentBlocks = Array.isArray(msg.contentBlocks) && msg.contentBlocks.length > 0
103+
const hasToolCalls = Array.isArray(msg.toolCalls) && msg.toolCalls.length > 0
104+
const contentBlocksHaveTools =
105+
hasContentBlocks && msg.contentBlocks!.some((b) => b.type === 'tool_call')
106+
107+
if (hasContentBlocks && (!hasToolCalls || contentBlocksHaveTools)) {
108+
const blocks = msg.contentBlocks!.map(mapStoredBlock)
109+
const hasText = blocks.some((b) => b.type === 'text' && b.content?.trim())
110+
if (!hasText && msg.content?.trim()) {
105111
blocks.push({ type: 'text', content: msg.content })
106112
}
107113
mapped.contentBlocks = blocks
108-
} else if (Array.isArray(msg.contentBlocks) && msg.contentBlocks.length > 0) {
109-
const blocks = msg.contentBlocks.map(mapStoredBlock)
110-
const hasText = blocks.some((b) => b.type === 'text' && b.content?.trim())
111-
if (!hasText && msg.content?.trim()) {
114+
} else if (hasToolCalls) {
115+
const blocks: ContentBlock[] = msg.toolCalls!.map(mapStoredToolCall)
116+
if (msg.content?.trim()) {
112117
blocks.push({ type: 'text', content: msg.content })
113118
}
114119
mapped.contentBlocks = blocks

apps/sim/lib/copilot/orchestrator/sse/handlers/handlers.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,14 @@ export const sseHandlers: Record<string, SSEHandler> = {
185185
event.toolName || (data?.toolName as string | undefined) || (data?.name as string | undefined)
186186
if (!toolCallId || !toolName) return
187187
if (!context.toolCalls.has(toolCallId)) {
188-
context.toolCalls.set(toolCallId, {
188+
const toolCall = {
189189
id: toolCallId,
190190
name: toolName,
191-
status: 'pending',
191+
status: 'pending' as const,
192192
startTime: Date.now(),
193-
})
193+
}
194+
context.toolCalls.set(toolCallId, toolCall)
195+
addContentBlock(context, { type: 'tool_call', toolCall })
194196
}
195197
},
196198
tool_call: async (event, context, execContext, options) => {
@@ -217,15 +219,20 @@ export const sseHandlers: Record<string, SSEHandler> = {
217219

218220
if (existing) {
219221
if (args && !existing.params) existing.params = args
222+
if (
223+
!context.contentBlocks.some((b) => b.type === 'tool_call' && b.toolCall?.id === toolCallId)
224+
) {
225+
addContentBlock(context, { type: 'tool_call', toolCall: existing })
226+
}
220227
} else {
221-
context.toolCalls.set(toolCallId, {
228+
const created = {
222229
id: toolCallId,
223230
name: toolName,
224-
status: 'pending',
231+
status: 'pending' as const,
225232
params: args,
226233
startTime: Date.now(),
227-
})
228-
const created = context.toolCalls.get(toolCallId)!
234+
}
235+
context.toolCalls.set(toolCallId, created)
229236
addContentBlock(context, { type: 'tool_call', toolCall: created })
230237
}
231238

0 commit comments

Comments
 (0)