fix(aux): downgrade json_schema response_format for json_object-only providers - #82372
Closed
hetong12345 wants to merge 1 commit into
Closed
hetong12345 wants to merge 1 commit into
hetong12345 wants to merge 1 commit into
Conversation
…providers
DeepSeek and Moonshot/Kimi Chat Completions endpoints reject response_format
type=json_schema with HTTP 400 ("This response_format_type is unavailable
now"); they only accept json_object. Since commit f726090, title
generation sends a strict json_schema, so every auto-title call on these
providers fails and falls back to the instant derived title.
Downgrade the wire response_format to json_object when the resolved
provider is documented json_object-only. The prompt already pins the JSON
shape and callers parse locally (_extract_title_text), so structured
output is preserved. Unknown providers fail open — the schema is kept.
Verified: new unit tests (18) + full test_auxiliary_client.py and
test_title_generator.py (213 passed); live DeepSeek title generation
returns a title with no 400.
8 of 9 tasks
3 tasks done
viz-A-viz
added a commit
to viz-A-viz/hermes-agent
that referenced
this pull request
Aug 10, 2026
Title generation hardcodes a strict json_schema response_format with no fallback. Providers without structured-output support (DeepSeek returns HTTP 400 "This response_format type is unavailable now") fail the whole call and the session keeps its truncated derived name. Walk a constraint ladder instead: json_schema -> json_object -> no response_format, pinning thinking off on retries so default-on reasoning models (DeepSeek V4) don't burn the 64-token budget on reasoning and return an empty content field. Failures unrelated to response_format (auth, quota, network) break out immediately - a different format cannot fix those. Unlike the other open PRs for this bug (NousResearch#82073, NousResearch#82372, NousResearch#82751, NousResearch#82868, NousResearch#82890), the retried calls also send thinking: {"type": "disabled"} - without it DeepSeek answers with an empty content and the title still never appears, even though the 400 is gone.
Collaborator
|
Thanks @hetong12345 for working on the json_schema rejection. This landed on main through #89589 (primary-path retry) and #113966 (5cc8177: DeepSeek profile flag + per-route memo + fallback path), which covers the same symptom on the primary and fallback auxiliary paths and omits the field up front for providers known to reject it. Closing as superseded by the landed fix — the tracking issue (#83390 cluster) is closed with the same references. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Since commit f726090 ("feat(sessions): name a session the moment it starts"), title generation sends a strict
response_format: {type: json_schema, ...}on every auto-title call. DeepSeek and Moonshot/Kimi Chat Completions endpoints rejectjson_schemawith HTTP 400:These providers only accept
response_format: {type: json_object}(DeepSeek API docs list onlyjson_object; Moonshot/Kimi the same). The failure is silent-ish: the instant derived title remains, but every session on these providers loses its LLM-refined title and the user sees the ⚠ warning on each new session.Fix
In
_call_llm_impl, after the provider is fully resolved (including auto-detection), downgrade the wireresponse_formatfromjson_schematojson_objectwhen the resolved provider is documented json_object-only (deepseek,moonshot,kimi— substring match, so labels likekimi-coding-cnare caught).Why this is safe:
Reply with JSON only: {"title": "..."}) and callers parse locally (_extract_title_texthas JSON + prose fallbacks), so structured output is preserved.json_objectmode on DeepSeek requires "json" to appear in the prompt, which the title prompt satisfies.Verification
_provider_rejects_json_schemaparam matrix + wire-level assertions thatcall_llmsendsjson_objectfor deepseek/kimi-coding-cn and keepsjson_schemafor openai/openrouter/zai, plus an extra_body non-clobber check.tests/agent/test_auxiliary_client.py+tests/agent/test_title_generator.py: 213 passed.generate_title("帮我查一下之前提的 PR 状态怎么样")returns查询 PR 状态— no 400.