mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-06 20:55:23 -05:00
improvements to resolve nested subblock values
This commit is contained in:
@@ -5,6 +5,7 @@ import { Tooltip } from '@/components/emcn'
|
||||
import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox'
|
||||
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import type { SelectorContext } from '@/hooks/selectors/types'
|
||||
|
||||
@@ -33,7 +34,8 @@ export function DocumentSelector({
|
||||
previewContextValues,
|
||||
})
|
||||
const [knowledgeBaseIdFromStore] = useSubBlockValue(blockId, 'knowledgeBaseId')
|
||||
const knowledgeBaseIdValue = previewContextValues?.knowledgeBaseId ?? knowledgeBaseIdFromStore
|
||||
const knowledgeBaseIdValue =
|
||||
resolvePreviewContextValue(previewContextValues?.knowledgeBaseId) ?? knowledgeBaseIdFromStore
|
||||
const normalizedKnowledgeBaseId =
|
||||
typeof knowledgeBaseIdValue === 'string' && knowledgeBaseIdValue.trim().length > 0
|
||||
? knowledgeBaseIdValue
|
||||
|
||||
@@ -17,6 +17,7 @@ import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/
|
||||
import { TagDropdown } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown'
|
||||
import { useSubBlockInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-input'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useKnowledgeBaseTagDefinitions } from '@/hooks/kb/use-knowledge-base-tag-definitions'
|
||||
@@ -77,7 +78,8 @@ export function DocumentTagEntry({
|
||||
})
|
||||
|
||||
const [knowledgeBaseIdFromStore] = useSubBlockValue(blockId, 'knowledgeBaseId')
|
||||
const knowledgeBaseIdValue = previewContextValues?.knowledgeBaseId ?? knowledgeBaseIdFromStore
|
||||
const knowledgeBaseIdValue =
|
||||
resolvePreviewContextValue(previewContextValues?.knowledgeBaseId) ?? knowledgeBaseIdFromStore
|
||||
const knowledgeBaseId =
|
||||
typeof knowledgeBaseIdValue === 'string' && knowledgeBaseIdValue.trim().length > 0
|
||||
? knowledgeBaseIdValue
|
||||
|
||||
@@ -9,6 +9,7 @@ import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/c
|
||||
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
|
||||
import { useForeignCredential } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-foreign-credential'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import { getBlock } from '@/blocks/registry'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { isDependency } from '@/blocks/utils'
|
||||
@@ -62,40 +63,42 @@ export function FileSelectorInput({
|
||||
|
||||
const [domainValueFromStore] = useSubBlockValue(blockId, 'domain')
|
||||
|
||||
const connectedCredential = previewContextValues?.credential ?? blockValues.credential
|
||||
const domainValue = previewContextValues?.domain ?? domainValueFromStore
|
||||
const connectedCredential =
|
||||
resolvePreviewContextValue(previewContextValues?.credential) ?? blockValues.credential
|
||||
const domainValue =
|
||||
resolvePreviewContextValue(previewContextValues?.domain) ?? domainValueFromStore
|
||||
|
||||
const teamIdValue = useMemo(
|
||||
() =>
|
||||
previewContextValues?.teamId ??
|
||||
resolvePreviewContextValue(previewContextValues?.teamId) ??
|
||||
resolveDependencyValue('teamId', blockValues, canonicalIndex, canonicalModeOverrides),
|
||||
[previewContextValues?.teamId, blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
const siteIdValue = useMemo(
|
||||
() =>
|
||||
previewContextValues?.siteId ??
|
||||
resolvePreviewContextValue(previewContextValues?.siteId) ??
|
||||
resolveDependencyValue('siteId', blockValues, canonicalIndex, canonicalModeOverrides),
|
||||
[previewContextValues?.siteId, blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
const collectionIdValue = useMemo(
|
||||
() =>
|
||||
previewContextValues?.collectionId ??
|
||||
resolvePreviewContextValue(previewContextValues?.collectionId) ??
|
||||
resolveDependencyValue('collectionId', blockValues, canonicalIndex, canonicalModeOverrides),
|
||||
[previewContextValues?.collectionId, blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
const projectIdValue = useMemo(
|
||||
() =>
|
||||
previewContextValues?.projectId ??
|
||||
resolvePreviewContextValue(previewContextValues?.projectId) ??
|
||||
resolveDependencyValue('projectId', blockValues, canonicalIndex, canonicalModeOverrides),
|
||||
[previewContextValues?.projectId, blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
const planIdValue = useMemo(
|
||||
() =>
|
||||
previewContextValues?.planId ??
|
||||
resolvePreviewContextValue(previewContextValues?.planId) ??
|
||||
resolveDependencyValue('planId', blockValues, canonicalIndex, canonicalModeOverrides),
|
||||
[previewContextValues?.planId, blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/c
|
||||
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
|
||||
import { useForeignCredential } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-foreign-credential'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { resolveSelectorForSubBlock } from '@/hooks/selectors/resolution'
|
||||
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
|
||||
@@ -17,6 +18,7 @@ interface FolderSelectorInputProps {
|
||||
disabled?: boolean
|
||||
isPreview?: boolean
|
||||
previewValue?: any | null
|
||||
previewContextValues?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export function FolderSelectorInput({
|
||||
@@ -25,9 +27,12 @@ export function FolderSelectorInput({
|
||||
disabled = false,
|
||||
isPreview = false,
|
||||
previewValue,
|
||||
previewContextValues,
|
||||
}: FolderSelectorInputProps) {
|
||||
const [storeValue] = useSubBlockValue(blockId, subBlock.id)
|
||||
const [connectedCredential] = useSubBlockValue(blockId, 'credential')
|
||||
const [credentialFromStore] = useSubBlockValue(blockId, 'credential')
|
||||
const connectedCredential =
|
||||
resolvePreviewContextValue(previewContextValues?.credential) ?? credentialFromStore
|
||||
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
|
||||
const { activeWorkflowId } = useWorkflowRegistry()
|
||||
const [selectedFolderId, setSelectedFolderId] = useState<string>('')
|
||||
@@ -47,7 +52,11 @@ export function FolderSelectorInput({
|
||||
)
|
||||
|
||||
// Central dependsOn gating
|
||||
const { finalDisabled } = useDependsOnGate(blockId, subBlock, { disabled, isPreview })
|
||||
const { finalDisabled } = useDependsOnGate(blockId, subBlock, {
|
||||
disabled,
|
||||
isPreview,
|
||||
previewContextValues,
|
||||
})
|
||||
|
||||
// Get the current value from the store or prop value if in preview mode
|
||||
useEffect(() => {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/
|
||||
import { TagDropdown } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown'
|
||||
import { useSubBlockInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-input'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
|
||||
import { useWorkflowState } from '@/hooks/queries/workflows'
|
||||
|
||||
@@ -37,6 +38,8 @@ interface InputMappingProps {
|
||||
isPreview?: boolean
|
||||
previewValue?: Record<string, unknown>
|
||||
disabled?: boolean
|
||||
/** Sub-block values from the preview context for resolving sibling sub-block values */
|
||||
previewContextValues?: Record<string, unknown>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,9 +53,12 @@ export function InputMapping({
|
||||
isPreview = false,
|
||||
previewValue,
|
||||
disabled = false,
|
||||
previewContextValues,
|
||||
}: InputMappingProps) {
|
||||
const [mapping, setMapping] = useSubBlockValue(blockId, subBlockId)
|
||||
const [selectedWorkflowId] = useSubBlockValue(blockId, 'workflowId')
|
||||
const [storeWorkflowId] = useSubBlockValue(blockId, 'workflowId')
|
||||
const selectedWorkflowId =
|
||||
resolvePreviewContextValue(previewContextValues?.workflowId) ?? storeWorkflowId
|
||||
|
||||
const inputController = useSubBlockInput({
|
||||
blockId,
|
||||
|
||||
@@ -17,6 +17,7 @@ import { type FilterFieldType, getOperatorsForFieldType } from '@/lib/knowledge/
|
||||
import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text'
|
||||
import { TagDropdown } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown'
|
||||
import { useSubBlockInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-input'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import { useAccessibleReferencePrefixes } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-accessible-reference-prefixes'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useKnowledgeBaseTagDefinitions } from '@/hooks/kb/use-knowledge-base-tag-definitions'
|
||||
@@ -69,7 +70,8 @@ export function KnowledgeTagFilters({
|
||||
const overlayRefs = useRef<Record<string, HTMLDivElement>>({})
|
||||
|
||||
const [knowledgeBaseIdFromStore] = useSubBlockValue(blockId, 'knowledgeBaseId')
|
||||
const knowledgeBaseIdValue = previewContextValues?.knowledgeBaseId ?? knowledgeBaseIdFromStore
|
||||
const knowledgeBaseIdValue =
|
||||
resolvePreviewContextValue(previewContextValues?.knowledgeBaseId) ?? knowledgeBaseIdFromStore
|
||||
const knowledgeBaseId =
|
||||
typeof knowledgeBaseIdValue === 'string' && knowledgeBaseIdValue.trim().length > 0
|
||||
? knowledgeBaseIdValue
|
||||
|
||||
@@ -6,6 +6,7 @@ import { cn } from '@/lib/core/utils/cn'
|
||||
import { LongInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/long-input/long-input'
|
||||
import { ShortInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/short-input/short-input'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useMcpTools } from '@/hooks/mcp/use-mcp-tools'
|
||||
import { formatParameterLabel } from '@/tools/params'
|
||||
@@ -18,6 +19,7 @@ interface McpDynamicArgsProps {
|
||||
disabled?: boolean
|
||||
isPreview?: boolean
|
||||
previewValue?: any
|
||||
previewContextValues?: Record<string, unknown>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,12 +49,16 @@ export function McpDynamicArgs({
|
||||
disabled = false,
|
||||
isPreview = false,
|
||||
previewValue,
|
||||
previewContextValues,
|
||||
}: McpDynamicArgsProps) {
|
||||
const params = useParams()
|
||||
const workspaceId = params.workspaceId as string
|
||||
const { mcpTools, isLoading } = useMcpTools(workspaceId)
|
||||
const [selectedTool] = useSubBlockValue(blockId, 'tool')
|
||||
const [cachedSchema] = useSubBlockValue(blockId, '_toolSchema')
|
||||
const [toolFromStore] = useSubBlockValue(blockId, 'tool')
|
||||
const selectedTool = resolvePreviewContextValue(previewContextValues?.tool) ?? toolFromStore
|
||||
const [schemaFromStore] = useSubBlockValue(blockId, '_toolSchema')
|
||||
const cachedSchema =
|
||||
resolvePreviewContextValue(previewContextValues?._toolSchema) ?? schemaFromStore
|
||||
const [toolArgs, setToolArgs] = useSubBlockValue(blockId, subBlockId)
|
||||
|
||||
const selectedToolConfig = mcpTools.find((tool) => tool.id === selectedTool)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useEffect, useMemo, useState } from 'react'
|
||||
import { useParams } from 'next/navigation'
|
||||
import { Combobox } from '@/components/emcn/components'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { useMcpTools } from '@/hooks/mcp/use-mcp-tools'
|
||||
|
||||
@@ -13,6 +14,7 @@ interface McpToolSelectorProps {
|
||||
disabled?: boolean
|
||||
isPreview?: boolean
|
||||
previewValue?: string | null
|
||||
previewContextValues?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export function McpToolSelector({
|
||||
@@ -21,6 +23,7 @@ export function McpToolSelector({
|
||||
disabled = false,
|
||||
isPreview = false,
|
||||
previewValue,
|
||||
previewContextValues,
|
||||
}: McpToolSelectorProps) {
|
||||
const params = useParams()
|
||||
const workspaceId = params.workspaceId as string
|
||||
@@ -31,7 +34,8 @@ export function McpToolSelector({
|
||||
const [storeValue, setStoreValue] = useSubBlockValue(blockId, subBlock.id)
|
||||
const [, setSchemaCache] = useSubBlockValue(blockId, '_toolSchema')
|
||||
|
||||
const [serverValue] = useSubBlockValue(blockId, 'server')
|
||||
const [serverFromStore] = useSubBlockValue(blockId, 'server')
|
||||
const serverValue = resolvePreviewContextValue(previewContextValues?.server) ?? serverFromStore
|
||||
|
||||
const label = subBlock.placeholder || 'Select tool'
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/c
|
||||
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
|
||||
import { useForeignCredential } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-foreign-credential'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import { getBlock } from '@/blocks/registry'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { resolveSelectorForSubBlock } from '@/hooks/selectors/resolution'
|
||||
@@ -55,12 +56,13 @@ export function ProjectSelectorInput({
|
||||
return (workflowValues as Record<string, Record<string, unknown>>)[blockId] || {}
|
||||
})
|
||||
|
||||
const connectedCredential = previewContextValues?.credential ?? blockValues.credential
|
||||
const jiraDomain = previewContextValues?.domain ?? jiraDomainFromStore
|
||||
const connectedCredential =
|
||||
resolvePreviewContextValue(previewContextValues?.credential) ?? blockValues.credential
|
||||
const jiraDomain = resolvePreviewContextValue(previewContextValues?.domain) ?? jiraDomainFromStore
|
||||
|
||||
const linearTeamId = useMemo(
|
||||
() =>
|
||||
previewContextValues?.teamId ??
|
||||
resolvePreviewContextValue(previewContextValues?.teamId) ??
|
||||
resolveDependencyValue('teamId', blockValues, canonicalIndex, canonicalModeOverrides),
|
||||
[previewContextValues?.teamId, blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import { buildCanonicalIndex, resolveDependencyValue } from '@/lib/workflows/sub
|
||||
import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/selector-combobox/selector-combobox'
|
||||
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
|
||||
import { useForeignCredential } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-foreign-credential'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import { getBlock } from '@/blocks/registry'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import { resolveSelectorForSubBlock, type SelectorResolution } from '@/hooks/selectors/resolution'
|
||||
@@ -66,9 +67,11 @@ export function SheetSelectorInput({
|
||||
[blockValues, canonicalIndex, canonicalModeOverrides]
|
||||
)
|
||||
|
||||
const connectedCredential = previewContextValues?.credential ?? connectedCredentialFromStore
|
||||
const connectedCredential =
|
||||
resolvePreviewContextValue(previewContextValues?.credential) ?? connectedCredentialFromStore
|
||||
const spreadsheetId = previewContextValues
|
||||
? (previewContextValues.spreadsheetId ?? previewContextValues.manualSpreadsheetId)
|
||||
? (resolvePreviewContextValue(previewContextValues.spreadsheetId) ??
|
||||
resolvePreviewContextValue(previewContextValues.manualSpreadsheetId))
|
||||
: spreadsheetIdFromStore
|
||||
|
||||
const normalizedCredentialId =
|
||||
|
||||
@@ -8,6 +8,7 @@ import { SelectorCombobox } from '@/app/workspace/[workspaceId]/w/[workflowId]/c
|
||||
import { useDependsOnGate } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-depends-on-gate'
|
||||
import { useForeignCredential } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-foreign-credential'
|
||||
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
|
||||
import { resolvePreviewContextValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/utils'
|
||||
import type { SubBlockConfig } from '@/blocks/types'
|
||||
import type { SelectorContext, SelectorKey } from '@/hooks/selectors/types'
|
||||
|
||||
@@ -58,9 +59,11 @@ export function SlackSelectorInput({
|
||||
const [botToken] = useSubBlockValue(blockId, 'botToken')
|
||||
const [connectedCredential] = useSubBlockValue(blockId, 'credential')
|
||||
|
||||
const effectiveAuthMethod = previewContextValues?.authMethod ?? authMethod
|
||||
const effectiveBotToken = previewContextValues?.botToken ?? botToken
|
||||
const effectiveCredential = previewContextValues?.credential ?? connectedCredential
|
||||
const effectiveAuthMethod =
|
||||
resolvePreviewContextValue(previewContextValues?.authMethod) ?? authMethod
|
||||
const effectiveBotToken = resolvePreviewContextValue(previewContextValues?.botToken) ?? botToken
|
||||
const effectiveCredential =
|
||||
resolvePreviewContextValue(previewContextValues?.credential) ?? connectedCredential
|
||||
const [_selectedValue, setSelectedValue] = useState<string | null>(null)
|
||||
|
||||
const serviceId = subBlock.serviceId || ''
|
||||
|
||||
@@ -820,6 +820,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -831,6 +832,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -853,6 +855,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue as any}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -864,6 +867,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue as any}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -875,6 +879,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue as any}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -899,6 +904,7 @@ function SubBlockComponent({
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue as any}
|
||||
disabled={isDisabled}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -934,6 +940,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -967,6 +974,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue as any}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -978,6 +986,7 @@ function SubBlockComponent({
|
||||
disabled={isDisabled}
|
||||
isPreview={isPreview}
|
||||
previewValue={previewValue}
|
||||
previewContextValues={isPreview ? subBlockValues : undefined}
|
||||
/>
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Extracts the raw value from a preview context entry.
|
||||
*
|
||||
* @remarks
|
||||
* In the sub-block preview context, values are wrapped as `{ value: T }` objects
|
||||
* (the full sub-block state). In the tool-input preview context, values are already
|
||||
* raw. This function normalizes both cases to return the underlying value.
|
||||
*
|
||||
* @param raw - The preview context entry, which may be a raw value or a `{ value: T }` wrapper
|
||||
* @returns The unwrapped value, or `null` if the input is nullish
|
||||
*/
|
||||
export function resolvePreviewContextValue(raw: unknown): unknown {
|
||||
if (raw === null || raw === undefined) return null
|
||||
if (typeof raw === 'object' && !Array.isArray(raw) && 'value' in raw) {
|
||||
return (raw as Record<string, unknown>).value ?? null
|
||||
}
|
||||
return raw
|
||||
}
|
||||
@@ -784,8 +784,12 @@ function PreviewEditorContent({
|
||||
? childWorkflowSnapshotState
|
||||
: childWorkflowState
|
||||
const resolvedIsLoadingChildWorkflow = isExecutionMode ? false : isLoadingChildWorkflow
|
||||
const isBlockNotExecuted = isExecutionMode && !executionData
|
||||
const isMissingChildWorkflow =
|
||||
Boolean(childWorkflowId) && !resolvedIsLoadingChildWorkflow && !resolvedChildWorkflowState
|
||||
Boolean(childWorkflowId) &&
|
||||
!isBlockNotExecuted &&
|
||||
!resolvedIsLoadingChildWorkflow &&
|
||||
!resolvedChildWorkflowState
|
||||
|
||||
/** Drills down into the child workflow or opens it in a new tab */
|
||||
const handleExpandChildWorkflow = useCallback(() => {
|
||||
@@ -1419,9 +1423,11 @@ function PreviewEditorContent({
|
||||
) : (
|
||||
<div className='flex h-full items-center justify-center bg-[var(--surface-3)]'>
|
||||
<span className='text-[13px] text-[var(--text-tertiary)]'>
|
||||
{isMissingChildWorkflow
|
||||
? DELETED_WORKFLOW_LABEL
|
||||
: 'Unable to load preview'}
|
||||
{isBlockNotExecuted
|
||||
? 'Not Executed'
|
||||
: isMissingChildWorkflow
|
||||
? DELETED_WORKFLOW_LABEL
|
||||
: 'Unable to load preview'}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -31,7 +31,6 @@ interface BlockExecutionData {
|
||||
/** Child trace spans for nested workflow blocks */
|
||||
children?: TraceSpan[]
|
||||
childWorkflowSnapshotId?: string
|
||||
childWorkflowName?: string
|
||||
}
|
||||
|
||||
/** Represents a level in the workflow navigation stack */
|
||||
@@ -88,7 +87,6 @@ export function buildBlockExecutions(spans: TraceSpan[]): Record<string, BlockEx
|
||||
|
||||
for (const span of allBlockSpans) {
|
||||
if (span.blockId && !blockExecutionMap[span.blockId]) {
|
||||
const output = span.output as Record<string, unknown> | undefined
|
||||
blockExecutionMap[span.blockId] = {
|
||||
input: redactApiKeys(span.input || {}),
|
||||
output: redactApiKeys(span.output || {}),
|
||||
@@ -96,8 +94,6 @@ export function buildBlockExecutions(spans: TraceSpan[]): Record<string, BlockEx
|
||||
durationMs: span.duration || 0,
|
||||
children: span.children,
|
||||
childWorkflowSnapshotId: span.childWorkflowSnapshotId,
|
||||
childWorkflowName:
|
||||
typeof output?.childWorkflowName === 'string' ? output.childWorkflowName : undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +192,7 @@ export function Preview({
|
||||
const childTraceSpans = extractChildTraceSpans(blockExecution)
|
||||
const childBlockExecutions = buildBlockExecutions(childTraceSpans)
|
||||
|
||||
const workflowName = blockExecution?.childWorkflowName || 'Nested Workflow'
|
||||
const workflowName = childWorkflowState.metadata?.name || 'Nested Workflow'
|
||||
|
||||
setWorkflowStack((prev) => [
|
||||
...prev,
|
||||
|
||||
@@ -33,11 +33,16 @@ export class SnapshotService implements ISnapshotService {
|
||||
|
||||
const existingSnapshot = await this.getSnapshotByHash(workflowId, stateHash)
|
||||
if (existingSnapshot) {
|
||||
await db
|
||||
.update(workflowExecutionSnapshots)
|
||||
.set({ stateData: state })
|
||||
.where(eq(workflowExecutionSnapshots.id, existingSnapshot.id))
|
||||
|
||||
logger.info(
|
||||
`Reusing existing snapshot for workflow ${workflowId} (hash: ${stateHash.slice(0, 12)}...)`
|
||||
)
|
||||
return {
|
||||
snapshot: existingSnapshot,
|
||||
snapshot: { ...existingSnapshot, stateData: state },
|
||||
isNew: false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user