diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx
index 06b0b586ba8..25324d61f91 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx
@@ -15,9 +15,10 @@ import {
Input,
Label,
languages,
+ Tooltip,
} from '@sim/emcn'
import { Trash } from '@sim/emcn/icons'
-import { Plus } from 'lucide-react'
+import { ArrowLeftRight, Plus } from 'lucide-react'
import Editor from 'react-simple-code-editor'
import {
createDefaultInputFormatField,
@@ -141,6 +142,59 @@ export function FieldFormat({
const renderFieldLabel = (label: string) =>
+ /**
+ * Resolves the current editor mode for a file field. The uploader is only
+ * offered when it can represent the stored value losslessly (empty or all
+ * run-ready); mixed/legacy values force JSON mode so the uploader can't drop
+ * entries it cannot show on save.
+ */
+ const getFileFieldMode = (field: Field): { mode: 'upload' | 'json'; canUseUploader: boolean } => {
+ const canUseUploader = defaultFileFieldMode(field.value) === 'upload'
+ return {
+ mode: canUseUploader ? (fileFieldModes[field.id] ?? 'upload') : 'json',
+ canUseUploader,
+ }
+ }
+
+ /**
+ * Renders the ⇄ toggle that switches a file field between the uploader and the
+ * raw JSON editor. Matches the canonical sub-block mode toggle. Hidden when the
+ * value can't be safely represented by the uploader.
+ */
+ const renderFileModeToggle = (field: Field) => {
+ const { mode, canUseUploader } = getFileFieldMode(field)
+ if (!canUseUploader) return null
+ const label = mode === 'upload' ? 'Switch to JSON' : 'Switch to file uploader'
+ return (
+
+
+
+
+
+
{label}
+
+
+ )
+ }
+
/**
* Adds a new field to the list
*/
@@ -493,52 +547,28 @@ export function FieldFormat({
}
if (isFileFieldType(field.type)) {
- // The uploader is only offered when it can represent the stored value
- // losslessly (empty or all run-ready). For mixed/legacy values it would
- // drop the entries it can't show on save, so we force JSON mode and hide
- // the toggle until the value is cleared or made fully run-ready.
- const canUseUploader = defaultFileFieldMode(field.value) === 'upload'
- const mode = canUseUploader ? (fileFieldModes[field.id] ?? 'upload') : 'json'
-
- const modeToggle = canUseUploader ? (
-
-
-
- ) : null
+ // The mode toggle lives on the "Value" label row (see the field header);
+ // this only renders the active control. Mode derivation is shared via
+ // getFileFieldMode so the two stay in sync.
+ const { mode } = getFileFieldMode(field)
if (mode === 'upload') {
const currentFiles = parseInputFormatFiles(field.value)
return (
-