| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- import React from 'react';
- import {
- Input,
- Slider,
- Typography,
- Button,
- Tag,
- } from '@douyinfe/semi-ui';
- import {
- Hash,
- Thermometer,
- Target,
- Repeat,
- Ban,
- Shuffle,
- Check,
- X,
- } from 'lucide-react';
- const ParameterControl = ({
- inputs,
- parameterEnabled,
- onInputChange,
- onParameterToggle,
- }) => {
- return (
- <>
- {/* Temperature */}
- <div className={`transition-opacity duration-200 ${!parameterEnabled.temperature ? 'opacity-50' : ''}`}>
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center gap-2">
- <Thermometer size={16} className="text-gray-500" />
- <Typography.Text strong className="text-sm">
- Temperature
- </Typography.Text>
- <Tag size="small" className="!rounded-full">
- {inputs.temperature}
- </Tag>
- </div>
- <Button
- theme={parameterEnabled.temperature ? 'solid' : 'borderless'}
- type={parameterEnabled.temperature ? 'primary' : 'tertiary'}
- size="small"
- icon={parameterEnabled.temperature ? <Check size={10} /> : <X size={10} />}
- onClick={() => onParameterToggle('temperature')}
- className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
- />
- </div>
- <Typography.Text className="text-xs text-gray-500 mb-2">
- 控制输出的随机性和创造性
- </Typography.Text>
- <Slider
- step={0.1}
- min={0.1}
- max={1}
- value={inputs.temperature}
- onChange={(value) => onInputChange('temperature', value)}
- className="mt-2"
- disabled={!parameterEnabled.temperature}
- />
- </div>
- {/* Top P */}
- <div className={`transition-opacity duration-200 ${!parameterEnabled.top_p ? 'opacity-50' : ''}`}>
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center gap-2">
- <Target size={16} className="text-gray-500" />
- <Typography.Text strong className="text-sm">
- Top P
- </Typography.Text>
- <Tag size="small" className="!rounded-full">
- {inputs.top_p}
- </Tag>
- </div>
- <Button
- theme={parameterEnabled.top_p ? 'solid' : 'borderless'}
- type={parameterEnabled.top_p ? 'primary' : 'tertiary'}
- size="small"
- icon={parameterEnabled.top_p ? <Check size={10} /> : <X size={10} />}
- onClick={() => onParameterToggle('top_p')}
- className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
- />
- </div>
- <Typography.Text className="text-xs text-gray-500 mb-2">
- 核采样,控制词汇选择的多样性
- </Typography.Text>
- <Slider
- step={0.1}
- min={0.1}
- max={1}
- value={inputs.top_p}
- onChange={(value) => onInputChange('top_p', value)}
- className="mt-2"
- disabled={!parameterEnabled.top_p}
- />
- </div>
- {/* Frequency Penalty */}
- <div className={`transition-opacity duration-200 ${!parameterEnabled.frequency_penalty ? 'opacity-50' : ''}`}>
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center gap-2">
- <Repeat size={16} className="text-gray-500" />
- <Typography.Text strong className="text-sm">
- Frequency Penalty
- </Typography.Text>
- <Tag size="small" className="!rounded-full">
- {inputs.frequency_penalty}
- </Tag>
- </div>
- <Button
- theme={parameterEnabled.frequency_penalty ? 'solid' : 'borderless'}
- type={parameterEnabled.frequency_penalty ? 'primary' : 'tertiary'}
- size="small"
- icon={parameterEnabled.frequency_penalty ? <Check size={10} /> : <X size={10} />}
- onClick={() => onParameterToggle('frequency_penalty')}
- className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
- />
- </div>
- <Typography.Text className="text-xs text-gray-500 mb-2">
- 频率惩罚,减少重复词汇的出现
- </Typography.Text>
- <Slider
- step={0.1}
- min={-2}
- max={2}
- value={inputs.frequency_penalty}
- onChange={(value) => onInputChange('frequency_penalty', value)}
- className="mt-2"
- disabled={!parameterEnabled.frequency_penalty}
- />
- </div>
- {/* Presence Penalty */}
- <div className={`transition-opacity duration-200 ${!parameterEnabled.presence_penalty ? 'opacity-50' : ''}`}>
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center gap-2">
- <Ban size={16} className="text-gray-500" />
- <Typography.Text strong className="text-sm">
- Presence Penalty
- </Typography.Text>
- <Tag size="small" className="!rounded-full">
- {inputs.presence_penalty}
- </Tag>
- </div>
- <Button
- theme={parameterEnabled.presence_penalty ? 'solid' : 'borderless'}
- type={parameterEnabled.presence_penalty ? 'primary' : 'tertiary'}
- size="small"
- icon={parameterEnabled.presence_penalty ? <Check size={10} /> : <X size={10} />}
- onClick={() => onParameterToggle('presence_penalty')}
- className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
- />
- </div>
- <Typography.Text className="text-xs text-gray-500 mb-2">
- 存在惩罚,鼓励讨论新话题
- </Typography.Text>
- <Slider
- step={0.1}
- min={-2}
- max={2}
- value={inputs.presence_penalty}
- onChange={(value) => onInputChange('presence_penalty', value)}
- className="mt-2"
- disabled={!parameterEnabled.presence_penalty}
- />
- </div>
- {/* MaxTokens */}
- <div className={`transition-opacity duration-200 ${!parameterEnabled.max_tokens ? 'opacity-50' : ''}`}>
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center gap-2">
- <Hash size={16} className="text-gray-500" />
- <Typography.Text strong className="text-sm">
- Max Tokens
- </Typography.Text>
- </div>
- <Button
- theme={parameterEnabled.max_tokens ? 'solid' : 'borderless'}
- type={parameterEnabled.max_tokens ? 'primary' : 'tertiary'}
- size="small"
- icon={parameterEnabled.max_tokens ? <Check size={10} /> : <X size={10} />}
- onClick={() => onParameterToggle('max_tokens')}
- className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
- />
- </div>
- <Input
- placeholder='MaxTokens'
- name='max_tokens'
- required
- autoComplete='new-password'
- defaultValue={0}
- value={inputs.max_tokens}
- onChange={(value) => onInputChange('max_tokens', value)}
- className="!rounded-lg"
- disabled={!parameterEnabled.max_tokens}
- />
- </div>
- {/* Seed */}
- <div className={`transition-opacity duration-200 ${!parameterEnabled.seed ? 'opacity-50' : ''}`}>
- <div className="flex items-center justify-between mb-2">
- <div className="flex items-center gap-2">
- <Shuffle size={16} className="text-gray-500" />
- <Typography.Text strong className="text-sm">
- Seed
- </Typography.Text>
- <Typography.Text className="text-xs text-gray-400">
- (可选,用于复现结果)
- </Typography.Text>
- </div>
- <Button
- theme={parameterEnabled.seed ? 'solid' : 'borderless'}
- type={parameterEnabled.seed ? 'primary' : 'tertiary'}
- size="small"
- icon={parameterEnabled.seed ? <Check size={10} /> : <X size={10} />}
- onClick={() => onParameterToggle('seed')}
- className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
- />
- </div>
- <Input
- placeholder='随机种子 (留空为随机)'
- name='seed'
- autoComplete='new-password'
- value={inputs.seed || ''}
- onChange={(value) => onInputChange('seed', value === '' ? null : value)}
- className="!rounded-lg"
- disabled={!parameterEnabled.seed}
- />
- </div>
- </>
- );
- };
- export default ParameterControl;
|