Try every raw candidate × every JSON value it yields against the schema; return the first schema-valid object, else the best parseable-but-invalid object (for repair).
(candidates: &[String], schema: &Value)
| 1060 | /// Try every raw candidate × every JSON value it yields against the schema; return the |
| 1061 | /// first schema-valid object, else the best parseable-but-invalid object (for repair). |
| 1062 | fn resolve_structured(candidates: &[String], schema: &Value) -> StructuredResolution { |
| 1063 | let mut invalid: Option<(String, Vec<String>)> = None; |
| 1064 | let mut raw_seen: Option<String> = None; |
| 1065 | for raw in candidates { |
| 1066 | if raw_seen.is_none() && !raw.trim().is_empty() { |
| 1067 | raw_seen = Some(raw.clone()); |
| 1068 | } |
| 1069 | for value in extract_all_json_values(raw) { |
| 1070 | match validate_against_schema(&value, schema) { |
| 1071 | Ok(()) => { |
| 1072 | return StructuredResolution { |
| 1073 | valid: Some((value, raw.clone())), |
| 1074 | invalid, |
| 1075 | raw_seen, |
| 1076 | }; |
| 1077 | } |
| 1078 | Err(errors) => { |
| 1079 | if invalid.is_none() { |
| 1080 | invalid = Some((raw.clone(), errors)); |
| 1081 | } |
| 1082 | } |
| 1083 | } |
| 1084 | } |
| 1085 | } |
| 1086 | StructuredResolution { |
| 1087 | valid: None, |
| 1088 | invalid, |
| 1089 | raw_seen, |
| 1090 | } |
| 1091 | } |
| 1092 | |
| 1093 | /// UTF-8-safe truncation to at most `max` bytes (never splits a multibyte char — |
| 1094 | /// repair prompts echo arbitrary model output, including CJK). |
no test coverage detected