From f116001b1dbda9cc5a4084b448819945f19f6eeb Mon Sep 17 00:00:00 2001 From: balibabu Date: Mon, 3 Aug 2026 17:52:53 +0800 Subject: [PATCH] Fix: The agent version page exported an incorrect DSL format. (#17736) --- web/src/pages/agent/hooks/use-export-json.ts | 17 +++++----------- .../clear-sensitive-fields.test.ts} | 0 .../clear-sensitive-fields.ts | 0 web/src/pages/agent/utils/download-dsl.ts | 20 +++++++++++++++++++ web/src/pages/agent/version-dialog/index.tsx | 9 ++++----- 5 files changed, 29 insertions(+), 17 deletions(-) rename web/src/pages/agent/{hooks/use-export-json.test.ts => utils/clear-sensitive-fields.test.ts} (100%) rename web/src/pages/agent/{hooks => utils}/clear-sensitive-fields.ts (100%) create mode 100644 web/src/pages/agent/utils/download-dsl.ts diff --git a/web/src/pages/agent/hooks/use-export-json.ts b/web/src/pages/agent/hooks/use-export-json.ts index 9f2e312159..ca1f3080bd 100644 --- a/web/src/pages/agent/hooks/use-export-json.ts +++ b/web/src/pages/agent/hooks/use-export-json.ts @@ -1,26 +1,19 @@ import { useFetchAgent } from '@/hooks/use-agent-request'; -import { downloadJsonFile } from '@/utils/file-util'; import { useCallback } from 'react'; import useGraphStore from '../store'; +import { downloadDsl } from '../utils/download-dsl'; import { exportDsl } from '../utils/dsl-bridge'; -import { clearSensitiveFields } from './clear-sensitive-fields'; export const useHandleExportJsonFile = () => { const { data } = useFetchAgent(); const { nodes, edges } = useGraphStore((state) => state); const handleExportJson = useCallback(() => { - // bridge.exportDsl returns the canonical wire shape from current - // graph state plus preserved DSL fields, so export can write it - // directly after sensitive-field sanitization. + // exportDsl returns the canonical wire shape from current graph + // state plus preserved DSL fields; downloadDsl sanitizes + // sensitive fields and writes the file. const full = exportDsl(nodes, edges, data?.dsl ?? {}); - const sanitizedDsl = clearSensitiveFields(full); - const nextDsl = { - ...sanitizedDsl, - globals: { ...(sanitizedDsl.globals ?? {}) }, - }; - - downloadJsonFile(nextDsl, `${data.title}.json`); + downloadDsl(full, data.title); }, [nodes, edges, data?.dsl, data.title]); return { diff --git a/web/src/pages/agent/hooks/use-export-json.test.ts b/web/src/pages/agent/utils/clear-sensitive-fields.test.ts similarity index 100% rename from web/src/pages/agent/hooks/use-export-json.test.ts rename to web/src/pages/agent/utils/clear-sensitive-fields.test.ts diff --git a/web/src/pages/agent/hooks/clear-sensitive-fields.ts b/web/src/pages/agent/utils/clear-sensitive-fields.ts similarity index 100% rename from web/src/pages/agent/hooks/clear-sensitive-fields.ts rename to web/src/pages/agent/utils/clear-sensitive-fields.ts diff --git a/web/src/pages/agent/utils/download-dsl.ts b/web/src/pages/agent/utils/download-dsl.ts new file mode 100644 index 0000000000..62afaf8b1f --- /dev/null +++ b/web/src/pages/agent/utils/download-dsl.ts @@ -0,0 +1,20 @@ +import { DSL } from '@/interfaces/database/agent'; +import { downloadJsonFile } from '@/utils/file-util'; +import { clearSensitiveFields } from './clear-sensitive-fields'; + +/** + * Shared agent-DSL download path: strips sensitive fields (api_key) + * and writes the canonical wire shape to `.json`. Used by the + * canvas export button and the version-history dialog so both emit + * the same structure. + */ +export const downloadDsl = ( + dsl: DSL | Record<string, any>, + title: string, +) => { + const sanitizedDsl = clearSensitiveFields(dsl); + downloadJsonFile( + { ...sanitizedDsl, globals: { ...(sanitizedDsl.globals ?? {}) } }, + `${title}.json`, + ); +}; diff --git a/web/src/pages/agent/version-dialog/index.tsx b/web/src/pages/agent/version-dialog/index.tsx index c4d4b4ad49..ef97e895a8 100644 --- a/web/src/pages/agent/version-dialog/index.tsx +++ b/web/src/pages/agent/version-dialog/index.tsx @@ -19,12 +19,12 @@ import { import { IModalProps } from '@/interfaces/common'; import { cn } from '@/lib/utils'; import { formatDate } from '@/utils/date'; -import { downloadJsonFile } from '@/utils/file-util'; import { ConnectionMode, ReactFlow, ReactFlowProvider } from '@xyflow/react'; import { ArrowDownToLine } from 'lucide-react'; import { ReactNode, useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { nodeTypes } from '../canvas'; +import { downloadDsl } from '../utils/download-dsl'; function Dot() { return ( @@ -51,11 +51,10 @@ export function VersionDialog({ ); const downloadFile = useCallback(() => { - const graph = agent?.dsl.graph; - if (graph) { - downloadJsonFile(graph, agent?.title); + if (agent?.dsl) { + downloadDsl(agent.dsl, agent.title); } - }, [agent?.dsl.graph, agent?.title]); + }, [agent?.dsl, agent?.title]); useEffect(() => { if (data.length > 0) {