fix(team): drop unavailable effort selections
This commit is contained in:
parent
a386e30667
commit
3c60ab8653
6 changed files with 143 additions and 37 deletions
|
|
@ -74,6 +74,7 @@ import { isGeminiUiFrozen } from '@renderer/utils/geminiUiFreeze';
|
||||||
import { normalizePath } from '@renderer/utils/pathNormalize';
|
import { normalizePath } from '@renderer/utils/pathNormalize';
|
||||||
import { resolveUiOwnedProviderBackendId } from '@renderer/utils/providerBackendIdentity';
|
import { resolveUiOwnedProviderBackendId } from '@renderer/utils/providerBackendIdentity';
|
||||||
import { refreshCliStatusForCurrentMode } from '@renderer/utils/refreshCliStatus';
|
import { refreshCliStatusForCurrentMode } from '@renderer/utils/refreshCliStatus';
|
||||||
|
import { getAvailableTeamEffortValue } from '@renderer/utils/teamEffortOptions';
|
||||||
import {
|
import {
|
||||||
getTeamModelSelectionError,
|
getTeamModelSelectionError,
|
||||||
normalizeExplicitTeamModelForUi,
|
normalizeExplicitTeamModelForUi,
|
||||||
|
|
@ -779,9 +780,27 @@ export const CreateTeamDialog = ({
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const selectedEffortForCurrentSelection = useMemo(
|
||||||
|
() =>
|
||||||
|
getAvailableTeamEffortValue({
|
||||||
|
providerId: selectedProviderId,
|
||||||
|
model: selectedModel,
|
||||||
|
limitContext: effectiveAnthropicRuntimeLimitContext,
|
||||||
|
providerStatus: runtimeProviderStatusById.get(selectedProviderId),
|
||||||
|
value: selectedEffort,
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
|
runtimeProviderStatusById,
|
||||||
|
selectedEffort,
|
||||||
|
selectedModel,
|
||||||
|
selectedProviderId,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
const selectedModelChecksByProvider = useMemo(() => {
|
const selectedModelChecksByProvider = useMemo(() => {
|
||||||
const modelsByProvider = new Map<TeamProviderId, TeamProvisioningModelCheckRequest[]>();
|
const modelsByProvider = new Map<TeamProviderId, TeamProvisioningModelCheckRequest[]>();
|
||||||
const leadEffort = (selectedEffort as EffortLevel | '') || undefined;
|
const leadEffort = (selectedEffortForCurrentSelection as EffortLevel | '') || undefined;
|
||||||
const addModel = (
|
const addModel = (
|
||||||
providerId: TeamProviderId,
|
providerId: TeamProviderId,
|
||||||
model: string | undefined,
|
model: string | undefined,
|
||||||
|
|
@ -850,7 +869,7 @@ export const CreateTeamDialog = ({
|
||||||
effectiveAnthropicRuntimeLimitContext,
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
effectiveMemberDrafts,
|
effectiveMemberDrafts,
|
||||||
runtimeProviderStatusById,
|
runtimeProviderStatusById,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
]);
|
]);
|
||||||
|
|
@ -1560,13 +1579,13 @@ export const CreateTeamDialog = ({
|
||||||
selectedModel,
|
selectedModel,
|
||||||
limitContext: effectiveAnthropicRuntimeLimitContext,
|
limitContext: effectiveAnthropicRuntimeLimitContext,
|
||||||
}),
|
}),
|
||||||
selectedEffort,
|
selectedEffort: selectedEffortForCurrentSelection,
|
||||||
selectedFastMode,
|
selectedFastMode,
|
||||||
providerFastModeDefault: anthropicProviderFastModeDefault,
|
providerFastModeDefault: anthropicProviderFastModeDefault,
|
||||||
runtimeCapabilities: runtimeProviderStatusById.get('anthropic')?.runtimeCapabilities,
|
runtimeCapabilities: runtimeProviderStatusById.get('anthropic')?.runtimeCapabilities,
|
||||||
})
|
})
|
||||||
: {
|
: {
|
||||||
nextEffort: selectedEffort,
|
nextEffort: selectedEffortForCurrentSelection,
|
||||||
effortResetReason: null,
|
effortResetReason: null,
|
||||||
...reconcileCodexRuntimeSelections({
|
...reconcileCodexRuntimeSelections({
|
||||||
selection:
|
selection:
|
||||||
|
|
@ -1586,7 +1605,11 @@ export const CreateTeamDialog = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const notices: string[] = [];
|
const notices: string[] = [];
|
||||||
if (reconciliation.nextEffort !== selectedEffort) {
|
if (selectedEffortForCurrentSelection !== selectedEffort) {
|
||||||
|
setSelectedEffortRaw(selectedEffortForCurrentSelection);
|
||||||
|
setStoredCreateTeamEffort(selectedEffortForCurrentSelection);
|
||||||
|
}
|
||||||
|
if (reconciliation.nextEffort !== selectedEffortForCurrentSelection) {
|
||||||
setSelectedEffortRaw(reconciliation.nextEffort);
|
setSelectedEffortRaw(reconciliation.nextEffort);
|
||||||
setStoredCreateTeamEffort(reconciliation.nextEffort);
|
setStoredCreateTeamEffort(reconciliation.nextEffort);
|
||||||
if (reconciliation.effortResetReason) {
|
if (reconciliation.effortResetReason) {
|
||||||
|
|
@ -1608,6 +1631,7 @@ export const CreateTeamDialog = ({
|
||||||
effectiveAnthropicRuntimeLimitContext,
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
runtimeProviderStatusById,
|
runtimeProviderStatusById,
|
||||||
selectedEffort,
|
selectedEffort,
|
||||||
|
selectedEffortForCurrentSelection,
|
||||||
selectedFastMode,
|
selectedFastMode,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
|
|
@ -1634,7 +1658,7 @@ export const CreateTeamDialog = ({
|
||||||
providerId: selectedProviderId,
|
providerId: selectedProviderId,
|
||||||
providerBackendId: selectedProviderBackendId ?? undefined,
|
providerBackendId: selectedProviderBackendId ?? undefined,
|
||||||
model: effectiveModel,
|
model: effectiveModel,
|
||||||
effort: (selectedEffort as EffortLevel) || undefined,
|
effort: (selectedEffortForCurrentSelection as EffortLevel) || undefined,
|
||||||
fastMode:
|
fastMode:
|
||||||
selectedProviderId === 'anthropic' || selectedProviderId === 'codex'
|
selectedProviderId === 'anthropic' || selectedProviderId === 'codex'
|
||||||
? selectedFastMode
|
? selectedFastMode
|
||||||
|
|
@ -1655,7 +1679,7 @@ export const CreateTeamDialog = ({
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
selectedProviderBackendId,
|
selectedProviderBackendId,
|
||||||
effectiveModel,
|
effectiveModel,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
selectedFastMode,
|
selectedFastMode,
|
||||||
effectiveAnthropicRuntimeLimitContext,
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
skipPermissions,
|
skipPermissions,
|
||||||
|
|
@ -1768,8 +1792,8 @@ export const CreateTeamDialog = ({
|
||||||
if (effectiveModel) args.push('--model', effectiveModel);
|
if (effectiveModel) args.push('--model', effectiveModel);
|
||||||
const effectiveEffort =
|
const effectiveEffort =
|
||||||
selectedProviderId === 'anthropic'
|
selectedProviderId === 'anthropic'
|
||||||
? selectedEffort || anthropicRuntimeSelection?.defaultEffort || ''
|
? selectedEffortForCurrentSelection || anthropicRuntimeSelection?.defaultEffort || ''
|
||||||
: selectedEffort;
|
: selectedEffortForCurrentSelection;
|
||||||
if (effectiveEffort) args.push('--effort', effectiveEffort);
|
if (effectiveEffort) args.push('--effort', effectiveEffort);
|
||||||
if (selectedProviderId === 'anthropic') {
|
if (selectedProviderId === 'anthropic') {
|
||||||
const fastSettings = anthropicFastModeResolution?.resolvedFastMode
|
const fastSettings = anthropicFastModeResolution?.resolvedFastMode
|
||||||
|
|
@ -1785,7 +1809,7 @@ export const CreateTeamDialog = ({
|
||||||
anthropicRuntimeSelection?.defaultEffort,
|
anthropicRuntimeSelection?.defaultEffort,
|
||||||
codexFastModeResolution?.resolvedFastMode,
|
codexFastModeResolution?.resolvedFastMode,
|
||||||
effectiveModel,
|
effectiveModel,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
skipPermissions,
|
skipPermissions,
|
||||||
]);
|
]);
|
||||||
|
|
@ -2172,7 +2196,7 @@ export const CreateTeamDialog = ({
|
||||||
defaultProviderId={selectedProviderId}
|
defaultProviderId={selectedProviderId}
|
||||||
inheritedProviderId={selectedProviderId}
|
inheritedProviderId={selectedProviderId}
|
||||||
inheritedModel={selectedModel}
|
inheritedModel={selectedModel}
|
||||||
inheritedEffort={(selectedEffort as EffortLevel) || undefined}
|
inheritedEffort={(selectedEffortForCurrentSelection as EffortLevel) || undefined}
|
||||||
inheritModelSettingsByDefault
|
inheritModelSettingsByDefault
|
||||||
lockProviderModel={syncModelsWithLead}
|
lockProviderModel={syncModelsWithLead}
|
||||||
forceInheritedModelSettings={syncModelsWithLead}
|
forceInheritedModelSettings={syncModelsWithLead}
|
||||||
|
|
@ -2180,7 +2204,7 @@ export const CreateTeamDialog = ({
|
||||||
hideMembersContent={soloTeam}
|
hideMembersContent={soloTeam}
|
||||||
providerId={selectedProviderId}
|
providerId={selectedProviderId}
|
||||||
model={selectedModel}
|
model={selectedModel}
|
||||||
effort={(selectedEffort as EffortLevel) || undefined}
|
effort={(selectedEffortForCurrentSelection as EffortLevel) || undefined}
|
||||||
limitContext={effectiveAnthropicRuntimeLimitContext}
|
limitContext={effectiveAnthropicRuntimeLimitContext}
|
||||||
leadProviderNoticeById={teammateRuntimeProviderNoticeById}
|
leadProviderNoticeById={teammateRuntimeProviderNoticeById}
|
||||||
onProviderChange={setSelectedProviderId}
|
onProviderChange={setSelectedProviderId}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ import React, { useEffect, useMemo } from 'react';
|
||||||
import { Label } from '@renderer/components/ui/label';
|
import { Label } from '@renderer/components/ui/label';
|
||||||
import { useEffectiveCliProviderStatus } from '@renderer/hooks/useEffectiveCliProviderStatus';
|
import { useEffectiveCliProviderStatus } from '@renderer/hooks/useEffectiveCliProviderStatus';
|
||||||
import { cn } from '@renderer/lib/utils';
|
import { cn } from '@renderer/lib/utils';
|
||||||
import { getTeamEffortSelectorPresentation } from '@renderer/utils/teamEffortOptions';
|
import {
|
||||||
|
getAvailableTeamEffortValue,
|
||||||
|
getTeamEffortSelectorPresentation,
|
||||||
|
} from '@renderer/utils/teamEffortOptions';
|
||||||
import { Brain } from 'lucide-react';
|
import { Brain } from 'lucide-react';
|
||||||
|
|
||||||
import type { TeamProviderId } from '@shared/types';
|
import type { TeamProviderId } from '@shared/types';
|
||||||
|
|
@ -33,6 +36,13 @@ export const EffortLevelSelector: React.FC<EffortLevelSelectorProps> = ({
|
||||||
providerStatus,
|
providerStatus,
|
||||||
});
|
});
|
||||||
const effortOptions = presentation.options;
|
const effortOptions = presentation.options;
|
||||||
|
const displayValue = getAvailableTeamEffortValue({
|
||||||
|
providerId,
|
||||||
|
model,
|
||||||
|
limitContext,
|
||||||
|
providerStatus,
|
||||||
|
value,
|
||||||
|
});
|
||||||
const validValues = useMemo(
|
const validValues = useMemo(
|
||||||
() => new Set(effortOptions.map((option) => option.value)),
|
() => new Set(effortOptions.map((option) => option.value)),
|
||||||
[effortOptions]
|
[effortOptions]
|
||||||
|
|
@ -59,13 +69,13 @@ export const EffortLevelSelector: React.FC<EffortLevelSelectorProps> = ({
|
||||||
<button
|
<button
|
||||||
key={opt.value || '__default__'}
|
key={opt.value || '__default__'}
|
||||||
type="button"
|
type="button"
|
||||||
id={opt.value === value ? id : undefined}
|
id={opt.value === displayValue ? id : undefined}
|
||||||
disabled={presentation.disabled}
|
disabled={presentation.disabled}
|
||||||
className={cn(
|
className={cn(
|
||||||
'rounded-[3px] px-3 py-1 text-xs font-medium transition-colors',
|
'rounded-[3px] px-3 py-1 text-xs font-medium transition-colors',
|
||||||
presentation.disabled
|
presentation.disabled
|
||||||
? 'cursor-not-allowed text-[var(--color-text-muted)] opacity-70'
|
? 'cursor-not-allowed text-[var(--color-text-muted)] opacity-70'
|
||||||
: value === opt.value
|
: displayValue === opt.value
|
||||||
? 'bg-[var(--color-surface-raised)] text-[var(--color-text)] shadow-sm'
|
? 'bg-[var(--color-surface-raised)] text-[var(--color-text)] shadow-sm'
|
||||||
: 'text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]'
|
: 'text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]'
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ import { normalizePath } from '@renderer/utils/pathNormalize';
|
||||||
import { nameColorSet } from '@renderer/utils/projectColor';
|
import { nameColorSet } from '@renderer/utils/projectColor';
|
||||||
import { resolveUiOwnedProviderBackendId } from '@renderer/utils/providerBackendIdentity';
|
import { resolveUiOwnedProviderBackendId } from '@renderer/utils/providerBackendIdentity';
|
||||||
import { refreshCliStatusForCurrentMode } from '@renderer/utils/refreshCliStatus';
|
import { refreshCliStatusForCurrentMode } from '@renderer/utils/refreshCliStatus';
|
||||||
|
import { getAvailableTeamEffortValue } from '@renderer/utils/teamEffortOptions';
|
||||||
import {
|
import {
|
||||||
getTeamModelSelectionError,
|
getTeamModelSelectionError,
|
||||||
normalizeExplicitTeamModelForUi,
|
normalizeExplicitTeamModelForUi,
|
||||||
|
|
@ -1081,6 +1082,24 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
[codexRuntimeSelection, selectedFastMode, selectedProviderId]
|
[codexRuntimeSelection, selectedFastMode, selectedProviderId]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const selectedEffortForCurrentSelection = useMemo(
|
||||||
|
() =>
|
||||||
|
getAvailableTeamEffortValue({
|
||||||
|
providerId: selectedProviderId,
|
||||||
|
model: selectedModel,
|
||||||
|
limitContext: effectiveAnthropicRuntimeLimitContext,
|
||||||
|
providerStatus: runtimeProviderStatusById.get(selectedProviderId),
|
||||||
|
value: selectedEffort,
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
|
runtimeProviderStatusById,
|
||||||
|
selectedEffort,
|
||||||
|
selectedModel,
|
||||||
|
selectedProviderId,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSchedule && schedule) {
|
if (isSchedule && schedule) {
|
||||||
const nextHydrationKey = `${schedule.id}:${schedule.updatedAt ?? ''}`;
|
const nextHydrationKey = `${schedule.id}:${schedule.updatedAt ?? ''}`;
|
||||||
|
|
@ -1107,13 +1126,13 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
selectedModel,
|
selectedModel,
|
||||||
limitContext: effectiveAnthropicRuntimeLimitContext,
|
limitContext: effectiveAnthropicRuntimeLimitContext,
|
||||||
}),
|
}),
|
||||||
selectedEffort,
|
selectedEffort: selectedEffortForCurrentSelection,
|
||||||
selectedFastMode,
|
selectedFastMode,
|
||||||
providerFastModeDefault: anthropicProviderFastModeDefault,
|
providerFastModeDefault: anthropicProviderFastModeDefault,
|
||||||
runtimeCapabilities: runtimeProviderStatusById.get('anthropic')?.runtimeCapabilities,
|
runtimeCapabilities: runtimeProviderStatusById.get('anthropic')?.runtimeCapabilities,
|
||||||
})
|
})
|
||||||
: {
|
: {
|
||||||
nextEffort: selectedEffort,
|
nextEffort: selectedEffortForCurrentSelection,
|
||||||
effortResetReason: null,
|
effortResetReason: null,
|
||||||
...reconcileCodexRuntimeSelections({
|
...reconcileCodexRuntimeSelections({
|
||||||
selection:
|
selection:
|
||||||
|
|
@ -1139,7 +1158,11 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
};
|
};
|
||||||
|
|
||||||
const notices: string[] = [];
|
const notices: string[] = [];
|
||||||
if (reconciliation.nextEffort !== selectedEffort) {
|
if (selectedEffortForCurrentSelection !== selectedEffort) {
|
||||||
|
setSelectedEffortRaw(selectedEffortForCurrentSelection);
|
||||||
|
localStorage.setItem('team:lastSelectedEffort', selectedEffortForCurrentSelection);
|
||||||
|
}
|
||||||
|
if (reconciliation.nextEffort !== selectedEffortForCurrentSelection) {
|
||||||
setSelectedEffortRaw(reconciliation.nextEffort);
|
setSelectedEffortRaw(reconciliation.nextEffort);
|
||||||
localStorage.setItem('team:lastSelectedEffort', reconciliation.nextEffort);
|
localStorage.setItem('team:lastSelectedEffort', reconciliation.nextEffort);
|
||||||
if (reconciliation.effortResetReason) {
|
if (reconciliation.effortResetReason) {
|
||||||
|
|
@ -1163,6 +1186,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
runtimeProviderStatusById,
|
runtimeProviderStatusById,
|
||||||
savedLaunchProviderBackendId,
|
savedLaunchProviderBackendId,
|
||||||
selectedEffort,
|
selectedEffort,
|
||||||
|
selectedEffortForCurrentSelection,
|
||||||
selectedFastMode,
|
selectedFastMode,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
|
|
@ -1173,7 +1197,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
|
|
||||||
const selectedModelChecksByProvider = useMemo(() => {
|
const selectedModelChecksByProvider = useMemo(() => {
|
||||||
const modelsByProvider = new Map<TeamProviderId, TeamProvisioningModelCheckRequest[]>();
|
const modelsByProvider = new Map<TeamProviderId, TeamProvisioningModelCheckRequest[]>();
|
||||||
const leadEffort = (selectedEffort as EffortLevel | '') || undefined;
|
const leadEffort = (selectedEffortForCurrentSelection as EffortLevel | '') || undefined;
|
||||||
const addModel = (
|
const addModel = (
|
||||||
providerId: TeamProviderId,
|
providerId: TeamProviderId,
|
||||||
model: string | undefined,
|
model: string | undefined,
|
||||||
|
|
@ -1237,7 +1261,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
effectiveLeadRuntimeModel,
|
effectiveLeadRuntimeModel,
|
||||||
effectiveMemberDrafts,
|
effectiveMemberDrafts,
|
||||||
runtimeProviderStatusById,
|
runtimeProviderStatusById,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
]);
|
]);
|
||||||
|
|
@ -1256,7 +1280,8 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
previousProviderId &&
|
previousProviderId &&
|
||||||
(previousProviderId !== selectedProviderId ||
|
(previousProviderId !== selectedProviderId ||
|
||||||
previousLeadModel !== currentLeadDisplayModel ||
|
previousLeadModel !== currentLeadDisplayModel ||
|
||||||
(previousLeadEffort ?? '') !== ((selectedEffort as EffortLevel | '') || ''))
|
(previousLeadEffort ?? '') !==
|
||||||
|
((selectedEffortForCurrentSelection as EffortLevel | '') || ''))
|
||||||
) {
|
) {
|
||||||
notes.push({
|
notes.push({
|
||||||
key: 'lead',
|
key: 'lead',
|
||||||
|
|
@ -1264,7 +1289,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
message: `${formatTeamModelSummary(
|
message: `${formatTeamModelSummary(
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
currentLeadDisplayModel,
|
currentLeadDisplayModel,
|
||||||
(selectedEffort as EffortLevel) || undefined
|
(selectedEffortForCurrentSelection as EffortLevel) || undefined
|
||||||
)} instead of ${formatTeamModelSummary(
|
)} instead of ${formatTeamModelSummary(
|
||||||
previousProviderId,
|
previousProviderId,
|
||||||
previousLeadModel,
|
previousLeadModel,
|
||||||
|
|
@ -1300,7 +1325,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
member,
|
member,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
currentLeadDisplayModel,
|
currentLeadDisplayModel,
|
||||||
(selectedEffort as EffortLevel) || undefined
|
(selectedEffortForCurrentSelection as EffortLevel) || undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -1358,7 +1383,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
effectiveLeadRuntimeModel,
|
effectiveLeadRuntimeModel,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
members,
|
members,
|
||||||
effectiveMemberDrafts,
|
effectiveMemberDrafts,
|
||||||
]);
|
]);
|
||||||
|
|
@ -1907,8 +1932,8 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
if (model) args.push('--model', model);
|
if (model) args.push('--model', model);
|
||||||
const effectiveEffort =
|
const effectiveEffort =
|
||||||
selectedProviderId === 'anthropic'
|
selectedProviderId === 'anthropic'
|
||||||
? selectedEffort || anthropicRuntimeSelection?.defaultEffort || ''
|
? selectedEffortForCurrentSelection || anthropicRuntimeSelection?.defaultEffort || ''
|
||||||
: selectedEffort;
|
: selectedEffortForCurrentSelection;
|
||||||
if (effectiveEffort) args.push('--effort', effectiveEffort);
|
if (effectiveEffort) args.push('--effort', effectiveEffort);
|
||||||
if (selectedProviderId === 'anthropic') {
|
if (selectedProviderId === 'anthropic') {
|
||||||
const fastSettings = anthropicFastModeResolution?.resolvedFastMode
|
const fastSettings = anthropicFastModeResolution?.resolvedFastMode
|
||||||
|
|
@ -1927,7 +1952,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
skipPermissions,
|
skipPermissions,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
effectiveAnthropicRuntimeLimitContext,
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
runtimeProviderStatusById,
|
runtimeProviderStatusById,
|
||||||
]);
|
]);
|
||||||
|
|
@ -1947,7 +1972,9 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
}
|
}
|
||||||
summary.push(`Provider: ${getProviderLabel(selectedProviderId)}`);
|
summary.push(`Provider: ${getProviderLabel(selectedProviderId)}`);
|
||||||
if (selectedModel) summary.push(`Model: ${selectedModel}`);
|
if (selectedModel) summary.push(`Model: ${selectedModel}`);
|
||||||
if (selectedEffort) summary.push(`Effort: ${selectedEffort}`);
|
if (selectedEffortForCurrentSelection) {
|
||||||
|
summary.push(`Effort: ${selectedEffortForCurrentSelection}`);
|
||||||
|
}
|
||||||
if (selectedProviderId === 'anthropic' || selectedProviderId === 'codex') {
|
if (selectedProviderId === 'anthropic' || selectedProviderId === 'codex') {
|
||||||
if (selectedFastMode === 'on') summary.push('Fast mode');
|
if (selectedFastMode === 'on') summary.push('Fast mode');
|
||||||
else if (selectedFastMode === 'off') summary.push('Fast disabled');
|
else if (selectedFastMode === 'off') summary.push('Fast disabled');
|
||||||
|
|
@ -1969,7 +1996,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
promptDraft.value,
|
promptDraft.value,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
selectedEffort,
|
selectedEffortForCurrentSelection,
|
||||||
selectedFastMode,
|
selectedFastMode,
|
||||||
anthropicProviderFastModeDefault,
|
anthropicProviderFastModeDefault,
|
||||||
effectiveAnthropicRuntimeLimitContext,
|
effectiveAnthropicRuntimeLimitContext,
|
||||||
|
|
@ -2222,7 +2249,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
runtimeProviderStatusById.get(selectedProviderId)
|
runtimeProviderStatusById.get(selectedProviderId)
|
||||||
),
|
),
|
||||||
effort: (selectedEffort as EffortLevel) || undefined,
|
effort: (selectedEffortForCurrentSelection as EffortLevel) || undefined,
|
||||||
fastMode:
|
fastMode:
|
||||||
selectedProviderId === 'anthropic' || selectedProviderId === 'codex'
|
selectedProviderId === 'anthropic' || selectedProviderId === 'codex'
|
||||||
? selectedFastMode
|
? selectedFastMode
|
||||||
|
|
@ -2258,8 +2285,8 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
selectedProviderId,
|
selectedProviderId,
|
||||||
runtimeProviderStatusById.get(selectedProviderId)
|
runtimeProviderStatusById.get(selectedProviderId)
|
||||||
);
|
);
|
||||||
const explicitScheduleEffort = selectedEffort
|
const explicitScheduleEffort = selectedEffortForCurrentSelection
|
||||||
? (selectedEffort as EffortLevel)
|
? (selectedEffortForCurrentSelection as EffortLevel)
|
||||||
: undefined;
|
: undefined;
|
||||||
const scheduleEffort =
|
const scheduleEffort =
|
||||||
selectedProviderId === 'anthropic'
|
selectedProviderId === 'anthropic'
|
||||||
|
|
@ -2687,14 +2714,14 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
defaultProviderId={selectedProviderId}
|
defaultProviderId={selectedProviderId}
|
||||||
inheritedProviderId={selectedProviderId}
|
inheritedProviderId={selectedProviderId}
|
||||||
inheritedModel={selectedModel}
|
inheritedModel={selectedModel}
|
||||||
inheritedEffort={(selectedEffort as EffortLevel) || undefined}
|
inheritedEffort={(selectedEffortForCurrentSelection as EffortLevel) || undefined}
|
||||||
inheritModelSettingsByDefault
|
inheritModelSettingsByDefault
|
||||||
lockProviderModel={syncModelsWithLead}
|
lockProviderModel={syncModelsWithLead}
|
||||||
forceInheritedModelSettings={syncModelsWithLead}
|
forceInheritedModelSettings={syncModelsWithLead}
|
||||||
modelLockReason="This teammate is synced with the lead model. Turn off sync to set a custom provider, model, or effort."
|
modelLockReason="This teammate is synced with the lead model. Turn off sync to set a custom provider, model, or effort."
|
||||||
providerId={selectedProviderId}
|
providerId={selectedProviderId}
|
||||||
model={selectedModel}
|
model={selectedModel}
|
||||||
effort={(selectedEffort as EffortLevel) || undefined}
|
effort={(selectedEffortForCurrentSelection as EffortLevel) || undefined}
|
||||||
limitContext={effectiveAnthropicRuntimeLimitContext}
|
limitContext={effectiveAnthropicRuntimeLimitContext}
|
||||||
leadProviderNoticeById={teammateRuntimeProviderNoticeById}
|
leadProviderNoticeById={teammateRuntimeProviderNoticeById}
|
||||||
onProviderChange={setSelectedProviderId}
|
onProviderChange={setSelectedProviderId}
|
||||||
|
|
@ -2893,7 +2920,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<EffortLevelSelector
|
<EffortLevelSelector
|
||||||
value={selectedEffort}
|
value={selectedEffortForCurrentSelection}
|
||||||
onValueChange={setSelectedEffort}
|
onValueChange={setSelectedEffort}
|
||||||
id="dialog-effort"
|
id="dialog-effort"
|
||||||
providerId={selectedProviderId}
|
providerId={selectedProviderId}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { getTeamEffortOptions, getTeamEffortSelectorPresentation } from '../teamEffortOptions';
|
import {
|
||||||
|
getAvailableTeamEffortValue,
|
||||||
|
getTeamEffortOptions,
|
||||||
|
getTeamEffortSelectorPresentation,
|
||||||
|
} from '../teamEffortOptions';
|
||||||
|
|
||||||
import type { CliProviderStatus } from '@shared/types';
|
import type { CliProviderStatus } from '@shared/types';
|
||||||
|
|
||||||
|
|
@ -326,4 +330,29 @@ describe('team effort options', () => {
|
||||||
unavailableText: 'Effort is unavailable for this model.',
|
unavailableText: 'Effort is unavailable for this model.',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('omits stale Anthropic effort when the selected model has no effort support', () => {
|
||||||
|
const providerStatus = createProviderStatus('anthropic', {
|
||||||
|
id: 'haiku',
|
||||||
|
launchModel: 'claude-haiku-4-5-20251001',
|
||||||
|
displayName: 'Haiku 4.5',
|
||||||
|
hidden: false,
|
||||||
|
supportedReasoningEfforts: [],
|
||||||
|
defaultReasoningEffort: null,
|
||||||
|
inputModalities: ['text', 'image'],
|
||||||
|
supportsPersonality: false,
|
||||||
|
isDefault: false,
|
||||||
|
upgrade: false,
|
||||||
|
source: 'anthropic-models-api',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getAvailableTeamEffortValue({
|
||||||
|
providerId: 'anthropic',
|
||||||
|
model: 'claude-haiku-4-5-20251001',
|
||||||
|
providerStatus,
|
||||||
|
value: 'medium',
|
||||||
|
})
|
||||||
|
).toBe('');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -213,3 +213,19 @@ export function getTeamEffortSelectorPresentation(params: {
|
||||||
canValidateValue: true,
|
canValidateValue: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAvailableTeamEffortValue(params: {
|
||||||
|
providerId?: TeamProviderId;
|
||||||
|
model?: string;
|
||||||
|
limitContext?: boolean;
|
||||||
|
providerStatus?: CliProviderStatus | null;
|
||||||
|
value?: string | null;
|
||||||
|
}): string {
|
||||||
|
const value = params.value?.trim() ?? '';
|
||||||
|
if (!value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const presentation = getTeamEffortSelectorPresentation(params);
|
||||||
|
return presentation.disabled && presentation.canValidateValue ? '' : value;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { act } from 'react';
|
import React, { act } from 'react';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
||||||
|
|
||||||
import { EffortLevelSelector } from '@renderer/components/team/dialogs/EffortLevelSelector';
|
import { EffortLevelSelector } from '@renderer/components/team/dialogs/EffortLevelSelector';
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import type { CliProviderStatus } from '@shared/types';
|
import type { CliProviderStatus } from '@shared/types';
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue