* Fix GoogleGenaiSamplingHandler thought part leaking and unhelpful errors
- Filter thought parts (part.thought=True) from response content instead
of leaking them as TextContent in _response_to_result_with_tools
- Include finish_reason in error messages when no content is found, so
safety-filtered responses (SAFETY, RECITATION, etc.) are distinguishable
- Add specific error message for thinking-only responses in
_response_to_create_message_result
Fixes#3846
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add tests for thought part filtering and error message improvements
Tests cover:
- Thought parts filtered from tool-path responses
- Thought-only responses produce descriptive errors
- Safety-filtered responses include finish_reason in error
- Normal responses (text + function calls) unaffected
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix ruff format and ty check issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix ty check errors in tests
Remove unused ty: ignore comments from lines where isinstance() narrows
the type, and add correct ty: ignore[invalid-argument-type] and
ty: ignore[not-subscriptable] comments on lines in newly added test
functions where ty cannot infer the union type is a list. Also apply
ruff format fix in test_task_return_types.py.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: use all() not any() for thinking-only detection
Addresses review feedback: any() would misclassify mixed responses
(thought + function_call) as thinking-only, hiding the real error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Raise on unhandled content types in sampling handler dispatch chains
The Anthropic and OpenAI sampling handlers have isinstance chains that
dispatch on MCP content types but silently drop unhandled variants like
EmbeddedResource and ResourceLink. This adds explicit else-raise guards
to match the Gemini handler's behavior and the single-content dispatch
paths that already raise.
Raising is the right choice over warn-and-skip: a partial conversion
produces a plausible-but-wrong LLM response (the model confidently
answers based on incomplete input), which is worse than a clear error
that tells the user exactly what isn't supported.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add tests for unsupported content type raises in sampling handlers
Tests the new ValueError raises for unsupported content types
(e.g. EmbeddedResource) in the Anthropic and OpenAI message
conversion loops. Uses model_construct to bypass Pydantic's
union validation since the raise is a defensive guard for
future SDK content types.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: strip title fields from tool schemas for Gemini compatibility
Gemini 2.5 Flash produces MALFORMED_FUNCTION_CALL when a function
declaration's parameters_json_schema contains 'title' fields (which
Pydantic adds by default). Strip them in _convert_tool_to_google_genai
before passing to the API.
Fixes#3860
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix ty errors and lowest-deps test failure
- Add assertions for non-None before subscripting FunctionDeclaration
fields (ty check)
- Test compress_schema directly instead of constructing FunctionDeclaration
which may not support parameters_json_schema in google-genai==1.18.0
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: support ImageContent and AudioContent in sampling handlers
Co-authored-by: Claude <noreply@anthropic.com>
* Validate image MIME types, fix silent drop in assistant list messages
* Reject image/audio in assistant messages with tool_calls
* Reject ImageContent in assistant messages for Anthropic
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add Google GenAI sampling handler
Co-authored-by: Bill Easton <strawgate@users.noreply.github.com>
* chore: Update SDK documentation
* Filter non-Gemini model hints in _get_model
Match the Anthropic/OpenAI handler pattern of only selecting
provider-compatible models from hints.
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Bill Easton <strawgate@users.noreply.github.com>
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
* Add AnthropicSamplingHandler
Adds a sampling handler for the Anthropic API at
fastmcp.client.sampling.handlers.anthropic, alongside the existing
OpenAI handler. Includes full support for tool calling.
Install with: pip install fastmcp[anthropic]
* Update default model
* Update sampling docs to cover both OpenAI and Anthropic handlers
* Use AsyncAnthropic, fix falsy value handling, handle tool_choice none
* Propagate isError to Anthropic, join multiple text blocks, fix docs
* Unify SamplingHandler and promote OpenAI handler
Consolidates ServerSamplingHandler and ClientSamplingHandler into a single
SamplingHandler type alias. Moves OpenAISamplingHandler from experimental
to fastmcp.client.sampling.handlers.openai as the canonical location.
Backwards compatibility maintained for imports from experimental.
* Remove unreachable code paths in OpenAI handler
* Fix docstring and use elif for mutually exclusive branches