Skip to content

Commit 080ab94

Browse files
committed
Cleanup
1 parent 69309ec commit 080ab94

File tree

5 files changed

+215
-196
lines changed

5 files changed

+215
-196
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/diff-controls/diff-controls.tsx

Lines changed: 12 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -7,192 +7,33 @@ import { usePreventZoom } from '@/app/workspace/[workspaceId]/w/[workflowId]/hoo
77
import { useCopilotStore, usePanelStore } from '@/stores/panel'
88
import { useTerminalStore } from '@/stores/terminal'
99
import { useWorkflowDiffStore } from '@/stores/workflow-diff'
10-
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
11-
import { mergeSubblockState } from '@/stores/workflows/utils'
12-
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
1310

1411
const logger = createLogger('DiffControls')
1512

1613
export const DiffControls = memo(function DiffControls() {
1714
const isTerminalResizing = useTerminalStore((state) => state.isResizing)
1815
const isPanelResizing = usePanelStore((state) => state.isResizing)
19-
const { isDiffReady, hasActiveDiff, acceptChanges, rejectChanges, baselineWorkflow } =
20-
useWorkflowDiffStore(
21-
useCallback(
22-
(state) => ({
23-
isDiffReady: state.isDiffReady,
24-
hasActiveDiff: state.hasActiveDiff,
25-
acceptChanges: state.acceptChanges,
26-
rejectChanges: state.rejectChanges,
27-
baselineWorkflow: state.baselineWorkflow,
28-
}),
29-
[]
30-
)
16+
const { isDiffReady, hasActiveDiff, acceptChanges, rejectChanges } = useWorkflowDiffStore(
17+
useCallback(
18+
(state) => ({
19+
isDiffReady: state.isDiffReady,
20+
hasActiveDiff: state.hasActiveDiff,
21+
acceptChanges: state.acceptChanges,
22+
rejectChanges: state.rejectChanges,
23+
}),
24+
[]
3125
)
26+
)
3227

33-
const { updatePreviewToolCallState, currentChat, messages } = useCopilotStore(
28+
const { updatePreviewToolCallState } = useCopilotStore(
3429
useCallback(
3530
(state) => ({
3631
updatePreviewToolCallState: state.updatePreviewToolCallState,
37-
currentChat: state.currentChat,
38-
messages: state.messages,
3932
}),
4033
[]
4134
)
4235
)
4336

44-
const { activeWorkflowId } = useWorkflowRegistry(
45-
useCallback((state) => ({ activeWorkflowId: state.activeWorkflowId }), [])
46-
)
47-
48-
const createCheckpoint = useCallback(async () => {
49-
if (!activeWorkflowId || !currentChat?.id) {
50-
logger.warn('Cannot create checkpoint: missing workflowId or chatId', {
51-
workflowId: activeWorkflowId,
52-
chatId: currentChat?.id,
53-
})
54-
return false
55-
}
56-
57-
try {
58-
logger.info('Creating checkpoint before accepting changes')
59-
60-
// Use the baseline workflow (state before diff) instead of current state
61-
// This ensures reverting to the checkpoint restores the pre-diff state
62-
const rawState = baselineWorkflow || useWorkflowStore.getState().getWorkflowState()
63-
64-
// The baseline already has merged subblock values, but we'll merge again to be safe
65-
// This ensures all user inputs and subblock data are captured
66-
const blocksWithSubblockValues = mergeSubblockState(rawState.blocks, activeWorkflowId)
67-
68-
// Filter and complete blocks to ensure all required fields are present
69-
// This matches the validation logic from /api/workflows/[id]/state
70-
const filteredBlocks = Object.entries(blocksWithSubblockValues).reduce(
71-
(acc, [blockId, block]) => {
72-
if (block.type && block.name) {
73-
// Ensure all required fields are present
74-
acc[blockId] = {
75-
...block,
76-
id: block.id || blockId, // Ensure id field is set
77-
enabled: block.enabled !== undefined ? block.enabled : true,
78-
horizontalHandles:
79-
block.horizontalHandles !== undefined ? block.horizontalHandles : true,
80-
height: block.height !== undefined ? block.height : 90,
81-
subBlocks: block.subBlocks || {},
82-
outputs: block.outputs || {},
83-
data: block.data || {},
84-
position: block.position || { x: 0, y: 0 }, // Ensure position exists
85-
}
86-
}
87-
return acc
88-
},
89-
{} as typeof rawState.blocks
90-
)
91-
92-
// Clean the workflow state - only include valid fields, exclude null/undefined values
93-
const workflowState = {
94-
blocks: filteredBlocks,
95-
edges: rawState.edges || [],
96-
loops: rawState.loops || {},
97-
parallels: rawState.parallels || {},
98-
lastSaved: rawState.lastSaved || Date.now(),
99-
deploymentStatuses: rawState.deploymentStatuses || {},
100-
}
101-
102-
logger.info('Prepared complete workflow state for checkpoint', {
103-
blocksCount: Object.keys(workflowState.blocks).length,
104-
edgesCount: workflowState.edges.length,
105-
loopsCount: Object.keys(workflowState.loops).length,
106-
parallelsCount: Object.keys(workflowState.parallels).length,
107-
hasRequiredFields: Object.values(workflowState.blocks).every(
108-
(block) => block.id && block.type && block.name && block.position
109-
),
110-
hasSubblockValues: Object.values(workflowState.blocks).some((block) =>
111-
Object.values(block.subBlocks || {}).some(
112-
(subblock) => subblock.value !== null && subblock.value !== undefined
113-
)
114-
),
115-
sampleBlock: Object.values(workflowState.blocks)[0],
116-
})
117-
118-
// Find the most recent user message ID from the current chat
119-
const userMessages = messages.filter((msg) => msg.role === 'user')
120-
const lastUserMessage = userMessages[userMessages.length - 1]
121-
const messageId = lastUserMessage?.id
122-
123-
logger.info('Creating checkpoint with message association', {
124-
totalMessages: messages.length,
125-
userMessageCount: userMessages.length,
126-
lastUserMessageId: messageId,
127-
chatId: currentChat.id,
128-
entireMessageArray: messages,
129-
allMessageIds: messages.map((m) => ({
130-
id: m.id,
131-
role: m.role,
132-
content: m.content.substring(0, 50),
133-
})),
134-
selectedUserMessages: userMessages.map((m) => ({
135-
id: m.id,
136-
content: m.content.substring(0, 100),
137-
})),
138-
allRawMessageIds: messages.map((m) => m.id),
139-
userMessageIds: userMessages.map((m) => m.id),
140-
checkpointData: {
141-
workflowId: activeWorkflowId,
142-
chatId: currentChat.id,
143-
messageId: messageId,
144-
messageFound: !!lastUserMessage,
145-
},
146-
})
147-
148-
const response = await fetch('/api/copilot/checkpoints', {
149-
method: 'POST',
150-
headers: { 'Content-Type': 'application/json' },
151-
body: JSON.stringify({
152-
workflowId: activeWorkflowId,
153-
chatId: currentChat.id,
154-
messageId,
155-
workflowState: JSON.stringify(workflowState),
156-
}),
157-
})
158-
159-
if (!response.ok) {
160-
throw new Error(`Failed to create checkpoint: ${response.statusText}`)
161-
}
162-
163-
const result = await response.json()
164-
const newCheckpoint = result.checkpoint
165-
166-
logger.info('Checkpoint created successfully', {
167-
messageId,
168-
chatId: currentChat.id,
169-
checkpointId: newCheckpoint?.id,
170-
})
171-
172-
// Update the copilot store immediately to show the checkpoint icon
173-
if (newCheckpoint && messageId) {
174-
const { messageCheckpoints: currentCheckpoints } = useCopilotStore.getState()
175-
const existingCheckpoints = currentCheckpoints[messageId] || []
176-
177-
const updatedCheckpoints = {
178-
...currentCheckpoints,
179-
[messageId]: [newCheckpoint, ...existingCheckpoints],
180-
}
181-
182-
useCopilotStore.setState({ messageCheckpoints: updatedCheckpoints })
183-
logger.info('Updated copilot store with new checkpoint', {
184-
messageId,
185-
checkpointId: newCheckpoint.id,
186-
})
187-
}
188-
189-
return true
190-
} catch (error) {
191-
logger.error('Failed to create checkpoint:', error)
192-
return false
193-
}
194-
}, [activeWorkflowId, currentChat, messages, baselineWorkflow])
195-
19637
const handleAccept = useCallback(() => {
19738
logger.info('Accepting proposed changes with backup protection')
19839

@@ -229,12 +70,8 @@ export const DiffControls = memo(function DiffControls() {
22970
})
23071

23172
// Create checkpoint in the background (fire-and-forget) so it doesn't block UI
232-
createCheckpoint().catch((error) => {
233-
logger.warn('Failed to create checkpoint after accept:', error)
234-
})
235-
23673
logger.info('Accept triggered; UI will update optimistically')
237-
}, [createCheckpoint, updatePreviewToolCallState, acceptChanges])
74+
}, [updatePreviewToolCallState, acceptChanges])
23875

23976
const handleReject = useCallback(() => {
24077
logger.info('Rejecting proposed changes (optimistic)')

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/copilot-message/hooks/use-checkpoint-management.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function useCheckpointManagement(
5757
const { messageCheckpoints: currentCheckpoints } = useCopilotStore.getState()
5858
const updatedCheckpoints = {
5959
...currentCheckpoints,
60-
[message.id]: messageCheckpoints.slice(1),
60+
[message.id]: [],
6161
}
6262
useCopilotStore.setState({ messageCheckpoints: updatedCheckpoints })
6363

@@ -140,7 +140,7 @@ export function useCheckpointManagement(
140140
const { messageCheckpoints: currentCheckpoints } = useCopilotStore.getState()
141141
const updatedCheckpoints = {
142142
...currentCheckpoints,
143-
[message.id]: messageCheckpoints.slice(1),
143+
[message.id]: [],
144144
}
145145
useCopilotStore.setState({ messageCheckpoints: updatedCheckpoints })
146146

0 commit comments

Comments
 (0)