@@ -824,22 +824,24 @@ function ScanRunSettings({ scan, onSave, references, referencesLoading, referenc
824824 const [ saving , setSaving ] = useState ( false ) ;
825825 const [ error , setError ] = useState ( null ) ;
826826 const current = runSettingsDraft ( scan ) ;
827- const activeDraft = draft || current ;
827+ const activeDraft = mergeRunSettingsDraft ( current , draft ) ;
828828 const payload = draft ? runSettingsPayload ( draft , current ) : { } ;
829829 const dirty = Object . keys ( payload ) . length > 0 ;
830- const jobLimitValid =
831- ! activeDraft . job_limit . trim ( ) ||
832- ( / ^ \d + $ / . test ( activeDraft . job_limit . trim ( ) ) &&
833- Number ( activeDraft . job_limit ) >= 1 &&
834- Number ( activeDraft . job_limit ) <= 1_000_000 ) ;
830+ const jobLimit = activeDraft . job_limit . trim ( ) ;
831+ const jobLimitValid = ! jobLimit || ( / ^ \d + $ / . test ( jobLimit ) && Number ( jobLimit ) >= 1 && Number ( jobLimit ) <= 1_000_000 ) ;
835832 const valid =
836833 jobLimitValid && ! ! references && modelConfigurationIsValid ( activeDraft , references . providers , references . catalog ) ;
837834 useUnsavedChangesPrompt ( editing && ( dirty || saving ) ) ;
838835
839836 const open = ( ) => {
840837 const currentDraft = runSettingsDraft ( scan ) ;
841838 setDraft (
842- references ? modelConfigurationForCatalog ( currentDraft , references . providers , references . catalog ) : currentDraft
839+ references
840+ ? mergeRunSettingsDraft (
841+ currentDraft ,
842+ modelConfigurationForCatalog ( currentDraft , references . providers , references . catalog )
843+ )
844+ : currentDraft
843845 ) ;
844846 setError ( null ) ;
845847 setEditing ( true ) ;
@@ -950,11 +952,7 @@ function ScanRunSettings({ scan, onSave, references, referencesLoading, referenc
950952 < ModelConfiguration
951953 value = { activeDraft }
952954 onChange = { ( nextDraft ) =>
953- setDraft ( ( currentDraft ) => ( {
954- ...currentDraft ,
955- ...nextDraft ,
956- job_limit : nextDraft . job_limit ?? currentDraft . job_limit ,
957- } ) )
955+ setDraft ( ( currentDraft ) => mergeRunSettingsDraft ( currentDraft || current , nextDraft ) )
958956 }
959957 providers = { references ?. providers || [ ] }
960958 catalog = { references ?. catalog || { } }
@@ -1043,7 +1041,7 @@ function ScanRunSettings({ scan, onSave, references, referencesLoading, referenc
10431041 ) ;
10441042}
10451043
1046- function runSettingsDraft ( scan ) {
1044+ export function runSettingsDraft ( scan = { } ) {
10471045 return {
10481046 model : scan . model || '' ,
10491047 model_provider : scan . modelProvider || 'openrouter' ,
@@ -1053,14 +1051,42 @@ function runSettingsDraft(scan) {
10531051 } ;
10541052}
10551053
1056- function runSettingsPayload ( draft , current ) {
1054+ function runSettingsValue ( value , fallback ) {
1055+ if ( value === undefined ) return fallback ;
1056+ if ( value === null ) return '' ;
1057+ return typeof value === 'string' ? value : String ( value ) ;
1058+ }
1059+
1060+ export function mergeRunSettingsDraft ( current = { } , patch = { } ) {
1061+ const base = {
1062+ model : runSettingsValue ( current ?. model , '' ) ,
1063+ model_provider : runSettingsValue ( current ?. model_provider , 'openrouter' ) ,
1064+ thinking_effort : runSettingsValue ( current ?. thinking_effort , 'medium' ) ,
1065+ harness : runSettingsValue ( current ?. harness , 'codex' ) ,
1066+ job_limit : runSettingsValue ( current ?. job_limit , '' ) ,
1067+ } ;
1068+ return {
1069+ model : runSettingsValue ( patch ?. model , base . model ) ,
1070+ model_provider : runSettingsValue ( patch ?. model_provider , base . model_provider ) ,
1071+ thinking_effort : runSettingsValue ( patch ?. thinking_effort , base . thinking_effort ) ,
1072+ harness : runSettingsValue ( patch ?. harness , base . harness ) ,
1073+ job_limit : runSettingsValue ( patch ?. job_limit , base . job_limit ) ,
1074+ } ;
1075+ }
1076+
1077+ export function runSettingsPayload ( draft , current ) {
1078+ const normalizedCurrent = mergeRunSettingsDraft ( { } , current ) ;
1079+ const normalizedDraft = mergeRunSettingsDraft ( normalizedCurrent , draft ) ;
10571080 const payload = { } ;
1058- const model = draft . model . trim ( ) ;
1059- if ( model !== current . model ) payload . model = model ;
1060- if ( draft . model_provider !== current . model_provider ) payload . model_provider = draft . model_provider ;
1061- if ( draft . thinking_effort !== current . thinking_effort ) payload . thinking_effort = draft . thinking_effort ;
1062- if ( draft . harness !== current . harness ) payload . harness = draft . harness ;
1063- if ( draft . job_limit !== current . job_limit ) payload . jobLimit = draft . job_limit . trim ( ) ? Number ( draft . job_limit ) : null ;
1081+ const model = normalizedDraft . model . trim ( ) ;
1082+ const jobLimit = normalizedDraft . job_limit . trim ( ) ;
1083+ if ( model !== normalizedCurrent . model ) payload . model = model ;
1084+ if ( normalizedDraft . model_provider !== normalizedCurrent . model_provider )
1085+ payload . model_provider = normalizedDraft . model_provider ;
1086+ if ( normalizedDraft . thinking_effort !== normalizedCurrent . thinking_effort )
1087+ payload . thinking_effort = normalizedDraft . thinking_effort ;
1088+ if ( normalizedDraft . harness !== normalizedCurrent . harness ) payload . harness = normalizedDraft . harness ;
1089+ if ( normalizedDraft . job_limit !== normalizedCurrent . job_limit ) payload . jobLimit = jobLimit ? Number ( jobLimit ) : null ;
10641090 return payload ;
10651091}
10661092
0 commit comments