@@ -301,9 +301,30 @@ async fn main() -> anyhow::Result<()> {
301301 } )
302302 . await ?;
303303 println ! ( "{}" , doctor_report. to_text( ) ) ;
304- if doctor_report. summary . error > 0 {
304+ let blocking_errors: Vec < & doctor:: DoctorCheck > = doctor_report
305+ . checks
306+ . iter ( )
307+ . filter ( |c| is_onboard_blocking_doctor_error ( c) )
308+ . collect ( ) ;
309+ if !blocking_errors. is_empty ( ) {
310+ eprintln ! ( "onboard blocked by critical setup errors:" ) ;
311+ for c in & blocking_errors {
312+ eprintln ! ( "- {}: {}" , c. id, c. message) ;
313+ }
305314 std:: process:: exit ( 1 ) ;
306315 }
316+ let non_blocking_errors = doctor_report
317+ . checks
318+ . iter ( )
319+ . filter ( |c| c. status == doctor:: CheckStatus :: Error )
320+ . count ( )
321+ . saturating_sub ( blocking_errors. len ( ) ) ;
322+ if non_blocking_errors > 0 {
323+ eprintln ! (
324+ "onboard: continuing despite {} non-blocking doctor error(s)" ,
325+ non_blocking_errors
326+ ) ;
327+ }
307328
308329 std:: fs:: create_dir_all ( & workspace)
309330 . with_context ( || format ! ( "create workspace: {}" , workspace. display( ) ) ) ?;
@@ -347,15 +368,25 @@ async fn main() -> anyhow::Result<()> {
347368 let agent = rexos:: agent:: AgentRuntime :: new ( memory, llms, router) ;
348369
349370 let session_id = rexos:: harness:: resolve_session_id ( & workspace) ?;
350- let out = agent
371+ let out = match agent
351372 . run_session (
352373 workspace. clone ( ) ,
353374 & session_id,
354375 None ,
355376 & prompt,
356377 rexos:: router:: TaskKind :: Coding ,
357378 )
358- . await ?;
379+ . await
380+ {
381+ Ok ( out) => out,
382+ Err ( e) => {
383+ eprintln ! ( "onboard: first agent run failed: {e}" ) ;
384+ eprintln ! (
385+ "hint: run `ollama list` and set [providers.ollama].default_model in ~/.rexos/config.toml to an available chat model"
386+ ) ;
387+ return Err ( e) ;
388+ }
389+ } ;
359390 println ! ( "{out}" ) ;
360391 eprintln ! ( "[loopforge] session_id={session_id}" ) ;
361392 println ! ( "onboard done (first agent run completed)" ) ;
@@ -703,6 +734,13 @@ fn select_onboard_model(preferred: &str, available: &[String]) -> Option<String>
703734 Some ( available[ 0 ] . clone ( ) )
704735}
705736
737+ fn is_onboard_blocking_doctor_error ( check : & doctor:: DoctorCheck ) -> bool {
738+ if check. status != doctor:: CheckStatus :: Error {
739+ return false ;
740+ }
741+ check. id == "config.parse" || check. id . starts_with ( "router." )
742+ }
743+
706744async fn fetch_openai_compat_models ( base_url : & str , timeout_ms : u64 ) -> anyhow:: Result < Vec < String > > {
707745 let endpoint = format ! ( "{}/models" , base_url. trim_end_matches( '/' ) ) ;
708746 let client = reqwest:: Client :: builder ( )
@@ -1149,4 +1187,38 @@ edition = "2021"
11491187 select_onboard_model ( "llama3.2" , & [ "nomic-embed-text:latest" . to_string ( ) ] ) ;
11501188 assert_eq ! ( selected. as_deref( ) , Some ( "nomic-embed-text:latest" ) ) ;
11511189 }
1190+
1191+ #[ test]
1192+ fn onboard_blocks_config_and_router_errors ( ) {
1193+ let config_error = doctor:: DoctorCheck {
1194+ id : "config.parse" . to_string ( ) ,
1195+ status : doctor:: CheckStatus :: Error ,
1196+ message : "bad toml" . to_string ( ) ,
1197+ } ;
1198+ let router_error = doctor:: DoctorCheck {
1199+ id : "router.coding.provider" . to_string ( ) ,
1200+ status : doctor:: CheckStatus :: Error ,
1201+ message : "unknown provider" . to_string ( ) ,
1202+ } ;
1203+
1204+ assert ! ( is_onboard_blocking_doctor_error( & config_error) ) ;
1205+ assert ! ( is_onboard_blocking_doctor_error( & router_error) ) ;
1206+ }
1207+
1208+ #[ test]
1209+ fn onboard_does_not_block_non_critical_errors ( ) {
1210+ let git_error = doctor:: DoctorCheck {
1211+ id : "tools.git" . to_string ( ) ,
1212+ status : doctor:: CheckStatus :: Error ,
1213+ message : "git not found" . to_string ( ) ,
1214+ } ;
1215+ let browser_warn = doctor:: DoctorCheck {
1216+ id : "browser.chromium" . to_string ( ) ,
1217+ status : doctor:: CheckStatus :: Warn ,
1218+ message : "missing" . to_string ( ) ,
1219+ } ;
1220+
1221+ assert ! ( !is_onboard_blocking_doctor_error( & git_error) ) ;
1222+ assert ! ( !is_onboard_blocking_doctor_error( & browser_warn) ) ;
1223+ }
11521224}
0 commit comments