unsloth/studio/backend/models
Daniel Han eb775d3207
Studio /v1/messages: accept thinking and unknown content blocks (#7017)
* Studio /v1/messages: accept thinking and unknown content blocks

The Anthropic-compatible /v1/messages endpoint modeled a message's content as
Union[str, list[{text|image|tool_use|tool_result}]], so any other block type
made Pydantic reject the whole request with
`messages.N.content.str: Input should be a valid string`. Resuming a Claude
session commonly replays assistant turns that carry `thinking` (extended
thinking) blocks, and sometimes a null content for a tool-only turn, both of
which tripped this and returned a 400.

Accept them:
- Add a permissive AnthropicUnknownBlock fallback (any block whose type is not
  one of the four known ones), so thinking/redacted_thinking/provider-specific/
  future blocks validate. A validator keeps known types on their typed models,
  so a malformed known block (e.g. a tool_use without id) still fails cleanly.
- Coerce a null message (and tool_result) content to "" so the converter's
  `for block in content` stays safe.

The converter already drops block types it does not translate, so a thinking
block is not forwarded to the model.

* Studio /v1/messages: keep user content validation strict

Make the thinking/null leniency role-aware so it never silently drops real
user input. Assistant turns (replayed history) still accept unknown/thinking
blocks and coerce a null tool-only turn to empty. User turns keep the strict
boundary: a null user content is rejected, and a content block the converter
cannot translate is rejected instead of being dropped into an empty prompt.

Also remove an empty file committed by accident.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Studio /v1/messages: coalesce resumed user turns and tighten content checks

- The /v1/messages count and generation paths now coalesce the adjacent user
  turns that dropping an empty or null assistant turn can leave behind, so a
  strict GGUF chat template no longer 400s on non-alternating roles.
- A user content block with a non-string type (list / dict) is rejected as a
  clean 400 instead of raising TypeError and escaping as a 500.
- The assistant null-to-empty coercion only applies to an explicit null; an
  assistant turn that omits content entirely still fails required-field
  validation instead of being silently coerced to an empty string.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Studio /v1/messages: tighten comments

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-09 12:20:02 +02:00
..
.gitkeep fix: restore models directory files deleted during restructure 2026-02-02 19:36:30 +00:00
__init__.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
auth.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
data_recipe.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
datasets.py Studio fix recipe dataset preview (#6031) 2026-06-09 14:02:00 +02:00
export.py Studio: multi-select export formats, portable FP8/INT8, GGUF LoRA, and source parity (#6767) 2026-07-03 08:25:10 -07:00
inference.py Studio /v1/messages: accept thinking and unknown content blocks (#7017) 2026-07-09 12:20:02 +02:00
mcp_servers.py studio: show MCP "Import config" on the add-server form (#6030) 2026-06-11 16:17:22 +01:00
models.py studio: allow updating HF models through UI (#5388) 2026-07-01 01:54:57 +03:00
providers.py Studio: Add custom provider option to Connections (#6112) 2026-06-12 13:09:35 +02:00
responses.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00
training.py (feat) Add project names to studio training runs (#6512) 2026-06-29 16:06:36 +02:00
users.py Studio: make code comments and docstrings more succinct (#6029) 2026-06-08 23:07:28 -07:00