Skip to content

Commit 13e5c45

Browse files
authored
feat(ui): new ux for run model settings (#1386)
Signed-off-by: Petr Kadlec <petr@puradesign.cz>
1 parent 128869e commit 13e5c45

22 files changed

+450
-277
lines changed

apps/beeai-sdk-py/examples/settings_agent.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
from beeai_sdk.a2a.extensions.ui.settings import (
1111
CheckboxField,
1212
CheckboxGroupField,
13+
OptionItem,
1314
SettingsExtensionServer,
1415
SettingsExtensionSpec,
1516
SettingsRender,
17+
SingleSelectField,
1618
)
1719
from beeai_sdk.a2a.types import RunYield
1820
from beeai_sdk.server import Server
@@ -39,7 +41,17 @@ async def settings_agent(
3941
default_value=True,
4042
)
4143
],
42-
)
44+
),
45+
SingleSelectField(
46+
id="response_style",
47+
label="Response Style",
48+
options=[
49+
OptionItem(value="concise", label="Concise"),
50+
OptionItem(value="detailed", label="Detailed"),
51+
OptionItem(value="humorous", label="Humorous"),
52+
],
53+
default_value="concise",
54+
),
4355
],
4456
),
4557
),

apps/beeai-ui/src/modules/runs/settings/SingleSelectSettingsField.module.scss renamed to apps/beeai-ui/src/components/RadioSelect/RadioSelect.module.scss

