(path: &Path)
| 29 | } |
| 30 | |
| 31 | pub(super) fn load_settings_file(path: &Path) -> Result<Option<DroidEntry>> { |
| 32 | let content = match fs::read_to_string(path) { |
| 33 | Ok(content) => content, |
| 34 | Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(None), |
| 35 | Err(error) => return Err(error.into()), |
| 36 | }; |
| 37 | let value = serde_json::from_str::<Value>(&content).map_err(|error| { |
| 38 | crate::cli_error(format!( |
| 39 | "failed to parse Droid settings {}: {error}", |
| 40 | path.display() |
| 41 | )) |
| 42 | })?; |
| 43 | let Some(settings) = value.as_object() else { |
| 44 | return Ok(None); |
| 45 | }; |
| 46 | let Some(usage) = parse_token_usage(settings.get("tokenUsage")) else { |
| 47 | return Ok(None); |
| 48 | }; |
| 49 | let provider = normalize_droid_provider(string_field(settings, "providerLock").as_deref()); |
| 50 | let model = if let Some(model) = string_field(settings, "model") { |
| 51 | normalize_droid_model_name(&model) |
| 52 | } else { |
| 53 | extract_model_from_sidecar_jsonl(path)? |
| 54 | .unwrap_or_else(|| default_model_from_provider(&provider).to_string()) |
| 55 | }; |
| 56 | let model = if model.is_empty() { |
| 57 | default_model_from_provider(&provider).to_string() |
| 58 | } else { |
| 59 | model |
| 60 | }; |
| 61 | let provider = if provider == "unknown" { |
| 62 | infer_droid_provider_from_model(&model).to_string() |
| 63 | } else { |
| 64 | provider |
| 65 | }; |
| 66 | let Some((timestamp, timestamp_text)) = settings_timestamp(settings, path) else { |
| 67 | return Ok(None); |
| 68 | }; |
| 69 | let session_id = path |
| 70 | .file_name() |
| 71 | .and_then(|name| name.to_str()) |
| 72 | .and_then(|name| name.strip_suffix(".settings.json")) |
| 73 | .unwrap_or("unknown") |
| 74 | .to_string(); |
| 75 | Ok(Some(DroidEntry { |
| 76 | timestamp, |
| 77 | timestamp_text, |
| 78 | session_id, |
| 79 | model, |
| 80 | provider, |
| 81 | usage: TokenUsageRaw { |
| 82 | input_tokens: usage.input_tokens, |
| 83 | output_tokens: usage.output_tokens, |
| 84 | cache_creation_input_tokens: usage.cache_creation_tokens, |
| 85 | cache_read_input_tokens: usage.cache_read_tokens, |
| 86 | speed: None, |
| 87 | cache_creation: None, |
| 88 | }, |
no test coverage detected