This commit is contained in:
2025-12-01 17:21:38 +08:00
parent 32fee2b8ab
commit fab8c13cb3
7511 changed files with 996300 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
import type { Meta, StoryObj } from '@storybook/nextjs'
import { useState } from 'react'
import ParamItem from '.'
type ParamConfig = {
id: string
name: string
tip: string
value: number
min: number
max: number
step: number
allowToggle?: boolean
}
const PARAMS: ParamConfig[] = [
{
id: 'temperature',
name: 'Temperature',
tip: 'Controls randomness. Lower values make the model more deterministic, higher values encourage creativity.',
value: 0.7,
min: 0,
max: 2,
step: 0.1,
allowToggle: true,
},
{
id: 'top_p',
name: 'Top P',
tip: 'Nucleus sampling keeps only the most probable tokens whose cumulative probability exceeds this threshold.',
value: 0.9,
min: 0,
max: 1,
step: 0.05,
},
{
id: 'frequency_penalty',
name: 'Frequency Penalty',
tip: 'Discourages repeating tokens. Increase to reduce repetition.',
value: 0.2,
min: 0,
max: 1,
step: 0.05,
},
]
const ParamItemPlayground = () => {
const [state, setState] = useState<Record<string, { value: number; enabled: boolean }>>(() => {
return PARAMS.reduce((acc, item) => {
acc[item.id] = { value: item.value, enabled: true }
return acc
}, {} as Record<string, { value: number; enabled: boolean }>)
})
const handleChange = (id: string, value: number) => {
setState(prev => ({
...prev,
[id]: {
...prev[id],
value: Number.parseFloat(value.toFixed(3)),
},
}))
}
const handleToggle = (id: string, enabled: boolean) => {
setState(prev => ({
...prev,
[id]: {
...prev[id],
enabled,
},
}))
}
return (
<div className="flex w-full max-w-2xl flex-col gap-5 rounded-2xl border border-divider-subtle bg-components-panel-bg p-6">
<div className="flex items-center justify-between text-xs uppercase tracking-[0.18em] text-text-tertiary">
<span>Generation parameters</span>
<code className="rounded-md border border-divider-subtle bg-background-default px-2 py-1 text-[11px] text-text-tertiary">
{JSON.stringify(state, null, 0)}
</code>
</div>
{PARAMS.map(param => (
<ParamItem
key={param.id}
className="rounded-xl border border-transparent px-3 py-2 hover:border-divider-subtle hover:bg-background-default-subtle"
id={param.id}
name={param.name}
tip={param.tip}
value={state[param.id].value}
enable={state[param.id].enabled}
min={param.min}
max={param.max}
step={param.step}
hasSwitch={param.allowToggle}
onChange={handleChange}
onSwitchChange={handleToggle}
/>
))}
</div>
)
}
const meta = {
title: 'Base/Data Entry/ParamItem',
component: ParamItemPlayground,
parameters: {
layout: 'centered',
docs: {
description: {
component: 'Slider + numeric input pairing used for model parameter tuning. Supports optional enable toggles per parameter.',
},
},
},
tags: ['autodocs'],
} satisfies Meta<typeof ParamItemPlayground>
export default meta
type Story = StoryObj<typeof meta>
export const Playground: Story = {}

View File

