发布

  • fix: Demote to non-strict schema instead of losing native path (COG-6271) (#4621)

    frostbyte_neo 发布于 2026-08-22 13:20:35 +00:00

    Description

    Hotfix for the 1.5.x line (base: main), bumping the version to
    1.5.2. Two related litellm_native adapter defects:

    1. Demote, don't disable

    A strict-mode schema rejection — SessionTurnAnalysis (oneOf from its
    discriminated union, one failed request on every answered session
    turn
    ), and DataPoint-derived models like EntityList/RuleSet
    (free-form metadata dict → additionalProperties) — dropped the
    adapter to prompted-JSON and re-paid the failed request per call for the
    process lifetime.

    Now: on a schema-classified BadRequestError, retry the same request
    once with an explicit non-strict json_schema payload (raw
    model_json_schema(), strict: false). Non-strict mode accepts the
    full schema as guidance — no 400 — while conformance is still validated
    app-side against the original Pydantic model. The demotion is remembered
    in a module-level set keyed by (llm_model, response_model.__name__),
    so the failed strict request is paid once per process, not per call.
    Compatible models (the majority, including KnowledgeGraph extraction)
    keep their strict grammar-constrained guarantee completely untouched. If
    non-strict is also rejected, prompted-JSON remains the final fallback.

    2. Route native ValidationErrors to the self-correcting fallback

    The native path validated with model_validate_json and no
    ValidationError handling — a validation failure bubbled into tenacity,
    which blindly re-sent the same prompt (no error feedback) under the
    stop_after_attempt(2) AND stop_after_delay(240) floor: up to 240 s of
    full-price LLM calls. Nearly unreachable under strict mode, but
    load-bearing the moment anything runs non-strict — which change 1 makes
    routine. Native validation failures now route to
    _acreate_json_fallback, which already has the error-feedback retry
    loop.

    This is a deliberately small, reactive version of the systemic
    schema-compat design (COG-6269 follow-up): the full capability-profile
    work replaces demotion-on-400 with pre-flight mode resolution; nothing
    here needs undoing when that lands.

    Testing

    Three new tests in test_litellm_native.py (28 total, all green; ruff
    clean):

    • strict 400 → non-strict retry succeeds, and the next call skips
      the strict attempt entirely (payload asserted: json_schema, strict: false);
    • non-strict also rejected → prompted-JSON fallback answers;
    • invalid native output → exactly two calls (failed native + fallback),
      proving no blind tenacity re-send.

    Fixes COG-6271

    🤖 Generated with Claude Code


    Co-authored-by: Claude Fable 5 noreply@anthropic.com

    下载附件