@lobehub/lobehub 2.0.0-next.262 → 2.0.0-next.263

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/locales/zh-CN/chat.json +1 -0
  4. package/locales/zh-CN/modelProvider.json +20 -0
  5. package/package.json +1 -1
  6. package/packages/database/src/models/aiModel.ts +2 -0
  7. package/packages/database/src/repositories/aiInfra/index.test.ts +41 -1
  8. package/packages/database/src/repositories/aiInfra/index.ts +3 -1
  9. package/packages/model-runtime/src/providers/openrouter/index.test.ts +9 -55
  10. package/packages/model-runtime/src/providers/openrouter/index.ts +47 -27
  11. package/packages/model-runtime/src/providers/openrouter/type.ts +16 -28
  12. package/packages/model-runtime/src/providers/vercelaigateway/index.test.ts +6 -6
  13. package/packages/model-runtime/src/providers/vercelaigateway/index.ts +54 -11
  14. package/packages/model-runtime/src/utils/modelParse.test.ts +185 -3
  15. package/packages/model-runtime/src/utils/modelParse.ts +108 -1
  16. package/packages/types/src/llm.ts +3 -1
  17. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/ExtendParamsSelect.tsx +398 -0
  18. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +11 -2
  19. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/__tests__/ExtendParamsSelect.test.tsx +59 -0
  20. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +1 -1
  21. package/src/features/ChatInput/ActionBar/Model/GPT51ReasoningEffortSlider.tsx +9 -54
  22. package/src/features/ChatInput/ActionBar/Model/GPT52ProReasoningEffortSlider.tsx +9 -53
  23. package/src/features/ChatInput/ActionBar/Model/GPT52ReasoningEffortSlider.tsx +9 -55
  24. package/src/features/ChatInput/ActionBar/Model/GPT5ReasoningEffortSlider.tsx +9 -54
  25. package/src/features/ChatInput/ActionBar/Model/ImageAspectRatioSelect.tsx +50 -16
  26. package/src/features/ChatInput/ActionBar/Model/ImageResolutionSlider.tsx +7 -53
  27. package/src/features/ChatInput/ActionBar/Model/LevelSlider.tsx +92 -0
  28. package/src/features/ChatInput/ActionBar/Model/ReasoningEffortSlider.tsx +9 -53
  29. package/src/features/ChatInput/ActionBar/Model/TextVerbositySlider.tsx +9 -53
  30. package/src/features/ChatInput/ActionBar/Model/ThinkingLevel2Slider.tsx +9 -52
  31. package/src/features/ChatInput/ActionBar/Model/ThinkingLevelSlider.tsx +9 -54
  32. package/src/features/ChatInput/ActionBar/Model/ThinkingSlider.tsx +20 -56
  33. package/src/features/ChatInput/ActionBar/Model/__tests__/createLevelSlider.test.tsx +126 -0
  34. package/src/features/ChatInput/ActionBar/Model/createLevelSlider.tsx +105 -0
  35. package/src/locales/default/chat.ts +1 -0
  36. package/src/locales/default/modelProvider.ts +38 -0
@@ -1,61 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
4
2
 
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
3
+ const GPT52_REASONING_EFFORT_LEVELS = ['none', 'low', 'medium', 'high', 'xhigh'] as const;
4
+ type GPT52ReasoningEffort = (typeof GPT52_REASONING_EFFORT_LEVELS)[number];
7
5
 
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
6
+ export type GPT52ReasoningEffortSliderProps = CreatedLevelSliderProps<GPT52ReasoningEffort>;
10
7
 
