diff --git a/apps/sim/serializer/index.test.ts b/apps/sim/serializer/index.test.ts index 9d725acef2..158d666fa6 100644 --- a/apps/sim/serializer/index.test.ts +++ b/apps/sim/serializer/index.test.ts @@ -961,5 +961,58 @@ describe('Serializer', () => { // Unknown fields are filtered out (no subblock config found, so shouldIncludeField is not called) expect(slackBlock?.config.params.unknownField).toBeUndefined() }) + + it.concurrent( + 'should preserve legacy agent fields (systemPrompt, userPrompt, memories) for backward compatibility', + () => { + const serializer = new Serializer() + + // Simulate an old workflow with legacy agent block format (before messages array migration) + const legacyAgentBlock: any = { + id: 'agent-1', + type: 'agent', + name: 'Legacy Agent', + position: { x: 0, y: 0 }, + advancedMode: false, + subBlocks: { + systemPrompt: { + id: 'systemPrompt', + type: 'long-input', + value: 'You are a helpful assistant.', + }, + userPrompt: { + id: 'userPrompt', + type: 'long-input', + value: 'What is the weather today?', + }, + memories: { + id: 'memories', + type: 'short-input', + value: [{ role: 'user', content: 'My name is Alice' }], + }, + model: { + id: 'model', + type: 'combobox', + value: 'gpt-4', + }, + }, + outputs: {}, + enabled: true, + } + + const serialized = serializer.serializeWorkflow({ 'agent-1': legacyAgentBlock }, [], {}) + + const agentBlock = serialized.blocks.find((b) => b.id === 'agent-1') + expect(agentBlock).toBeDefined() + + // Legacy fields should be preserved even though they're not in the current block config + expect(agentBlock?.config.params.systemPrompt).toBe('You are a helpful assistant.') + expect(agentBlock?.config.params.userPrompt).toBe('What is the weather today?') + expect(agentBlock?.config.params.memories).toEqual([ + { role: 'user', content: 'My name is Alice' }, + ]) + expect(agentBlock?.config.params.model).toBe('gpt-4') + } + ) }) }) diff --git a/apps/sim/serializer/index.ts b/apps/sim/serializer/index.ts index ca44df141f..3fb005c695 100644 --- a/apps/sim/serializer/index.ts +++ b/apps/sim/serializer/index.ts @@ -422,6 +422,7 @@ export class Serializer { const params: Record = {} const isAdvancedMode = block.advancedMode ?? false const isStarterBlock = block.type === 'starter' + const isAgentBlock = block.type === 'agent' // First collect all current values from subBlocks, filtering by mode Object.entries(block.subBlocks).forEach(([id, subBlock]) => { @@ -435,9 +436,15 @@ export class Serializer { Array.isArray(subBlock.value) && subBlock.value.length > 0 + // Include legacy agent block fields (systemPrompt, userPrompt, memories) even if not in current config + // This ensures backward compatibility with old workflows that were exported before the messages array migration + const isLegacyAgentField = + isAgentBlock && ['systemPrompt', 'userPrompt', 'memories'].includes(id) + if ( - subBlockConfig && - (shouldIncludeField(subBlockConfig, isAdvancedMode) || hasStarterInputFormatValues) + (subBlockConfig && + (shouldIncludeField(subBlockConfig, isAdvancedMode) || hasStarterInputFormatValues)) || + isLegacyAgentField ) { params[id] = subBlock.value }