mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-21 12:58:07 -05:00
Compare commits
5 Commits
feat/tools
...
fix/deploy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
098b9eff8c | ||
|
|
1d450578c8 | ||
|
|
c6d408c65b | ||
|
|
16716ea26a | ||
|
|
563098ca0a |
@@ -26,7 +26,6 @@ export interface CanvasMenuProps {
|
|||||||
onOpenLogs: () => void
|
onOpenLogs: () => void
|
||||||
onToggleVariables: () => void
|
onToggleVariables: () => void
|
||||||
onToggleChat: () => void
|
onToggleChat: () => void
|
||||||
onInvite: () => void
|
|
||||||
isVariablesOpen?: boolean
|
isVariablesOpen?: boolean
|
||||||
isChatOpen?: boolean
|
isChatOpen?: boolean
|
||||||
hasClipboard?: boolean
|
hasClipboard?: boolean
|
||||||
@@ -55,15 +54,12 @@ export function CanvasMenu({
|
|||||||
onOpenLogs,
|
onOpenLogs,
|
||||||
onToggleVariables,
|
onToggleVariables,
|
||||||
onToggleChat,
|
onToggleChat,
|
||||||
onInvite,
|
|
||||||
isVariablesOpen = false,
|
isVariablesOpen = false,
|
||||||
isChatOpen = false,
|
isChatOpen = false,
|
||||||
hasClipboard = false,
|
hasClipboard = false,
|
||||||
disableEdit = false,
|
disableEdit = false,
|
||||||
disableAdmin = false,
|
|
||||||
canUndo = false,
|
canUndo = false,
|
||||||
canRedo = false,
|
canRedo = false,
|
||||||
isInvitationsDisabled = false,
|
|
||||||
}: CanvasMenuProps) {
|
}: CanvasMenuProps) {
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
@@ -179,22 +175,6 @@ export function CanvasMenu({
|
|||||||
>
|
>
|
||||||
{isChatOpen ? 'Close Chat' : 'Open Chat'}
|
{isChatOpen ? 'Close Chat' : 'Open Chat'}
|
||||||
</PopoverItem>
|
</PopoverItem>
|
||||||
|
|
||||||
{/* Admin action - hidden when invitations are disabled */}
|
|
||||||
{!isInvitationsDisabled && (
|
|
||||||
<>
|
|
||||||
<PopoverDivider />
|
|
||||||
<PopoverItem
|
|
||||||
disabled={disableAdmin}
|
|
||||||
onClick={() => {
|
|
||||||
onInvite()
|
|
||||||
onClose()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Invite to Workspace
|
|
||||||
</PopoverItem>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -886,17 +886,16 @@ export function Chat() {
|
|||||||
onMouseDown={(e) => e.stopPropagation()}
|
onMouseDown={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{shouldShowConfigureStartInputsButton && (
|
{shouldShowConfigureStartInputsButton && (
|
||||||
<Badge
|
<div
|
||||||
variant='outline'
|
className='flex flex-none cursor-pointer items-center whitespace-nowrap rounded-[6px] border border-[var(--border-1)] bg-[var(--surface-5)] px-[9px] py-[2px] font-medium font-sans text-[12px] text-[var(--text-primary)] hover:bg-[var(--surface-7)] dark:hover:border-[var(--surface-7)] dark:hover:bg-[var(--border-1)]'
|
||||||
className='flex-none cursor-pointer whitespace-nowrap rounded-[6px]'
|
|
||||||
title='Add chat inputs to Start block'
|
title='Add chat inputs to Start block'
|
||||||
onMouseDown={(e) => {
|
onMouseDown={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
handleConfigureStartInputs()
|
handleConfigureStartInputs()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className='whitespace-nowrap text-[12px]'>Add inputs</span>
|
<span className='whitespace-nowrap'>Add inputs</span>
|
||||||
</Badge>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<OutputSelect
|
<OutputSelect
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { createLogger } from '@sim/logger'
|
|||||||
import { Check, Clipboard } from 'lucide-react'
|
import { Check, Clipboard } from 'lucide-react'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
import {
|
import {
|
||||||
Badge,
|
|
||||||
Button,
|
Button,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
ButtonGroupItem,
|
ButtonGroupItem,
|
||||||
@@ -883,14 +882,13 @@ console.log(data);`
|
|||||||
<code className='text-[10px]'><start.files></code>.
|
<code className='text-[10px]'><start.files></code>.
|
||||||
</p>
|
</p>
|
||||||
{missingFields.any && (
|
{missingFields.any && (
|
||||||
<Badge
|
<div
|
||||||
variant='outline'
|
className='flex flex-none cursor-pointer items-center whitespace-nowrap rounded-[6px] border border-[var(--border-1)] bg-[var(--surface-5)] px-[9px] py-[2px] font-medium font-sans text-[12px] text-[var(--text-primary)] hover:bg-[var(--surface-7)] dark:hover:border-[var(--surface-7)] dark:hover:bg-[var(--border-1)]'
|
||||||
className='flex-none cursor-pointer whitespace-nowrap rounded-[6px]'
|
|
||||||
title='Add required A2A input fields to Start block'
|
title='Add required A2A input fields to Start block'
|
||||||
onClick={handleAddA2AInputs}
|
onClick={handleAddA2AInputs}
|
||||||
>
|
>
|
||||||
<span className='whitespace-nowrap text-[12px]'>Add inputs</span>
|
<span className='whitespace-nowrap'>Add inputs</span>
|
||||||
</Badge>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3323,15 +3323,12 @@ const WorkflowContent = React.memo(() => {
|
|||||||
onOpenLogs={handleContextOpenLogs}
|
onOpenLogs={handleContextOpenLogs}
|
||||||
onToggleVariables={handleContextToggleVariables}
|
onToggleVariables={handleContextToggleVariables}
|
||||||
onToggleChat={handleContextToggleChat}
|
onToggleChat={handleContextToggleChat}
|
||||||
onInvite={handleContextInvite}
|
|
||||||
isVariablesOpen={isVariablesOpen}
|
isVariablesOpen={isVariablesOpen}
|
||||||
isChatOpen={isChatOpen}
|
isChatOpen={isChatOpen}
|
||||||
hasClipboard={hasClipboard()}
|
hasClipboard={hasClipboard()}
|
||||||
disableEdit={!effectivePermissions.canEdit}
|
disableEdit={!effectivePermissions.canEdit}
|
||||||
disableAdmin={!effectivePermissions.canAdmin}
|
|
||||||
canUndo={canUndo}
|
canUndo={canUndo}
|
||||||
canRedo={canRedo}
|
canRedo={canRedo}
|
||||||
isInvitationsDisabled={isInvitationsDisabled}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
GetBlockConfigInput,
|
GetBlockConfigInput,
|
||||||
GetBlockConfigResult,
|
GetBlockConfigResult,
|
||||||
} from '@/lib/copilot/tools/shared/schemas'
|
} from '@/lib/copilot/tools/shared/schemas'
|
||||||
import { getBlock } from '@/blocks/registry'
|
import { getLatestBlock } from '@/blocks/registry'
|
||||||
|
|
||||||
interface GetBlockConfigArgs {
|
interface GetBlockConfigArgs {
|
||||||
blockType: string
|
blockType: string
|
||||||
@@ -40,8 +40,7 @@ export class GetBlockConfigClientTool extends BaseClientTool {
|
|||||||
},
|
},
|
||||||
getDynamicText: (params, state) => {
|
getDynamicText: (params, state) => {
|
||||||
if (params?.blockType && typeof params.blockType === 'string') {
|
if (params?.blockType && typeof params.blockType === 'string') {
|
||||||
// Look up the block config to get the human-readable name
|
const blockConfig = getLatestBlock(params.blockType)
|
||||||
const blockConfig = getBlock(params.blockType)
|
|
||||||
const blockName = (blockConfig?.name ?? params.blockType.replace(/_/g, ' ')).toLowerCase()
|
const blockName = (blockConfig?.name ?? params.blockType.replace(/_/g, ' ')).toLowerCase()
|
||||||
const opSuffix = params.operation ? ` (${params.operation})` : ''
|
const opSuffix = params.operation ? ` (${params.operation})` : ''
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
GetBlockOptionsInput,
|
GetBlockOptionsInput,
|
||||||
GetBlockOptionsResult,
|
GetBlockOptionsResult,
|
||||||
} from '@/lib/copilot/tools/shared/schemas'
|
} from '@/lib/copilot/tools/shared/schemas'
|
||||||
import { getBlock } from '@/blocks/registry'
|
import { getLatestBlock } from '@/blocks/registry'
|
||||||
|
|
||||||
interface GetBlockOptionsArgs {
|
interface GetBlockOptionsArgs {
|
||||||
blockId: string
|
blockId: string
|
||||||
@@ -43,8 +43,7 @@ export class GetBlockOptionsClientTool extends BaseClientTool {
|
|||||||
(params as any)?.block_id ||
|
(params as any)?.block_id ||
|
||||||
(params as any)?.block_type
|
(params as any)?.block_type
|
||||||
if (typeof blockId === 'string') {
|
if (typeof blockId === 'string') {
|
||||||
// Look up the block config to get the human-readable name
|
const blockConfig = getLatestBlock(blockId)
|
||||||
const blockConfig = getBlock(blockId)
|
|
||||||
const blockName = (blockConfig?.name ?? blockId.replace(/_/g, ' ')).toLowerCase()
|
const blockName = (blockConfig?.name ?? blockId.replace(/_/g, ' ')).toLowerCase()
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
GetBlockConfigResult,
|
GetBlockConfigResult,
|
||||||
type GetBlockConfigResultType,
|
type GetBlockConfigResultType,
|
||||||
} from '@/lib/copilot/tools/shared/schemas'
|
} from '@/lib/copilot/tools/shared/schemas'
|
||||||
import { registry as blockRegistry } from '@/blocks/registry'
|
import { registry as blockRegistry, getLatestBlock } from '@/blocks/registry'
|
||||||
import type { SubBlockConfig } from '@/blocks/types'
|
import type { SubBlockConfig } from '@/blocks/types'
|
||||||
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
|
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
|
||||||
import { PROVIDER_DEFINITIONS } from '@/providers/models'
|
import { PROVIDER_DEFINITIONS } from '@/providers/models'
|
||||||
@@ -452,9 +452,12 @@ export const getBlockConfigServerTool: BaseServerTool<
|
|||||||
const inputs = extractInputsFromSubBlocks(subBlocks, operation, trigger)
|
const inputs = extractInputsFromSubBlocks(subBlocks, operation, trigger)
|
||||||
const outputs = extractOutputs(blockConfig, operation, trigger)
|
const outputs = extractOutputs(blockConfig, operation, trigger)
|
||||||
|
|
||||||
|
const latestBlock = getLatestBlock(blockType)
|
||||||
|
const displayName = latestBlock?.name ?? blockConfig.name
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
blockType,
|
blockType,
|
||||||
blockName: blockConfig.name,
|
blockName: displayName,
|
||||||
operation,
|
operation,
|
||||||
trigger,
|
trigger,
|
||||||
inputs,
|
inputs,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
GetBlockOptionsResult,
|
GetBlockOptionsResult,
|
||||||
type GetBlockOptionsResultType,
|
type GetBlockOptionsResultType,
|
||||||
} from '@/lib/copilot/tools/shared/schemas'
|
} from '@/lib/copilot/tools/shared/schemas'
|
||||||
import { registry as blockRegistry } from '@/blocks/registry'
|
import { registry as blockRegistry, getLatestBlock } from '@/blocks/registry'
|
||||||
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
|
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
|
||||||
import { tools as toolsRegistry } from '@/tools/registry'
|
import { tools as toolsRegistry } from '@/tools/registry'
|
||||||
|
|
||||||
@@ -113,9 +113,12 @@ export const getBlockOptionsServerTool: BaseServerTool<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const latestBlock = getLatestBlock(blockId)
|
||||||
|
const displayName = latestBlock?.name ?? blockConfig.name
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
blockId,
|
blockId,
|
||||||
blockName: blockConfig.name,
|
blockName: displayName,
|
||||||
operations,
|
operations,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { WorkflowState } from '@/stores/workflows/workflow/types'
|
import type { BlockState, WorkflowState } from '@/stores/workflows/workflow/types'
|
||||||
import { SYSTEM_SUBBLOCK_IDS, TRIGGER_RUNTIME_SUBBLOCK_IDS } from '@/triggers/constants'
|
import { SYSTEM_SUBBLOCK_IDS, TRIGGER_RUNTIME_SUBBLOCK_IDS } from '@/triggers/constants'
|
||||||
import {
|
import {
|
||||||
normalizedStringify,
|
normalizedStringify,
|
||||||
@@ -13,6 +13,20 @@ import {
|
|||||||
sortEdges,
|
sortEdges,
|
||||||
} from './normalize'
|
} from './normalize'
|
||||||
|
|
||||||
|
/** Block with optional diff markers added by copilot */
|
||||||
|
type BlockWithDiffMarkers = BlockState & {
|
||||||
|
is_diff?: string
|
||||||
|
field_diffs?: Record<string, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SubBlock with optional diff marker */
|
||||||
|
type SubBlockWithDiffMarker = {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
value: unknown
|
||||||
|
is_diff?: string
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the current workflow state with the deployed state to detect meaningful changes
|
* Compare the current workflow state with the deployed state to detect meaningful changes
|
||||||
* @param currentState - The current workflow state
|
* @param currentState - The current workflow state
|
||||||
@@ -63,21 +77,32 @@ export function hasWorkflowChanged(
|
|||||||
// - subBlocks: handled separately below
|
// - subBlocks: handled separately below
|
||||||
// - layout: contains measuredWidth/measuredHeight from autolayout
|
// - layout: contains measuredWidth/measuredHeight from autolayout
|
||||||
// - height: block height measurement from autolayout
|
// - height: block height measurement from autolayout
|
||||||
|
// - outputs: derived from subBlocks (e.g., inputFormat), already compared via subBlocks
|
||||||
|
// - is_diff, field_diffs: diff markers from copilot edits
|
||||||
|
const currentBlockWithDiff = currentBlock as BlockWithDiffMarkers
|
||||||
|
const deployedBlockWithDiff = deployedBlock as BlockWithDiffMarkers
|
||||||
|
|
||||||
const {
|
const {
|
||||||
position: _currentPos,
|
position: _currentPos,
|
||||||
subBlocks: currentSubBlocks = {},
|
subBlocks: currentSubBlocks = {},
|
||||||
layout: _currentLayout,
|
layout: _currentLayout,
|
||||||
height: _currentHeight,
|
height: _currentHeight,
|
||||||
|
outputs: _currentOutputs,
|
||||||
|
is_diff: _currentIsDiff,
|
||||||
|
field_diffs: _currentFieldDiffs,
|
||||||
...currentRest
|
...currentRest
|
||||||
} = currentBlock
|
} = currentBlockWithDiff
|
||||||
|
|
||||||
const {
|
const {
|
||||||
position: _deployedPos,
|
position: _deployedPos,
|
||||||
subBlocks: deployedSubBlocks = {},
|
subBlocks: deployedSubBlocks = {},
|
||||||
layout: _deployedLayout,
|
layout: _deployedLayout,
|
||||||
height: _deployedHeight,
|
height: _deployedHeight,
|
||||||
|
outputs: _deployedOutputs,
|
||||||
|
is_diff: _deployedIsDiff,
|
||||||
|
field_diffs: _deployedFieldDiffs,
|
||||||
...deployedRest
|
...deployedRest
|
||||||
} = deployedBlock
|
} = deployedBlockWithDiff
|
||||||
|
|
||||||
// Also exclude width/height from data object (container dimensions from autolayout)
|
// Also exclude width/height from data object (container dimensions from autolayout)
|
||||||
const {
|
const {
|
||||||
@@ -156,14 +181,13 @@ export function hasWorkflowChanged(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare type and other properties
|
// Compare type and other properties (excluding diff markers and value)
|
||||||
const currentSubBlockWithoutValue = { ...currentSubBlocks[subBlockId], value: undefined }
|
const currentSubBlockWithDiff = currentSubBlocks[subBlockId] as SubBlockWithDiffMarker
|
||||||
const deployedSubBlockWithoutValue = { ...deployedSubBlocks[subBlockId], value: undefined }
|
const deployedSubBlockWithDiff = deployedSubBlocks[subBlockId] as SubBlockWithDiffMarker
|
||||||
|
const { value: _cv, is_diff: _cd, ...currentSubBlockRest } = currentSubBlockWithDiff
|
||||||
|
const { value: _dv, is_diff: _dd, ...deployedSubBlockRest } = deployedSubBlockWithDiff
|
||||||
|
|
||||||
if (
|
if (normalizedStringify(currentSubBlockRest) !== normalizedStringify(deployedSubBlockRest)) {
|
||||||
normalizedStringify(currentSubBlockWithoutValue) !==
|
|
||||||
normalizedStringify(deployedSubBlockWithoutValue)
|
|
||||||
) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user