Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@
"value-name": "Value Name",
"missing-value-name": "Missing value name",
"check-only-number": "Only numbers can be entered",
"invalid-json": "Invalid JSON format",
"json-value-placeholder": "Enter JSON value, e.g. {\"key\": \"value\"}",
"add-form-list-btn": "Add keyword argument"
}
},
Expand Down
2 changes: 2 additions & 0 deletions packages/client/src/i18n/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@
"value-name": "值名称",
"missing-value-name": "缺少值名称",
"check-only-number": "只能输入数字",
"invalid-json": "无效的 JSON 格式",
"json-value-placeholder": "输入 JSON 格式的值,例如 {\"key\": \"value\"}",
"add-form-list-btn": "添加关键字参数"
}
},
Expand Down
199 changes: 137 additions & 62 deletions packages/client/src/pages/FridayPage/SettingPage/KwargsFormList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { MinusCircleIcon, PlusCircleIcon } from 'lucide-react';
import { Button } from '@/components/ui/button.tsx';
import { inputTypeOptions, booleanOptions } from '../config';

const { TextArea } = Input;

const KwargsFormList = ({ name }: { name: string }) => {
const { t } = useTranslation();
const form = Form.useFormInstance();
Expand Down Expand Up @@ -115,69 +117,142 @@ const KwargsFormList = ({ name }: { name: string }) => {
{...restField}
name={[fieldName, 'value']}
className="flex-1 min-w-0"
validateTrigger={
isNewlyAdded
? ['onSubmit']
: ['onBlur', 'onChange']
}
rules={
getFieldValue([
name,
fieldName,
'type',
]) === 'number'
? [
{
pattern:
/^-?\d+(\.\d+)?$/,
required: true,
whitespace: true,
message: t(
'help.friday.check-only-number',
),
},
]
: [
{
required: true,
whitespace: true,
message: t(
'help.friday.missing-value-name',
),
},
]
}
validateTrigger={[
'onBlur',
'onChange',
]}
rules={(() => {
const fieldType =
getFieldValue([
name,
fieldName,
'type',
]);
if (
fieldType === 'number'
) {
return [
{
pattern:
/^-?\d+(\.\d+)?$/,
required: true,
whitespace: true,
message: t(
'help.friday.check-only-number',
),
},
];
} else if (
fieldType === 'json'
) {
return [
{
required: true,
whitespace: true,
message: t(
'help.friday.missing-value-name',
),
},
{
validator:
async (
_,
value,
) => {
if (
!value
)
return;
try {
JSON.parse(
value,
);
} catch {
throw new Error(
t(
'help.friday.invalid-json',
),
);
}
},
},
];
} else {
return [
{
required: true,
whitespace: true,
message: t(
'help.friday.missing-value-name',
),
},
];
}
})()}
>
{getFieldValue([
name,
fieldName,
'type',
]) === 'boolean' ? (
<Select
placeholder={t(
'help.friday.value-name',
)}
className="w-full"
options={booleanOptions}
onFocus={() => {
newlyAddedRef.current.delete(
fieldName,
);
}}
/>
) : (
<Input
placeholder={t(
'help.friday.value-name',
)}
className="w-full"
onFocus={() => {
newlyAddedRef.current.delete(
fieldName,
);
}}
/>
)}
{(() => {
const fieldType =
getFieldValue([
name,
fieldName,
'type',
]);
if (
fieldType === 'boolean'
) {
return (
<Select
placeholder={t(
'help.friday.value-name',
)}
className="w-full"
options={
booleanOptions
}
onFocus={() => {
newlyAddedRef.current.delete(
fieldName,
);
}}
/>
);
} else if (
fieldType === 'json'
) {
return (
<TextArea
placeholder={t(
'help.friday.json-value-placeholder',
)}
className="w-full font-mono text-xs"
rows={4}
autoSize={{
minRows: 4,
maxRows: 8,
}}
onFocus={() => {
newlyAddedRef.current.delete(
fieldName,
);
}}
/>
);
} else {
return (
<Input
placeholder={t(
'help.friday.value-name',
)}
className="w-full"
onFocus={() => {
newlyAddedRef.current.delete(
fieldName,
);
}}
/>
);
}
})()}
</Form.Item>

<Button
Expand Down
15 changes: 13 additions & 2 deletions packages/client/src/pages/FridayPage/SettingPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface KwargsFormItem {
}

// Backend format for kwargs
type KwargsBackendItem = { [key: string]: string | number | boolean };
type KwargsBackendItem = { [key: string]: string | number | boolean | object };

// Convert kwargs from form format [{type, key, value}] to backend format {key1: value1, key2: value2}
const convertKwargsToBackendFormat = (
Expand All @@ -33,12 +33,20 @@ const convertKwargsToBackendFormat = (
const result: KwargsBackendItem = {};
kwargs.forEach((item) => {
if (!item.key) return; // Skip items without key
let convertedValue: string | number | boolean = item.value;
let convertedValue: string | number | boolean | object = item.value;
// Convert value based on type
if (item.type === 'number') {
convertedValue = Number(item.value);
} else if (item.type === 'boolean') {
convertedValue = item.value === 'true';
} else if (item.type === 'json') {
try {
convertedValue = JSON.parse(item.value);
} catch (e) {
// If JSON parsing fails, keep as string
console.error(`Failed to parse JSON for key "${item.key}":`, e);
convertedValue = item.value;
}
}
result[item.key] = convertedValue;
});
Expand All @@ -62,6 +70,9 @@ const convertKwargsFromBackendFormat = (
} else if (typeof value === 'number') {
type = 'number';
stringValue = String(value);
} else if (typeof value === 'object' && value !== null) {
type = 'json';
stringValue = JSON.stringify(value, null, 2);
} else if (value === 'true' || value === 'false') {
type = 'boolean';
} else if (/^[0-9]+$/.test(String(value))) {
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/pages/FridayPage/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const inputTypeOptions: InputTypeOption[] = [
{ label: 'string', value: 'string' },
{ label: 'number', value: 'number' },
{ label: 'bool', value: 'boolean' },
{ label: 'json', value: 'json' },
];

export const llmProviderOptions: LlmProviderOption[] = [
Expand Down
Loading