diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx
index e91a710b590..757d57e9da3 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/message-content.tsx
@@ -413,7 +413,9 @@ export function MessageContent({
return (
- Stopped
+
+ Stopped by user
+
)
}
diff --git a/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts b/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
index 90e76f6be6f..b2667577992 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
+++ b/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
@@ -85,8 +85,6 @@ const STATE_TO_STATUS: Record = {
const DEPLOY_TOOL_NAMES = new Set(['deploy_api', 'deploy_chat', 'deploy_mcp', 'redeploy'])
const RECONNECT_TAIL_ERROR =
'Live reconnect failed before the stream finished. The latest response may be incomplete.'
-const CONTINUE_OPTIONS_CONTENT =
- '{"continue":{"title":"Continue","description":"Pick up where we left off"}}'
function mapStoredBlock(block: TaskStoredContentBlock): ContentBlock {
const mapped: ContentBlock = {
@@ -1215,14 +1213,8 @@ export function useChat(
if (storedBlocks.length > 0) {
storedBlocks.push({ type: 'stopped' })
- storedBlocks.push({ type: 'text', content: CONTINUE_OPTIONS_CONTENT })
}
- const persistedContent =
- content && !content.includes('')
- ? `${content}\n\n${CONTINUE_OPTIONS_CONTENT}`
- : content
-
try {
const res = await fetch(stopPathRef.current, {
method: 'POST',
@@ -1230,7 +1222,7 @@ export function useChat(
body: JSON.stringify({
chatId,
streamId,
- content: persistedContent,
+ content,
...(storedBlocks.length > 0 && { contentBlocks: storedBlocks }),
}),
})
@@ -1256,50 +1248,6 @@ export function useChat(
const messagesRef = useRef(messages)
messagesRef.current = messages
- const resolveInterruptedToolCalls = useCallback(() => {
- setMessages((prev) => {
- const hasAnyExecuting = prev.some((m) =>
- m.contentBlocks?.some((b) => b.toolCall?.status === 'executing')
- )
- if (!hasAnyExecuting) return prev
-
- let lastAssistantIdx = -1
- for (let i = prev.length - 1; i >= 0; i--) {
- if (prev[i].role === 'assistant') {
- lastAssistantIdx = i
- break
- }
- }
- return prev.map((msg, idx) => {
- const hasExecuting = msg.contentBlocks?.some((b) => b.toolCall?.status === 'executing')
- const isLastAssistant = idx === lastAssistantIdx
- if (!hasExecuting && !isLastAssistant) return msg
-
- const blocks: ContentBlock[] = (msg.contentBlocks ?? []).map((block) => {
- if (block.toolCall?.status !== 'executing') return block
- return {
- ...block,
- toolCall: {
- ...block.toolCall,
- status: 'cancelled' as const,
- displayTitle: 'Stopped',
- },
- }
- })
- if (isLastAssistant && !blocks.some((b) => b.type === 'stopped')) {
- blocks.push({ type: 'stopped' as const })
- }
- if (
- isLastAssistant &&
- !blocks.some((b) => b.type === 'text' && b.content?.includes(''))
- ) {
- blocks.push({ type: 'text', content: CONTINUE_OPTIONS_CONTENT })
- }
- return { ...msg, contentBlocks: blocks.length > 0 ? blocks : msg.contentBlocks }
- })
- })
- }, [])
-
const finalize = useCallback(
(options?: { error?: boolean }) => {
sendingRef.current = false
@@ -1314,8 +1262,6 @@ export function useChat(
}
}
- resolveInterruptedToolCalls()
-
if (options?.error) {
setMessageQueue([])
return
@@ -1331,7 +1277,7 @@ export function useChat(
})
}
},
- [invalidateChatQueries, resolveInterruptedToolCalls]
+ [invalidateChatQueries]
)
finalizeRef.current = finalize
@@ -1489,7 +1435,24 @@ export function useChat(
sendingRef.current = false
setIsSending(false)
- resolveInterruptedToolCalls()
+ setMessages((prev) =>
+ prev.map((msg) => {
+ if (!msg.contentBlocks?.some((b) => b.toolCall?.status === 'executing')) return msg
+ const updated = msg.contentBlocks!.map((block) => {
+ if (block.toolCall?.status !== 'executing') return block
+ return {
+ ...block,
+ toolCall: {
+ ...block.toolCall,
+ status: 'cancelled' as const,
+ displayTitle: 'Stopped by user',
+ },
+ }
+ })
+ updated.push({ type: 'stopped' as const })
+ return { ...msg, contentBlocks: updated }
+ })
+ )
if (sid) {
fetch('/api/copilot/chat/abort', {
@@ -1555,7 +1518,7 @@ export function useChat(
reportManualRunToolStop(workflowId, toolCallId).catch(() => {})
}
- }, [invalidateChatQueries, persistPartialResponse, executionStream, resolveInterruptedToolCalls])
+ }, [invalidateChatQueries, persistPartialResponse, executionStream])
const removeFromQueue = useCallback((id: string) => {
messageQueueRef.current = messageQueueRef.current.filter((m) => m.id !== id)
diff --git a/bun.lock b/bun.lock
index 742b7d9079e..ed31b1d954d 100644
--- a/bun.lock
+++ b/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "simstudio",