11
- const GPT52ReasoningEffortSlider = memo(() => {
12
- const agentId = useAgentId();
13
- const { updateAgentChatConfig } = useUpdateAgentConfig();
14
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
15
-
16
- const gpt5_2ReasoningEffort = config.gpt5_2ReasoningEffort || 'none';
17
-
18
- const marks = {
19
- 0: 'none',
20
- 1: 'low',
21
- 2: 'medium',
22
- 3: 'high',
23
- 4: 'xhigh',
24
- };
25
-
26
- const effortValues = ['none', 'low', 'medium', 'high', 'xhigh'];
27
- const indexValue = effortValues.indexOf(gpt5_2ReasoningEffort);
28
- const currentValue = indexValue === -1 ? 0 : indexValue;
29
-
30
- const updateGPT52ReasoningEffort = useCallback(
31
- (value: number) => {
32
- const effort = effortValues[value] as 'none' | 'low' | 'medium' | 'high' | 'xhigh';
33
- updateAgentChatConfig({ gpt5_2ReasoningEffort: effort });
34
- },
35
- [updateAgentChatConfig],
36
- );
37
-
38
- return (
39
- <Flexbox
40
- align={'center'}
41
- gap={12}
42
- horizontal
43
- paddingInline={'0 20px'}
44
- style={{ minWidth: 230, width: '100%' }}
45
- >
46
- <Flexbox flex={1}>
47
- <Slider
48
- marks={marks}
49
- max={4}
50
- min={0}
51
- onChange={updateGPT52ReasoningEffort}
52
- step={1}
53
- tooltip={{ open: false }}
54
- value={currentValue}
55
- />
56
- </Flexbox>
57
- </Flexbox>
58
- );
8
+ const GPT52ReasoningEffortSlider = createLevelSliderComponent<GPT52ReasoningEffort>({
9
+ configKey: 'gpt5_2ReasoningEffort',
10
+ defaultValue: 'none',
11
+ levels: GPT52_REASONING_EFFORT_LEVELS,
12
+ style: { minWidth: 230 },
59
13
  });
60
14
 
61
15
  export default GPT52ReasoningEffortSlider;
@@ -1,60 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
4
2
 
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
3
+ const GPT5_REASONING_EFFORT_LEVELS = ['minimal', 'low', 'medium', 'high'] as const;
4
+ type GPT5ReasoningEffort = (typeof GPT5_REASONING_EFFORT_LEVELS)[number];
7
5
 
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
6
+ export type GPT5ReasoningEffortSliderProps = CreatedLevelSliderProps<GPT5ReasoningEffort>;
10
7
 
11
- const GPT5ReasoningEffortSlider = memo(() => {
12
- const agentId = useAgentId();
13
- const { updateAgentChatConfig } = useUpdateAgentConfig();
14
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
15
-
16
- const gpt5ReasoningEffort = config.gpt5ReasoningEffort || 'medium'; // Default to 'medium' if not set
17
-
18
- const marks = {
19
- 0: 'minimal',
20
- 1: 'low',
21
- 2: 'medium',
22
- 3: 'high',
23
- };
24
-
25
- const effortValues = ['minimal', 'low', 'medium', 'high'];
26
- const indexValue = effortValues.indexOf(gpt5ReasoningEffort);
27
- const currentValue = indexValue === -1 ? 2 : indexValue;
28
-
29
- const updateGPT5ReasoningEffort = useCallback(
30
- (value: number) => {
31
- const effort = effortValues[value] as 'minimal' | 'low' | 'medium' | 'high';
32
- updateAgentChatConfig({ gpt5ReasoningEffort: effort });
33
- },
34
- [updateAgentChatConfig],
35
- );
36
-
37
- return (
38
- <Flexbox
39
- align={'center'}
40
- gap={12}
41
- horizontal
42
- paddingInline={'0 20px'}
43
- style={{ minWidth: 200, width: '100%' }}
44
- >
45
- <Flexbox flex={1}>
46
- <Slider
47
- marks={marks}
48
- max={3}
49
- min={0}
50
- onChange={updateGPT5ReasoningEffort}
51
- step={1}
52
- tooltip={{ open: false }}
53
- value={currentValue}
54
- />
55
- </Flexbox>
56
- </Flexbox>
57
- );
8
+ const GPT5ReasoningEffortSlider = createLevelSliderComponent<GPT5ReasoningEffort>({
9
+ configKey: 'gpt5ReasoningEffort',
10
+ defaultValue: 'medium',
11
+ levels: GPT5_REASONING_EFFORT_LEVELS,
12
+ style: { minWidth: 200 },
58
13
  });
59
14
 
60
15
  export default GPT5ReasoningEffortSlider;
@@ -1,5 +1,5 @@
1
1
  import { Select } from 'antd';
2
- import { memo, useCallback, useMemo } from 'react';
2
+ import { memo, useMemo } from 'react';
3
3
 
4
4
  import { useAgentStore } from '@/store/agent';
5
5
  import { chatConfigByIdSelectors } from '@/store/agent/selectors';
@@ -18,15 +18,21 @@ const NANO_BANANA_ASPECT_RATIOS = [
18
18
  '9:16', // 768x1376 / 1536x2752 / 3072x5504
19
19
  '16:9', // 1376x768 / 2752x1536 / 5504x3072
20
20
  '21:9', // 1584x672 / 3168x1344 / 6336x2688
21
- ];
21
+ ] as const;
22
22
 
23
- const ImageAspectRatioSelect = memo(() => {
24
- const agentId = useAgentId();
25
- const { updateAgentChatConfig } = useUpdateAgentConfig();
26
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
23
+ type AspectRatio = (typeof NANO_BANANA_ASPECT_RATIOS)[number];
27
24
 
28
- const imageAspectRatio = config.imageAspectRatio || '1:1';
25
+ export interface ImageAspectRatioSelectProps {
26
+ defaultValue?: AspectRatio;
27
+ onChange?: (value: AspectRatio) => void;
28
+ value?: AspectRatio;
29
+ }
29
30
 
31
+ // Inner pure UI component - no store hooks, safe for preview
32
+ const ImageAspectRatioSelectInner = memo<{
33
+ onChange: (_value: AspectRatio) => void;
34
+ value: AspectRatio;
35
+ }>(({ value, onChange }) => {
30
36
  const options = useMemo(
31
37
  () =>
32
38
  NANO_BANANA_ASPECT_RATIOS.map((ratio) => ({
@@ -36,21 +42,49 @@ const ImageAspectRatioSelect = memo(() => {
36
42
  [],
37
43
  );
38
44
 
39
- const updateAspectRatio = useCallback(
40
- (value: string) => {
41
- updateAgentChatConfig({ imageAspectRatio: value });
42
- },
43
- [updateAgentChatConfig],
44
- );
45
-
46
45
  return (
47
46
  <Select
48
- onChange={updateAspectRatio}
47
+ onChange={(v: string) => onChange(v as AspectRatio)}
49
48
  options={options}
50
49
  style={{ height: 32, marginRight: 10, width: 75 }}
51
- value={imageAspectRatio}
50
+ value={value}
52
51
  />
53
52
  );
54
53
  });
55
54
 
55
+ // Store-connected component - uses agent store hooks
56
+ const ImageAspectRatioSelectWithStore = memo<{ defaultValue: AspectRatio }>(({ defaultValue }) => {
57
+ const agentId = useAgentId();
58
+ const { updateAgentChatConfig } = useUpdateAgentConfig();
59
+ const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
60
+
61
+ const storeValue = (config.imageAspectRatio as AspectRatio) || defaultValue;
62
+
63
+ const handleChange = (ratio: AspectRatio) => {
64
+ updateAgentChatConfig({ imageAspectRatio: ratio });
65
+ };
66
+
67
+ return <ImageAspectRatioSelectInner onChange={handleChange} value={storeValue} />;
68
+ });
69
+
70
+ // Main exported component - chooses between controlled and store mode
71
+ const ImageAspectRatioSelect = memo<ImageAspectRatioSelectProps>(
72
+ ({ value: controlledValue, onChange: controlledOnChange, defaultValue = '1:1' }) => {
73
+ const isControlled = controlledValue !== undefined || controlledOnChange !== undefined;
74
+
75
+ if (isControlled) {
76
+ // Controlled mode: use props only, no store access
77
+ return (
78
+ <ImageAspectRatioSelectInner
79
+ onChange={controlledOnChange ?? (() => {})}
80
+ value={controlledValue ?? defaultValue}
81
+ />
82
+ );
83
+ }
84
+
85
+ // Uncontrolled mode: use store
86
+ return <ImageAspectRatioSelectWithStore defaultValue={defaultValue} />;
87
+ },
88
+ );
89
+
56
90
  export default ImageAspectRatioSelect;
@@ -1,61 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
4
-
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
7
-
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
10
2
 
11
3
  const IMAGE_RESOLUTIONS = ['1K', '2K', '4K'] as const;
12
4
  type ImageResolution = (typeof IMAGE_RESOLUTIONS)[number];
13
5
 
14
- const ImageResolutionSlider = memo(() => {
15
- const agentId = useAgentId();
16
- const { updateAgentChatConfig } = useUpdateAgentConfig();
17
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
18
-
19
- const imageResolution = (config.imageResolution as ImageResolution) || '1K';
20
-
21
- const marks = {
22
- 0: '1K',
23
- 1: '2K',
24
- 2: '4K',
25
- };
26
-
27
- const indexValue = IMAGE_RESOLUTIONS.indexOf(imageResolution);
28
- const currentValue = indexValue === -1 ? 0 : indexValue;
29
-
30
- const updateResolution = useCallback(
31
- (value: number) => {
32
- const resolution = IMAGE_RESOLUTIONS[value];
33
- updateAgentChatConfig({ imageResolution: resolution });
34
- },
35
- [updateAgentChatConfig],
36
- );
6
+ export type ImageResolutionSliderProps = CreatedLevelSliderProps<ImageResolution>;
37
7
 
38
- return (
39
- <Flexbox
40
- align={'center'}
41
- gap={12}
42
- horizontal
43
- paddingInline={'0 20px'}
44
- style={{ minWidth: 150, width: '100%' }}
45
- >
46
- <Flexbox flex={1}>
47
- <Slider
48
- marks={marks}
49
- max={2}
50
- min={0}
51
- onChange={updateResolution}
52
- step={1}
53
- tooltip={{ open: false }}
54
- value={currentValue}
55
- />
56
- </Flexbox>
57
- </Flexbox>
58
- );
8
+ const ImageResolutionSlider = createLevelSliderComponent<ImageResolution>({
9
+ configKey: 'imageResolution',
10
+ defaultValue: '1K',
11
+ levels: IMAGE_RESOLUTIONS,
12
+ style: { minWidth: 150 },
59
13
  });
60
14
 
61
15
  export default ImageResolutionSlider;
@@ -0,0 +1,92 @@
1
+ import { Flexbox } from '@lobehub/ui';
2
+ import { Slider } from 'antd';
3
+ import { type SliderSingleProps } from 'antd/es/slider';
4
+ import { type CSSProperties, memo, useMemo } from 'react';
5
+ import useMergeState from 'use-merge-value';
6
+
7
+ export interface LevelSliderProps<T extends string = string> {
8
+ /**
9
+ * Default value when uncontrolled
10
+ */
11
+ defaultValue?: T;
12
+ /**
13
+ * Ordered array of level values (left to right on slider)
14
+ */
15
+ levels: readonly T[];
16
+ /**
17
+ * Optional custom marks. If not provided, uses level values as marks.
18
+ */
19
+ marks?: SliderSingleProps['marks'];
20
+ /**
21
+ * Callback when value changes
22
+ */
23
+ onChange?: (value: T) => void;
24
+ /**
25
+ * Style for the slider container
26
+ */
27
+ style?: CSSProperties;
28
+ /**
29
+ * Controlled value
30
+ */
31
+ value?: T;
32
+ }
33
+
34
+ function LevelSlider<T extends string = string>({
35
+ levels,
36
+ value,
37
+ defaultValue,
38
+ onChange,
39
+ marks: customMarks,
40
+ style,
41
+ }: LevelSliderProps<T>) {
42
+ const defaultLevel = defaultValue ?? levels[Math.floor(levels.length / 2)];
43
+
44
+ const [currentLevel, setCurrentLevel] = useMergeState<T>(defaultLevel, {
45
+ defaultValue,
46
+ onChange,
47
+ value,
48
+ });
49
+
50
+ const marks = useMemo(() => {
51
+ if (customMarks) return customMarks;
52
+ const result: SliderSingleProps['marks'] = {};
53
+ levels.forEach((level, index) => {
54
+ result[index] = level;
55
+ });
56
+ return result;
57
+ }, [customMarks, levels]);
58
+
59
+ const currentIndex = levels.indexOf(currentLevel);
60
+ const sliderValue = currentIndex === -1 ? Math.floor(levels.length / 2) : currentIndex;
61
+
62
+ const handleChange = (index: number) => {
63
+ const newLevel = levels[index];
64
+ if (newLevel !== undefined) {
65
+ setCurrentLevel(newLevel);
66
+ }
67
+ };
68
+
69
+ return (
70
+ <Flexbox
71
+ align={'center'}
72
+ gap={12}
73
+ horizontal
74
+ paddingInline={'0 20px'}
75
+ style={{ minWidth: 200, width: '100%', ...style }}
76
+ >
77
+ <Flexbox flex={1}>
78
+ <Slider
79
+ marks={marks}
80
+ max={levels.length - 1}
81
+ min={0}
82
+ onChange={handleChange}
83
+ step={1}
84
+ tooltip={{ open: false }}
85
+ value={sliderValue}
86
+ />
87
+ </Flexbox>
88
+ </Flexbox>
89
+ );
90
+ }
91
+
92
+ export default memo(LevelSlider) as typeof LevelSlider;
@@ -1,59 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
4
2
 
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
3
+ const REASONING_EFFORT_LEVELS = ['low', 'medium', 'high'] as const;
4
+ type ReasoningEffort = (typeof REASONING_EFFORT_LEVELS)[number];
7
5
 
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
6
+ export type ReasoningEffortSliderProps = CreatedLevelSliderProps<ReasoningEffort>;
10
7
 
11
- const ReasoningEffortSlider = memo(() => {
12
- const agentId = useAgentId();
13
- const { updateAgentChatConfig } = useUpdateAgentConfig();
14
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
15
-
16
- const reasoningEffort = config.reasoningEffort || 'medium'; // Default to 'medium' if not set
17
-
18
- const marks = {
19
- 0: 'low',
20
- 1: 'medium',
21
- 2: 'high',
22
- };
23
-
24
- const effortValues = ['low', 'medium', 'high'];
25
- const indexValue = effortValues.indexOf(reasoningEffort);
26
- const currentValue = indexValue === -1 ? 1 : indexValue;
27
-
28
- const updateReasoningEffort = useCallback(
29
- (value: number) => {
30
- const effort = effortValues[value] as 'low' | 'medium' | 'high';
31
- updateAgentChatConfig({ reasoningEffort: effort });
32
- },
33
- [updateAgentChatConfig],
34
- );
35
-
36
- return (
37
- <Flexbox
38
- align={'center'}
39
- gap={12}
40
- horizontal
41
- paddingInline={'0 20px'}
42
- style={{ minWidth: 200, width: '100%' }}
43
- >
44
- <Flexbox flex={1}>
45
- <Slider
46
- marks={marks}
47
- max={2}
48
- min={0}
49
- onChange={updateReasoningEffort}
50
- step={1}
51
- tooltip={{ open: false }}
52
- value={currentValue}
53
- />
54
- </Flexbox>
55
- </Flexbox>
56
- );
8
+ const ReasoningEffortSlider = createLevelSliderComponent<ReasoningEffort>({
9
+ configKey: 'reasoningEffort',
10
+ defaultValue: 'medium',
11
+ levels: REASONING_EFFORT_LEVELS,
12
+ style: { minWidth: 200 },
57
13
  });
58
14
 
59
15
  export default ReasoningEffortSlider;
@@ -1,59 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
4
2
 
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
3
+ const TEXT_VERBOSITY_LEVELS = ['low', 'medium', 'high'] as const;
4
+ type TextVerbosity = (typeof TEXT_VERBOSITY_LEVELS)[number];
7
5
 
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
6
+ export type TextVerbositySliderProps = CreatedLevelSliderProps<TextVerbosity>;
10
7
 
11
- const TextVerbositySlider = memo(() => {
12
- const agentId = useAgentId();
13
- const { updateAgentChatConfig } = useUpdateAgentConfig();
14
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
15
-
16
- const textVerbosity = config.textVerbosity || 'medium'; // Default to 'medium' if not set
17
-
18
- const marks = {
19
- 0: 'low',
20
- 1: 'medium',
21
- 2: 'high',
22
- };
23
-
24
- const verbosityValues = ['low', 'medium', 'high'];
25
- const indexValue = verbosityValues.indexOf(textVerbosity);
26
- const currentValue = indexValue === -1 ? 1 : indexValue;
27
-
28
- const updateTextVerbosity = useCallback(
29
- (value: number) => {
30
- const verbosity = verbosityValues[value] as 'low' | 'medium' | 'high';
31
- updateAgentChatConfig({ textVerbosity: verbosity });
32
- },
33
- [updateAgentChatConfig],
34
- );
35
-
36
- return (
37
- <Flexbox
38
- align={'center'}
39
- gap={12}
40
- horizontal
41
- paddingInline={'0 20px'}
42
- style={{ minWidth: 160, width: '100%' }}
43
- >
44
- <Flexbox flex={1}>
45
- <Slider
46
- marks={marks}
47
- max={2}
48
- min={0}
49
- onChange={updateTextVerbosity}
50
- step={1}
51
- tooltip={{ open: false }}
52
- value={currentValue}
53
- />
54
- </Flexbox>
55
- </Flexbox>
56
- );
8
+ const TextVerbositySlider = createLevelSliderComponent<TextVerbosity>({
9
+ configKey: 'textVerbosity',
10
+ defaultValue: 'medium',
11
+ levels: TEXT_VERBOSITY_LEVELS,
12
+ style: { minWidth: 160 },
57
13
  });
58
14
 
59
15
  export default TextVerbositySlider;
@@ -1,58 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
4
2
 
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
3
+ const THINKING_LEVELS_2 = ['low', 'high'] as const;
4
+ type ThinkingLevel2 = (typeof THINKING_LEVELS_2)[number];
7
5
 
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
6
+ export type ThinkingLevel2SliderProps = CreatedLevelSliderProps<ThinkingLevel2>;
10
7
 
11
- const ThinkingLevel2Slider = memo(() => {
12
- const agentId = useAgentId();
13
- const { updateAgentChatConfig } = useUpdateAgentConfig();
14
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
15
-
16
- const thinkingLevel = config.thinkingLevel || 'high'; // Default to 'high' if not set
17
-
18
- const marks = {
19
- 0: 'low',
20
- 1: 'high',
21
- };
22
-
23
- const levelValues = ['low', 'high'];
24
- const indexValue = levelValues.indexOf(thinkingLevel as any);
25
- const currentValue = indexValue === -1 ? 1 : indexValue;
26
-
27
- const updateThinkingLevel = useCallback(
28
- (value: number) => {
29
- const level = levelValues[value] as 'low' | 'high';
30
- updateAgentChatConfig({ thinkingLevel: level });
31
- },
32
- [updateAgentChatConfig],
33
- );
34
-
35
- return (
36
- <Flexbox
37
- align={'center'}
38
- gap={12}
39
- horizontal
40
- paddingInline={'0 20px'}
41
- style={{ minWidth: 110, width: '100%' }}
42
- >
43
- <Flexbox flex={1}>
44
- <Slider
45
- marks={marks}
46
- max={1}
47
- min={0}
48
- onChange={updateThinkingLevel}
49
- step={1}
50
- tooltip={{ open: false }}
51
- value={currentValue}
52
- />
53
- </Flexbox>
54
- </Flexbox>
55
- );
8
+ const ThinkingLevel2Slider = createLevelSliderComponent<ThinkingLevel2>({
9
+ configKey: 'thinkingLevel',
10
+ defaultValue: 'high',
11
+ levels: THINKING_LEVELS_2,
12
+ style: { minWidth: 110 },
56
13
  });
57
14
 
58
15
  export default ThinkingLevel2Slider;
@@ -1,60 +1,15 @@
1
- import { Flexbox } from '@lobehub/ui';
2
- import { Slider } from 'antd';
3
- import { memo, useCallback } from 'react';
1
+ import { type CreatedLevelSliderProps, createLevelSliderComponent } from './createLevelSlider';
4
2
 
5
- import { useAgentStore } from '@/store/agent';
6
- import { chatConfigByIdSelectors } from '@/store/agent/selectors';
3
+ const THINKING_LEVELS = ['minimal', 'low', 'medium', 'high'] as const;
4
+ type ThinkingLevel = (typeof THINKING_LEVELS)[number];
7
5
 
8
- import { useAgentId } from '../../hooks/useAgentId';
9
- import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig';
6
+ export type ThinkingLevelSliderProps = CreatedLevelSliderProps<ThinkingLevel>;
10
7
 
11
- const ThinkingLevelSlider = memo(() => {
12
- const agentId = useAgentId();
13
- const { updateAgentChatConfig } = useUpdateAgentConfig();
14
- const config = useAgentStore((s) => chatConfigByIdSelectors.getChatConfigById(agentId)(s));
15
-
16
- const thinkingLevel = config.thinkingLevel || 'high'; // Default to 'high' if not set
17
-
18
- const marks = {
19
- 0: 'minimal',
20
- 1: 'low',
21
- 2: 'medium',
22
- 3: 'high',
23
- };
24
-
25
- const levelValues = ['minimal', 'low', 'medium', 'high'];
26
- const indexValue = levelValues.indexOf(thinkingLevel as any);
27
- const currentValue = indexValue === -1 ? 3 : indexValue;
28
-
29
- const updateThinkingLevel = useCallback(
30
- (value: number) => {
31
- const level = levelValues[value] as 'minimal' | 'low' | 'medium' | 'high';
32
- updateAgentChatConfig({ thinkingLevel: level });
33
- },
34
- [updateAgentChatConfig],
35
- );
36
-
37
- return (
38
- <Flexbox
39
- align={'center'}
40
- gap={12}
41
- horizontal
42
- paddingInline={'0 20px'}
43
- style={{ minWidth: 200, width: '100%' }}
44
- >
45
- <Flexbox flex={1}>
46
- <Slider
47
- marks={marks}
48
- max={3}
49
- min={0}
50
- onChange={updateThinkingLevel}
51
- step={1}
52
- tooltip={{ open: false }}
53
- value={currentValue}
54
- />
55
- </Flexbox>
56
- </Flexbox>
57
- );
8
+ const ThinkingLevelSlider = createLevelSliderComponent<ThinkingLevel>({
9
+ configKey: 'thinkingLevel',
10
+ defaultValue: 'high',
11
+ levels: THINKING_LEVELS,
12
+ style: { minWidth: 200 },
58
13
  });
59
14
 
60
15
  export default ThinkingLevelSlider;