@@ -0,0 +1,79 @@
'use client'
import type { FC } from 'react'
import { InputNumber } from '../input-number'
import Tooltip from '@/app/components/base/tooltip'
import Slider from '@/app/components/base/slider'
import Switch from '@/app/components/base/switch'
type Props = {
className?: string
id: string
name: string
noTooltip?: boolean
tip?: string
value: number
enable: boolean
step?: number
min?: number
max: number
onChange: (key: string, value: number) => void
hasSwitch?: boolean
onSwitchChange?: (key: string, enable: boolean) => void
}
const ParamItem: FC<Props> = ({ className, id, name, noTooltip, tip, step = 0.1, min = 0, max, value, enable, onChange, hasSwitch, onSwitchChange }) => {
return (
<div className={className}>
<div className='flex items-center justify-between'>
<div className='flex h-6 items-center'>
{hasSwitch && (
<Switch
size='md'
className='mr-2'
defaultValue={enable}
onChange={async (val) => {
onSwitchChange?.(id, val)
}}
/>
)}
<span className='system-sm-semibold mr-1 text-text-secondary'>{name}</span>
{!noTooltip && (
<Tooltip
triggerClassName='w-4 h-4 shrink-0'
popupContent={<div className='w-[200px]'>{tip}</div>}
/>
)}
</div>
</div>
<div className='mt-1 flex items-center'>
<div className='mr-3 flex shrink-0 items-center'>
<InputNumber
disabled={!enable}
type='number'
min={min}
max={max}
step={step}
amount={step}
size='regular'
value={value}
onChange={(value) => {
onChange(id, value)
}}
className='w-[72px]'
/>
</div>
<div className='flex grow items-center'>
<Slider
className='w-full'
disabled={!enable}
value={max < 5 ? value * 100 : value}
min={min < 1 ? min * 100 : min}
max={max < 5 ? max * 100 : max}
onChange={value => onChange(id, value / (max < 5 ? 100 : 1))}
/>
</div>
</div>
</div>
)
}
export default ParamItem

View File

@@ -0,0 +1,53 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import ParamItem from '.'
type Props = {
className?: string
value: number
onChange: (key: string, value: number) => void
enable: boolean
hasSwitch?: boolean
onSwitchChange?: (key: string, enable: boolean) => void
}
const VALUE_LIMIT = {
default: 0.7,
step: 0.01,
min: 0,
max: 1,
}
const ScoreThresholdItem: FC<Props> = ({
className,
value,
enable,
onChange,
hasSwitch,
onSwitchChange,
}) => {
const { t } = useTranslation()
const handleParamChange = (key: string, value: number) => {
let notOutRangeValue = Number.parseFloat(value.toFixed(2))
notOutRangeValue = Math.max(VALUE_LIMIT.min, notOutRangeValue)
notOutRangeValue = Math.min(VALUE_LIMIT.max, notOutRangeValue)
onChange(key, notOutRangeValue)
}
return (
<ParamItem
className={className}
id='score_threshold'
name={t('appDebug.datasetConfig.score_threshold')}
tip={t('appDebug.datasetConfig.score_thresholdTip') as string}
{...VALUE_LIMIT}
value={value}
enable={enable}
onChange={handleParamChange}
hasSwitch={hasSwitch}
onSwitchChange={onSwitchChange}
/>
)
}
export default React.memo(ScoreThresholdItem)

View File

@@ -0,0 +1,53 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import ParamItem from '.'
type Props = {
className?: string
value: number
onChange: (key: string, value: number) => void
enable: boolean
}
const maxTopK = (() => {
const configValue = Number.parseInt(globalThis.document?.body?.getAttribute('data-public-top-k-max-value') || '', 10)
if (configValue && !isNaN(configValue))
return configValue
return 10
})()
const VALUE_LIMIT = {
default: 2,
step: 1,
min: 1,
max: maxTopK,
}
const TopKItem: FC<Props> = ({
className,
value,
enable,
onChange,
}) => {
const { t } = useTranslation()
const handleParamChange = (key: string, value: number) => {
let notOutRangeValue = Number.parseInt(value.toFixed(0))
notOutRangeValue = Math.max(VALUE_LIMIT.min, notOutRangeValue)
notOutRangeValue = Math.min(VALUE_LIMIT.max, notOutRangeValue)
onChange(key, notOutRangeValue)
}
return (
<ParamItem
className={className}
id='top_k'
name={t('appDebug.datasetConfig.top_k')}
tip={t('appDebug.datasetConfig.top_kTip') as string}
{...VALUE_LIMIT}
value={value}
enable={enable}
onChange={handleParamChange}
/>
)
}
export default React.memo(TopKItem)