Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
23 changes: 17 additions & 6 deletions react/src/components/AgentSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, { useDeferredValue, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { graphql, useLazyLoadQuery } from 'react-relay';

interface Props extends SelectProps {
interface Props extends Omit<SelectProps, 'options'> {
autoSelectDefault?: boolean;
fetchKey?: string;
resourceGroup?: string | null;
Expand Down Expand Up @@ -122,19 +122,30 @@ const AgentSelect: React.FC<Props> = ({
: undefined;
return (
<Select
onChange={(value, option) => {
setValue(value, option);
}}
loading={searchStr !== deferredSearchStr}
filterOption={false}
showSearch
searchValue={searchStr}
onSearch={(v) => {
setSearchStr(v);
}}
{...selectProps}
value={value}
options={filterOutEmpty([autoSelectIfMatch, ...agentOptions])}
//override props.onChange and props.value, it is handled by useControllableValue
{..._.omit(selectProps, ['value', 'onChange'])}
onChange={(value: unknown, option) => {
// multi-mode
if (_.isArray(value) && _.isArray(option)) {
if (_.last(value) === 'auto' || value.length === 0) {
value = ['auto'];
option = _.last(option);
} else if (value[0] === 'auto' && value.length > 1) {
value = value.slice(1);
option = option.slice(1);
}
}
setValue(value, option);
}}
value={value}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const RESOURCE_ALLOCATION_INITIAL_FORM_VALUES: DeepPartial<ResourceAlloca
cluster_mode: 'single-node',
cluster_size: 1,
enabledAutomaticShmem: true,
agent: 'auto',
agent: ['auto'],
};

export const isMinOversMaxValue = (min: number, max: number) => {
Expand All @@ -67,7 +67,7 @@ export interface ResourceAllocationFormValue {
cluster_size: number;
enabledAutomaticShmem: boolean;
allocationPreset?: string;
agent?: string;
agent?: string[] | string;
}

export type MergedResourceAllocationFormValue = ResourceAllocationFormValue &
Expand Down Expand Up @@ -1232,15 +1232,16 @@ const ResourceAllocationFormItems: React.FC<
<AgentSelect
resourceGroup={currentResourceGroupInForm}
fetchKey={agentFetchKey}
onChange={(value, option) => {
if (value !== 'auto') {
form.setFieldsValue({
cluster_mode: 'single-node',
cluster_size: 1,
});
}
// TODO: set cluster mode to single node and cluster size to 1 when agent value is not "auto"
}}
mode={
baiClient.supports('multi-agents') ? 'multiple' : undefined
}
labelRender={
baiClient.supports('multi-agents')
? ({ label, value }) => {
return value === 'auto' ? label : value;
}
: undefined
}
></AgentSelect>
</Form.Item>
</Suspense>
Expand Down Expand Up @@ -1285,7 +1286,6 @@ const ResourceAllocationFormItems: React.FC<
onChange={(e) => {
form.validateFields().catch(() => {});
}}
disabled={getFieldValue('agent') !== 'auto'}
>
<Radio.Button value="single-node">
{t('session.launcher.SingleNode')}
Expand Down Expand Up @@ -1348,10 +1348,7 @@ const ResourceAllocationFormItems: React.FC<
? derivedClusterSizeMaxLimit
: undefined
}
disabled={
derivedClusterSizeMaxLimit === 1 ||
getFieldValue('agent') !== 'auto'
}
disabled={derivedClusterSizeMaxLimit === 1}
sliderProps={{
marks: {
1: '1',
Expand Down
41 changes: 31 additions & 10 deletions react/src/pages/SessionLauncherPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -549,16 +549,37 @@ const SessionLauncherPage = () => {
preopen_ports: transformPortValuesToNumbers(values.ports),

// Agent selection (optional)
...(baiClient.supports('agent-select') &&
!baiClient?._config?.hideAgents &&
values.agent !== 'auto'
? {
// Filter out undefined values
agent_list: [values.agent].filter(
(agent): agent is string => !!agent,
...(() => {
if (values.agent === undefined) return {};

const agents = _.castArray(values.agent);

if (
!baiClient.supports('agent-select') ||
baiClient?._config?.hideAgents ||
_.isEqual(agents, ['auto']) ||
agents.length === 0
) {
return {};
}

if (
!baiClient.supports('multi-agents') &&
values.cluster_mode === 'multi-node'
) {
// The server now requires agents equivalent to the cluster size.
return {
agent_list: Array.from(
{ length: values.cluster_size },
() => agents[0],
),
}
: undefined),
};
}

return {
agent_list: _.filter(agents, (item) => !!item),
};
})(),
},
},
};
Expand Down Expand Up @@ -1546,7 +1567,7 @@ const SessionLauncherPage = () => {
command: undefined,
scheduleDate: undefined,
},
agent: 'auto', // Add the missing 'agent' property
agent: ['auto'], // Add the missing 'agent' property
} as SessionLauncherFormData,
formValue,
);
Expand Down
3 changes: 3 additions & 0 deletions src/lib/backend.ai-client-esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,9 @@ class Client {
if (this.isManagerVersionCompatibleWith('25.12.0')) {
this._features['reservoir'] = true;
}
if (this.isManagerVersionCompatibleWith('25.15.0')) {
this._features['multi-agents'] = true;
}
}

/**
Expand Down