diff --git a/config/routes.ts b/config/routes.ts index b866133f..51be9567 100644 --- a/config/routes.ts +++ b/config/routes.ts @@ -73,18 +73,18 @@ export default [ selectedIcon: 'icon-audio-filled', defaultIcon: 'icon-audio1', component: './playground/speech/index' + }, + { + name: 'video', + title: 'Video', + path: '/playground/video', + key: 'video', + icon: 'icon-video-outline', + hideInMenu: false, + selectedIcon: 'icon-video-filled02', + defaultIcon: 'icon-video-outline', + component: './playground/video' } - // { - // name: 'video', - // title: 'Video', - // path: '/playground/video', - // key: 'video', - // icon: 'icon-video-outline', - // hideInMenu: false, - // selectedIcon: 'icon-video-filled02', - // defaultIcon: 'icon-video-outline', - // component: './playground/video' - // } ] }, { diff --git a/src/components/list-input/index.tsx b/src/components/list-input/index.tsx index 862c3fde..677121c7 100644 --- a/src/components/list-input/index.tsx +++ b/src/components/list-input/index.tsx @@ -1,3 +1,4 @@ +import { parseParamsString } from '@/utils'; import _ from 'lodash'; import React, { useEffect } from 'react'; import Wrapper from '../label-selector/wrapper'; @@ -83,10 +84,7 @@ const ListInput: React.FC = (props) => { const pastedText = e.clipboardData?.getData('text'); if (!pastedText) return; - const lines = pastedText.split(/\r?\n/).filter((line: string) => { - const trimmedLine = trim ? line.trim() : line; - return trimmedLine.length > 0; - }); + const lines = parseParamsString(pastedText); if (lines.length <= 1) { // if there's only one line, let the default paste behavior handle it diff --git a/src/pages/llmodels/forms/backend.tsx b/src/pages/llmodels/forms/backend.tsx index d6649dbc..9953ff33 100644 --- a/src/pages/llmodels/forms/backend.tsx +++ b/src/pages/llmodels/forms/backend.tsx @@ -43,6 +43,11 @@ const BackendFields: React.FC = () => { useCompareEnvs(); const handleBackendVersionOnChange = (value: any, option: any) => { + // const oldEnvs = _.get(initialValues, 'env') || {}; + // const newEnvs = option.data?.env || {}; + + // handleCompareEnvs(oldEnvs, newEnvs); + if (Object.keys(option.data?.env || {}).length > 0) { form.setFieldValue('env', { ...(option?.data?.env || {}) }); } diff --git a/src/pages/llmodels/hooks/use-compare-envs.ts b/src/pages/llmodels/hooks/use-compare-envs.ts index 3679d051..eee565bd 100644 --- a/src/pages/llmodels/hooks/use-compare-envs.ts +++ b/src/pages/llmodels/hooks/use-compare-envs.ts @@ -24,13 +24,14 @@ export default function useCompareEnvs() { new: {} as Record }; - Object.keys(oldEnvs).forEach((key) => { + Object.keys(oldEnvs || {}).forEach((key) => { if (key in newEnvs && oldEnvs[key] !== newEnvs[key]) { result.old[key] = oldEnvs[key]; result.new[key] = newEnvs[key]; } }); + console.log('compare result:', oldEnvs, newEnvs, result); setDiffEnvs(result); if (Object.keys(result.old).length > 0) { handleOpenTips(); diff --git a/src/pages/playground/video/page.tsx b/src/pages/playground/video/page.tsx index 82e994db..87b5c3f3 100644 --- a/src/pages/playground/video/page.tsx +++ b/src/pages/playground/video/page.tsx @@ -98,7 +98,7 @@ const GroundVideo: React.FC = forwardRef((props, ref) => { const finalParameters = useMemo(() => { if (parameters.size === 'custom') { return { - ..._.omit(parameters, ['width', 'height', 'random_seed', 'seed']), + ..._.omit(parameters, ['width', 'height']), size: parameters.width && parameters.height ? `${parameters.width}x${parameters.height}` @@ -106,7 +106,7 @@ const GroundVideo: React.FC = forwardRef((props, ref) => { }; } return { - ..._.omit(parameters, ['width', 'height', 'random_seed', 'seed']) + ..._.omit(parameters, ['width', 'height']) }; }, [parameters]); diff --git a/src/utils/index.ts b/src/utils/index.ts index 5c31ed5e..b938a2d5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -263,3 +263,102 @@ export const genColors = ({ base.setAlpha(alpha_end).toRgbString() ]; }; + +/** + * Parse a command-line parameter string into an array format. + * @param paramsString - The parameter string to parse (supports multiline). + * @returns An array of parameters, e.g. ['--param=value', '--flag'] + * + * @example + * parseParamsString('--foo=bar --baz 123 --flag') + * // Returns: ['--foo=bar', '--baz=123', '--flag'] + * + * parseParamsString(`--foo bar + * --baz=123`) + * // Returns: ['--foo=bar', '--baz=123'] + */ +export const parseParamsString = (paramsString: string): string[] => { + if (!paramsString || !paramsString.trim()) { + return []; + } + + // Convert multiline to single line, replace newlines with spaces + const normalizedString = paramsString + .replace(/\n/g, ' ') + .replace(/\s+/g, ' ') + .trim(); + + const result: string[] = []; + const tokens: string[] = []; + let current = ''; + let inQuote = false; + let quoteChar = ''; + let braceDepth = 0; // Curly brace depth + + // Tokenize, handle quotes and curly braces + for (let i = 0; i < normalizedString.length; i++) { + const char = normalizedString[i]; + + if ( + (char === '"' || char === "'") && + (i === 0 || normalizedString[i - 1] !== '\\') + ) { + if (!inQuote) { + inQuote = true; + quoteChar = char; + current += char; + } else if (char === quoteChar) { + inQuote = false; + quoteChar = ''; + current += char; + } else { + current += char; + } + } else if (char === '{' && !inQuote) { + braceDepth++; + current += char; + } else if (char === '}' && !inQuote) { + braceDepth--; + current += char; + } else if (char === ' ' && !inQuote && braceDepth === 0) { + if (current) { + tokens.push(current); + current = ''; + } + } else { + current += char; + } + } + + if (current) { + tokens.push(current); + } + + // Parse tokens into parameter array + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + + // Check if already contains '=' with value + if (token.includes('=')) { + result.push(token); + } else if (token.startsWith('-')) { + // Check if next token is a value (does not start with '-') + const nextToken = tokens[i + 1]; + if (nextToken && !nextToken.startsWith('-')) { + // If value is quoted, keep space format + if (nextToken.startsWith('"') || nextToken.startsWith("'")) { + result.push(`${token} ${nextToken}`); + } else { + // Otherwise, use '=' to join + result.push(`${token}=${nextToken}`); + } + i++; // Skip next token, already consumed + } else { + // This is a flag without value + result.push(token); + } + } + } + + return result; +};