(name: &str, model: &str, address: &str)
| 459 | } |
| 460 | |
| 461 | async fn run_direct_worker(name: &str, model: &str, address: &str) -> String { |
| 462 | let force_cpu = should_force_cpu(); |
| 463 | let args = Args { |
| 464 | address: address.to_string(), |
| 465 | mode: Mode::Worker, |
| 466 | name: Some(name.to_string()), |
| 467 | model: model.to_string(), |
| 468 | model_type: ModelType::TextModel, |
| 469 | cpu: force_cpu, |
| 470 | ..Default::default() |
| 471 | }; |
| 472 | |
| 473 | update_status("loading", "Downloading model...", 0.0); |
| 474 | log_mobile("[cake-mobile] creating context..."); |
| 475 | |
| 476 | // Context::from_args downloads / loads large model weight files. Run it |
| 477 | // on a dedicated blocking thread so the Tokio async runtime stays live. |
| 478 | let ctx_result = tokio::task::spawn_blocking(move || Context::from_args(args)).await; |
| 479 | let mut ctx = match ctx_result { |
| 480 | Ok(Ok(ctx)) => { |
| 481 | log_mobile(&format!("[cake-mobile] context created, device={:?}", ctx.device)); |
| 482 | ctx |
| 483 | } |
| 484 | Ok(Err(e)) => { |
| 485 | update_status("error", &format!("Failed: {}", e), 0.0); |
| 486 | return format!("context creation failed: {}", e); |
| 487 | } |
| 488 | Err(join_err) => { |
| 489 | let msg = format!("context loading task failed: {}", join_err); |
| 490 | update_status("error", &msg, 0.0); |
| 491 | return msg; |
| 492 | } |
| 493 | }; |
| 494 | |
| 495 | update_status("serving", "Ready — serving inference", 1.0); |
| 496 | run_text_worker(&mut ctx).await |
| 497 | } |
| 498 | |
| 499 | // --------------------------------------------------------------------------- |
| 500 | // Plain C exports — used by Kotlin/Native cinterop on iOS |
no test coverage detected