File renamed without changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright 2025 © BeeAI a Series of LF Projects, LLC
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { Checkmark } from '@carbon/icons-react';
7+
import { RadioButton, RadioButtonGroup } from '@carbon/react';
8+
import clsx from 'clsx';
9+
import { useId } from 'react';
10+
11+
import classes from './RadioSelect.module.scss';
12+
13+
interface Props {
14+
name: string;
15+
label: string;
16+
value?: string;
17+
options: { value: string; label: string }[];
18+
onChange: (value: string) => void;
19+
}
20+
21+
export function RadioSelect({ name, label, value, options, onChange }: Props) {
22+
const htmlId = useId();
23+
24+
return (
25+
<RadioButtonGroup
26+
legendText={label}
27+
name={name}
28+
valueSelected={value}
29+
orientation="vertical"
30+
className={classes.root}
31+
>
32+
{options.map(({ value: optionValue, label }) => {
33+
const isSelected = optionValue === value;
34+
return (
35+
<div className={clsx(classes.option, { [classes.selected]: isSelected })} key={optionValue}>
36+
<RadioButton
37+
id={`${htmlId}:${optionValue}`}
38+
value={optionValue}
39+
labelText={label}
40+
onClick={() => onChange(optionValue)}
41+
/>
42+
{optionValue === value && <Checkmark size={16} />}
43+
</div>
44+
);
45+
})}
46+
</RadioButtonGroup>
47+
);
48+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright 2025 © BeeAI a Series of LF Projects, LLC
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
.root {
7+
display: grid;
8+
grid-template-columns: 1fr max-content;
9+
align-items: center;
10+
}
11+
12+
.settings {
13+
display: flex;
14+
gap: $spacing-03;
15+
}
16+
17+
.buttons {
18+
display: flex;
19+
justify-content: flex-end;
20+
text-align: end;
21+
gap: $spacing-04;
22+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright 2025 © BeeAI a Series of LF Projects, LLC
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { Button } from '@carbon/react';
7+
import { useMergeRefs } from '@floating-ui/react';
8+
9+
import { useApp } from '#contexts/App/index.ts';
10+
import { RunModels } from '#modules/runs/settings/RunModels.tsx';
11+
import { RunSettings } from '#modules/runs/settings/RunSettings.tsx';
12+
import { useRunSettingsDialog } from '#modules/runs/settings/useRunSettingsDialog.ts';
13+
14+
import classes from './FormActionBar.module.scss';
15+
16+
interface Props {
17+
showSubmitButton?: boolean;
18+
submitLabel: string;
19+
showRunSettings?: boolean;
20+
}
21+
22+
export function FormActionBar({ showSubmitButton = true, submitLabel, showRunSettings }: Props) {
23+
const {
24+
config: { featureFlags },
25+
} = useApp();
26+
27+
const modelsDialog = useRunSettingsDialog({ blockOffset: 8 });
28+
const settingsDialog = useRunSettingsDialog({ blockOffset: 8 });
29+
const formRefs = useMergeRefs([modelsDialog.refs.setPositionReference, settingsDialog.refs.setPositionReference]);
30+
31+
return (
32+
<div className={classes.root} ref={formRefs}>
33+
{showRunSettings && (
34+
<div className={classes.settings}>
35+
<RunSettings dialog={settingsDialog} iconOnly={false} />
36+
{featureFlags.ModelProviders && <RunModels dialog={modelsDialog} iconOnly={false} />}
37+
</div>
38+
)}
39+
{showSubmitButton && (
40+
<div className={classes.buttons}>
41+
<Button type="submit" size="md">
42+
{submitLabel}
43+
</Button>
44+
</div>
45+
)}
46+
</div>
47+
);
48+
}

apps/beeai-ui/src/modules/form/components/FormRenderer.module.scss

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,3 @@
88
flex-direction: column;
99
row-gap: $spacing-06;
1010
}
11-
12-
.fields {
13-
display: grid;
14-
column-gap: $spacing-04;
15-
row-gap: $spacing-06;
16-
grid-template-columns: repeat(var(--grid-columns, 1), minmax(0, 1fr));
17-
}
18-
19-
.buttons {
20-
display: flex;
21-
justify-content: flex-end;
22-
text-align: end;
23-
gap: $spacing-04;
24-
}

apps/beeai-ui/src/modules/form/components/FormRenderer.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { Button } from '@carbon/react';
76
import type { FormRender } from 'beeai-sdk';
87
import { FormProvider, useForm } from 'react-hook-form';
98

@@ -13,6 +12,7 @@ import { isNotNull } from '#utils/helpers.ts';
1312

1413
import type { RunFormValues } from '../types';
1514
import { getDefaultValues } from '../utils';
15+
import { FormActionBar } from './FormActionBar';
1616
import { FormFields } from './FormFields';
1717
import classes from './FormRenderer.module.scss';
1818

@@ -21,13 +21,15 @@ interface Props {
2121
defaultHeading?: string | null;
2222
showHeading?: boolean;
2323
isDisabled?: boolean;
24+
showRunSettings?: boolean;
2425
onSubmit: (values: RunFormValues) => void;
2526
}
2627

2728
export function FormRenderer({
2829
definition,
2930
defaultHeading,
3031
showHeading: showHeadingProp = true,
32+
showRunSettings,
3133
isDisabled,
3234
onSubmit,
3335
}: Props) {
@@ -52,15 +54,11 @@ export function FormRenderer({
5254

5355
<FormFields fields={fields} columns={columns} />
5456

55-
{!isDisabled && (
56-
<>
57-
<div className={classes.buttons}>
58-
<Button type="submit" size="md">
59-
{submit_label ?? 'Submit'}
60-
</Button>
61-
</div>
62-
</>
63-
)}
57+
<FormActionBar
58+
submitLabel={submit_label ?? 'Submit'}
59+
showRunSettings={showRunSettings}
60+
showSubmitButton={!isDisabled}
61+
/>
6462
</fieldset>
6563
</form>
6664
</FormProvider>

apps/beeai-ui/src/modules/runs/components/FormRenderView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export function FormRenderView({ formRender }: Props) {
2727
<Container size="sm" className={classes.root}>
2828
<FormRenderer
2929
definition={formRender}
30+
showRunSettings
3031
onSubmit={(values: RunFormValues) => {
3132
const form = {
3233
request: formRender,

apps/beeai-ui/src/modules/runs/components/MCPConfig.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ export function MCPConfig() {
1616
const id = useId();
1717
const { selectedMCPServers, selectMCPServer } = useAgentDemands();
1818

19+
const entries = Object.entries(selectedMCPServers);
20+
if (!entries.length) {
21+
return null;
22+
}
23+
1924
return (
2025
<div className={classes.root}>
21-
{Object.entries(selectedMCPServers).map(([key, value]) => (
26+
{entries.map(([key, value]) => (
2227
<TextInput
2328
value={value}
2429
onChange={(e) => selectMCPServer(key, e.target.value)}

apps/beeai-ui/src/modules/runs/components/ModelProviders.tsx

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)