mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-27 07:48:22 -05:00
118 lines
3.7 KiB
TypeScript
118 lines
3.7 KiB
TypeScript
import { normalizeInputFormatValue } from '@/lib/workflows/input-format'
|
|
import { isTriggerBehavior, normalizeName } from '@/executor/constants'
|
|
import type { ExecutionContext } from '@/executor/types'
|
|
import type { OutputSchema } from '@/executor/utils/block-reference'
|
|
import type { SerializedBlock } from '@/serializer/types'
|
|
import type { ToolConfig } from '@/tools/types'
|
|
import { getTool } from '@/tools/utils'
|
|
|
|
export interface BlockDataCollection {
|
|
blockData: Record<string, unknown>
|
|
blockNameMapping: Record<string, string>
|
|
blockOutputSchemas: Record<string, OutputSchema>
|
|
}
|
|
|
|
/**
|
|
* Block types where inputFormat fields should be merged into outputs schema.
|
|
* These are blocks where users define custom fields via inputFormat that become
|
|
* valid output paths (e.g., <start.myField>, <webhook1.customField>, <hitl1.resumeField>).
|
|
*
|
|
* Note: This includes non-trigger blocks like 'starter' and 'human_in_the_loop' which
|
|
* have category 'blocks' but still need their inputFormat exposed as outputs.
|
|
*/
|
|
const BLOCKS_WITH_INPUT_FORMAT_OUTPUTS = [
|
|
'start_trigger',
|
|
'starter',
|
|
'api_trigger',
|
|
'input_trigger',
|
|
'generic_webhook',
|
|
'human_in_the_loop',
|
|
] as const
|
|
|
|
function getInputFormatFields(block: SerializedBlock): OutputSchema {
|
|
const inputFormat = normalizeInputFormatValue(block.config?.params?.inputFormat)
|
|
if (inputFormat.length === 0) {
|
|
return {}
|
|
}
|
|
|
|
const schema: OutputSchema = {}
|
|
for (const field of inputFormat) {
|
|
if (!field.name) continue
|
|
schema[field.name] = {
|
|
type: (field.type || 'any') as 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any',
|
|
}
|
|
}
|
|
|
|
return schema
|
|
}
|
|
|
|
export function getBlockSchema(
|
|
block: SerializedBlock,
|
|
toolConfig?: ToolConfig
|
|
): OutputSchema | undefined {
|
|
const blockType = block.metadata?.id
|
|
|
|
// For blocks that expose inputFormat as outputs, always merge them
|
|
// This includes both triggers (start_trigger, generic_webhook) and
|
|
// non-triggers (starter, human_in_the_loop) that have inputFormat
|
|
if (
|
|
blockType &&
|
|
BLOCKS_WITH_INPUT_FORMAT_OUTPUTS.includes(
|
|
blockType as (typeof BLOCKS_WITH_INPUT_FORMAT_OUTPUTS)[number]
|
|
)
|
|
) {
|
|
const baseOutputs = (block.outputs as OutputSchema) || {}
|
|
const inputFormatFields = getInputFormatFields(block)
|
|
const merged = { ...baseOutputs, ...inputFormatFields }
|
|
if (Object.keys(merged).length > 0) {
|
|
return merged
|
|
}
|
|
}
|
|
|
|
const isTrigger = isTriggerBehavior(block)
|
|
|
|
if (isTrigger && block.outputs && Object.keys(block.outputs).length > 0) {
|
|
return block.outputs as OutputSchema
|
|
}
|
|
|
|
if (toolConfig?.outputs && Object.keys(toolConfig.outputs).length > 0) {
|
|
return toolConfig.outputs as OutputSchema
|
|
}
|
|
|
|
if (block.outputs && Object.keys(block.outputs).length > 0) {
|
|
return block.outputs as OutputSchema
|
|
}
|
|
|
|
return undefined
|
|
}
|
|
|
|
export function collectBlockData(ctx: ExecutionContext): BlockDataCollection {
|
|
const blockData: Record<string, unknown> = {}
|
|
const blockNameMapping: Record<string, string> = {}
|
|
const blockOutputSchemas: Record<string, OutputSchema> = {}
|
|
|
|
for (const [id, state] of ctx.blockStates.entries()) {
|
|
if (state.output !== undefined) {
|
|
blockData[id] = state.output
|
|
}
|
|
}
|
|
|
|
const workflowBlocks = ctx.workflow?.blocks ?? []
|
|
for (const block of workflowBlocks) {
|
|
const id = block.id
|
|
|
|
if (block.metadata?.name) {
|
|
blockNameMapping[normalizeName(block.metadata.name)] = id
|
|
}
|
|
|
|
const toolId = block.config?.tool
|
|
const toolConfig = toolId ? getTool(toolId) : undefined
|
|
const schema = getBlockSchema(block, toolConfig)
|
|
if (schema && Object.keys(schema).length > 0) {
|
|
blockOutputSchemas[id] = schema
|
|
}
|
|
}
|
|
|
|
return { blockData, blockNameMapping, blockOutputSchemas }
|
|
}
|