{
  "cases": [
    {
      "expected": {
        "code": "auth_failed",
        "detail": "invalid key"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "https://api.deepseek.com/v1",
        "body": "{\"error\":{\"message\":\"invalid key\"}}",
        "requestedUrl": "https://api.deepseek.com/v1/models",
        "status": 401
      }
    },
    {
      "expected": {
        "code": "auth_failed",
        "detail": "HTTP 403"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "https://api.deepseek.com/v1",
        "body": "{}",
        "requestedUrl": "https://api.deepseek.com/v1/models",
        "status": 403
      }
    },
    {
      "expected": {
        "code": "not_found",
        "requested_url": "https://api.deepseek.com/models",
        "suggested_url": "https://api.deepseek.com/v1"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "https://api.deepseek.com",
        "body": "{}",
        "requestedUrl": "https://api.deepseek.com/models",
        "status": 404
      }
    },
    {
      "expected": {
        "code": "not_found",
        "requested_url": "https://api.deepseek.com/v1/models",
        "suggested_url": null
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "https://api.deepseek.com/v1",
        "body": "{}",
        "requestedUrl": "https://api.deepseek.com/v1/models",
        "status": 404
      }
    },
    {
      "expected": {
        "code": "not_found",
        "requested_url": "https://x.com/v1beta/openai/models",
        "suggested_url": null
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "https://x.com/v1beta/openai",
        "body": "{}",
        "requestedUrl": "https://x.com/v1beta/openai/models",
        "status": 404
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "bad request"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "{\"message\":\"bad request\"}",
        "requestedUrl": "u",
        "status": 400
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "HTTP 429"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "Too Many Requests",
        "requestedUrl": "u",
        "status": 429
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "HTTP 500"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "{}",
        "requestedUrl": "u",
        "status": 500
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "HTTP 502"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "<html>Bad Gateway</html>",
        "requestedUrl": "u",
        "status": 502
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "model not supported"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "{\"error\":\"model not supported\"}",
        "requestedUrl": "u",
        "status": 400
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "from error"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "{\"error\":{\"message\":\"  from error  \"},\"message\":\"from top\"}",
        "requestedUrl": "u",
        "status": 400
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "HTTP 400"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "{\"message\":\"   \"}",
        "requestedUrl": "u",
        "status": 400
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "HTTP 400"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "[{\"error\":{\"message\":\"bad\"}}]",
        "requestedUrl": "u",
        "status": 400
      }
    },
    {
      "expected": {
        "code": "malformed",
        "detail": "很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错"
      },
      "fn": "diagnose",
      "input": {
        "baseUrl": "b",
        "body": "{\"error\":{\"message\":\"很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错很长的报错\"}}",
        "requestedUrl": "u",
        "status": 400
      }
    },
    {
      "expected": "https://api.deepseek.com/v1",
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://api.deepseek.com"
      }
    },
    {
      "expected": "https://api.deepseek.com/v1",
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://api.deepseek.com/"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://api.deepseek.com/v1"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://open.bigmodel.cn/api/paas/v4"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://generativelanguage.googleapis.com/v1beta/openai"
      }
    },
    {
      "expected": "https://x.com/api/v1",
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://x.com/api"
      }
    },
    {
      "expected": "https://x.com/v2beta/openai/v1",
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://x.com/v2beta/openai"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://x.com/v1beta"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://x.com/v1beta/"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": "https://x.com/v1/extra"
      }
    },
    {
      "expected": null,
      "fn": "suggest_url",
      "input": {
        "baseUrl": ""
      }
    },
    {
      "expected": {
        "ok": null
      },
      "fn": "check_required_fields",
      "input": {
        "extra": [
          {
            "key": "appid",
            "value": "123"
          },
          {
            "key": "cluster",
            "value": ""
          }
        ],
        "presetKey": "volc_tts"
      }
    },
    {
      "expected": {
        "error": {
          "code": "missing_extra_field",
          "key": "appid"
        }
      },
      "fn": "check_required_fields",
      "input": {
        "extra": [
          {
            "key": "cluster",
            "value": "volcano_tts"
          }
        ],
        "presetKey": "volc_tts"
      }
    },
    {
      "expected": {
        "error": {
          "code": "missing_extra_field",
          "key": "appid"
        }
      },
      "fn": "check_required_fields",
      "input": {
        "extra": [
          {
            "key": "appid",
            "value": "   "
          }
        ],
        "presetKey": "volc_tts"
      }
    },
    {
      "expected": {
        "ok": null
      },
      "fn": "check_required_fields",
      "input": {
        "extra": [],
        "presetKey": "deepseek"
      }
    },
    {
      "expected": {
        "ok": null
      },
      "fn": "check_required_fields",
      "input": {
        "extra": [],
        "presetKey": null
      }
    },
    {
      "expected": {
        "ok": null
      },
      "fn": "check_required_fields",
      "input": {
        "extra": [],
        "presetKey": "no_such_preset"
      }
    }
  ],
  "crateVersion": "0.1.2",
  "description": "diagnose：HTTP 状态 + 响应体 → 结构化错误（code 判别字段）。401/403 → auth_failed；404 → not_found（requested_url 原样，suggested_url = suggest_url(baseUrl)）；其余 → malformed。detail：响应体是 JSON **对象**时依次取 error.message、error（本身是字符串时）、顶层 message（都须是字符串），去两端空白后非空即用，再取前 300 个字符（按字符数，截断后不再去空白）；响应体不是 JSON、顶层是数组、或都取不到 → 「HTTP <状态码>」。响应体的其余内容不进 detail。suggest_url：去两端空白、去末尾所有 / 后记为 t。t 为空 → null；ends_with_version_segment(t) → null；t + \"/\" 包含 /v1beta/ 或 /v1/ → null；否则返回 t + \"/v1\"。check_required_fields：按 presetKey 在 presets.json 里找预置（找不到、或为 null → 放行，返回 ok）；按 extraFields 的顺序，对 required 为 true 的每一项，取 extra 里**第一条**同 key 的条目，其值去空白后须非空，否则返回这一项的 missing_extra_field（只报第一个缺的）。defaultExtra 不算已填。extra 在用例里写成 [{key, value}]。返回值为空的 Result 在用例里写成 {\"ok\": null}。unreachable 由网络层产生，不在本文件范围。",
  "generatedBy": "cargo xtask gen-spec（期望值由 Rust 参考实现算出，请勿手改）",
  "specVersion": 1,
  "title": "验证错误判定"
}
