Skip to content

Commit 221a473

Browse files
authored
fix(copilot): fix state message sent on move to background (#871)
* Initial fix * Add execution start time to message * Lint
1 parent 48b32a3 commit 221a473

File tree

6 files changed

+60
-13
lines changed

6 files changed

+60
-13
lines changed

apps/sim/app/api/copilot/confirm/route.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ async function updateToolCallStatus(
7878
message: message || null,
7979
timestamp: new Date().toISOString(),
8080
}
81+
82+
// Log what we're about to update in Redis
83+
logger.info('About to update Redis with tool call data', {
84+
toolCallId,
85+
key,
86+
toolCallData,
87+
serializedData: JSON.stringify(toolCallData),
88+
providedStatus: status,
89+
providedMessage: message,
90+
messageIsUndefined: message === undefined,
91+
messageIsNull: message === null,
92+
})
93+
8194
await redis.set(key, JSON.stringify(toolCallData), 'EX', 86400) // Keep 24 hour expiry
8295

8396
logger.info('Tool call status updated in Redis', {

apps/sim/app/api/copilot/methods/route.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ async function pollRedisForTool(
9898
}
9999

100100
if (status !== 'pending') {
101+
// Log the message found in redis prominently - always log, even if message is null/undefined
102+
logger.info('Redis poller found non-pending status', {
103+
toolCallId,
104+
foundMessage: message,
105+
messageType: typeof message,
106+
messageIsNull: message === null,
107+
messageIsUndefined: message === undefined,
108+
status,
109+
duration: Date.now() - startTime,
110+
rawRedisValue: redisValue,
111+
})
112+
101113
logger.info('Tool call status resolved', {
102114
toolCallId,
103115
status,

apps/sim/lib/copilot/tools/client-tools/run-workflow.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ export class RunWorkflowTool extends BaseTool {
139139

140140
// Note: toolCall.state is already set to 'executing' by clientAcceptTool
141141

142+
// Capture the execution timestamp
143+
const executionStartTime = new Date().toISOString()
144+
145+
// Store execution start time in context for background notifications
146+
if (options?.context) {
147+
options.context.executionStartTime = executionStartTime
148+
}
149+
142150
// Use the standalone execution utility with full logging support
143151
// This works for both deployed and non-deployed workflows
144152
const result = await executeWorkflowWithFullLogging({
@@ -151,8 +159,12 @@ export class RunWorkflowTool extends BaseTool {
151159

152160
// Check if execution was successful
153161
if (result && (!('success' in result) || result.success !== false)) {
154-
// Notify server of success
155-
await this.notify(toolCall.id, 'success', 'Workflow execution completed successfully')
162+
// Notify server of success with execution timestamp
163+
await this.notify(
164+
toolCall.id,
165+
'success',
166+
`Workflow execution completed successfully. Started at: ${executionStartTime}`
167+
)
156168

157169
options?.onStateChange?.('success')
158170

apps/sim/lib/copilot/tools/inline-tool-call.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,9 @@ export function InlineToolCall({ toolCall, onStateChange, context }: InlineToolC
262262
// Set tool state to background
263263
setToolCallState(toolCall, 'background')
264264

265-
// Notify the backend about background state
266-
await notifyServerTool(toolCall.id, toolCall.name, 'background')
265+
// Notify the backend about background state with execution start time if available
266+
const executionStartTime = context?.executionStartTime
267+
await notifyServerTool(toolCall.id, toolCall.name, 'background', executionStartTime)
267268

268269
// Track that this tool was moved to background
269270
if (context) {

apps/sim/lib/copilot/tools/notification-utils.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,21 @@ const SERVER_TOOL_MAPPINGS: Partial<Record<ToolState, NotificationStatus>> = {
3232
export async function notifyServerTool(
3333
toolId: string,
3434
toolName: string,
35-
toolState: ToolState
35+
toolState: ToolState,
36+
executionStartTime?: string
3637
): Promise<void> {
3738
const notificationStatus = SERVER_TOOL_MAPPINGS[toolState]
3839
if (!notificationStatus) {
3940
throw new Error(`Invalid tool state: ${toolState}`)
4041
}
41-
await notify(toolId, toolName, toolState)
42+
await notify(toolId, toolName, toolState, executionStartTime)
4243
}
4344

4445
export async function notify(
4546
toolId: string,
4647
toolName: string,
47-
toolState: ToolState
48+
toolState: ToolState,
49+
executionStartTime?: string
4850
): Promise<void> {
4951
// toolState must be in STATE_MAPPINGS
5052
const notificationStatus = STATE_MAPPINGS[toolState]
@@ -55,8 +57,15 @@ export async function notify(
5557
// Get the state message from tool metadata
5658
const metadata = toolRegistry.getToolMetadata(toolId)
5759
let stateMessage = metadata?.stateMessages?.[notificationStatus]
60+
61+
// If no message from metadata, provide default messages
5862
if (!stateMessage) {
59-
stateMessage = ''
63+
if (notificationStatus === 'background') {
64+
const timeInfo = executionStartTime ? ` Started at: ${executionStartTime}.` : ''
65+
stateMessage = `The user has moved tool execution to the background and it is not complete, it will run asynchronously.${timeInfo}`
66+
} else {
67+
stateMessage = ''
68+
}
6069
}
6170

6271
// Call backend confirm route
@@ -68,9 +77,7 @@ export async function notify(
6877
body: JSON.stringify({
6978
toolCallId: toolId,
7079
status: notificationStatus,
71-
toolName,
72-
toolState,
73-
stateMessage,
80+
message: stateMessage,
7481
}),
7582
})
7683
}

apps/sim/lib/copilot/tools/tool-confirmation.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ export function ToolConfirmation({
6161
})
6262
} else {
6363
// For server tools, use the notification system
64-
const toolState = action === 'run' ? 'accepted' : 'rejected'
65-
const uiState = action === 'run' ? 'accepted' : 'rejected'
64+
const toolState =
65+
action === 'run' ? 'accepted' : action === 'background' ? 'background' : 'rejected'
66+
const uiState =
67+
action === 'run' ? 'accepted' : action === 'background' ? 'background' : 'rejected'
6668

6769
// Update UI state
6870
onStateChange(uiState)

0 commit comments

Comments
 (0)