diff --git a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.test.ts b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.test.ts new file mode 100644 index 000000000..a83a7efd4 --- /dev/null +++ b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.test.ts @@ -0,0 +1,44 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it, vi } from 'vitest' +import { createBlockFromParams } from './builders' + +const agentBlockConfig = { + type: 'agent', + name: 'Agent', + outputs: { + content: { type: 'string', description: 'Default content output' }, + }, + subBlocks: [{ id: 'responseFormat', type: 'response-format' }], +} + +vi.mock('@/blocks/registry', () => ({ + getAllBlocks: () => [agentBlockConfig], + getBlock: (type: string) => (type === 'agent' ? agentBlockConfig : undefined), +})) + +describe('createBlockFromParams', () => { + it('derives agent outputs from responseFormat when outputs are not provided', () => { + const block = createBlockFromParams('b-agent', { + type: 'agent', + name: 'Agent', + inputs: { + responseFormat: { + type: 'object', + properties: { + answer: { + type: 'string', + description: 'Structured answer text', + }, + }, + required: ['answer'], + }, + }, + triggerMode: false, + }) + + expect(block.outputs.answer).toBeDefined() + expect(block.outputs.answer.type).toBe('string') + }) +}) diff --git a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.ts b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.ts index 935e7bcee..21e71edfa 100644 --- a/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.ts +++ b/apps/sim/lib/copilot/tools/server/workflow/edit-workflow/builders.ts @@ -1,7 +1,7 @@ import crypto from 'crypto' import { createLogger } from '@sim/logger' import type { PermissionGroupConfig } from '@/lib/permission-groups/types' -import { getBlockOutputs } from '@/lib/workflows/blocks/block-outputs' +import { getEffectiveBlockOutputs } from '@/lib/workflows/blocks/block-outputs' import { buildCanonicalIndex, isCanonicalPair } from '@/lib/workflows/subblocks/visibility' import { getAllBlocks } from '@/blocks/registry' import type { BlockConfig } from '@/blocks/types' @@ -54,7 +54,10 @@ export function createBlockFromParams( subBlocks[key] = { id: key, type: 'short-input', value: value } }) } - outputs = getBlockOutputs(params.type, subBlocks, triggerMode) + outputs = getEffectiveBlockOutputs(params.type, subBlocks, { + triggerMode, + preferToolOutputs: !triggerMode, + }) } else { outputs = {} } diff --git a/apps/sim/lib/workflows/defaults.ts b/apps/sim/lib/workflows/defaults.ts index d93dd0b13..7de0c058a 100644 --- a/apps/sim/lib/workflows/defaults.ts +++ b/apps/sim/lib/workflows/defaults.ts @@ -1,4 +1,4 @@ -import { getBlockOutputs } from '@/lib/workflows/blocks/block-outputs' +import { getEffectiveBlockOutputs } from '@/lib/workflows/blocks/block-outputs' import { getBlock } from '@/blocks' import type { BlockConfig, SubBlockConfig } from '@/blocks/types' import type { BlockState, SubBlockState, WorkflowState } from '@/stores/workflows/workflow/types' @@ -85,7 +85,10 @@ function buildStartBlockState( subBlockValues[config.id] = initialValue ?? null }) - const outputs = getBlockOutputs(blockConfig.type, subBlocks) + const outputs = getEffectiveBlockOutputs(blockConfig.type, subBlocks, { + triggerMode: false, + preferToolOutputs: true, + }) const blockState: BlockState = { id: blockId, diff --git a/apps/sim/stores/workflows/utils.ts b/apps/sim/stores/workflows/utils.ts index 03039b7f8..c63e67053 100644 --- a/apps/sim/stores/workflows/utils.ts +++ b/apps/sim/stores/workflows/utils.ts @@ -1,7 +1,7 @@ import type { Edge } from 'reactflow' import { v4 as uuidv4 } from 'uuid' import { DEFAULT_DUPLICATE_OFFSET } from '@/lib/workflows/autolayout/constants' -import { getBlockOutputs } from '@/lib/workflows/blocks/block-outputs' +import { getEffectiveBlockOutputs } from '@/lib/workflows/blocks/block-outputs' import { mergeSubblockStateWithValues } from '@/lib/workflows/subblocks' import { TriggerUtils } from '@/lib/workflows/triggers/triggers' import { getBlock } from '@/blocks' @@ -188,7 +188,10 @@ export function prepareBlockState(options: PrepareBlockStateOptions): BlockState }) } - const outputs = getBlockOutputs(type, subBlocks, triggerMode) + const outputs = getEffectiveBlockOutputs(type, subBlocks, { + triggerMode, + preferToolOutputs: !triggerMode, + }) return { id,