Providers Package API¶
Package¶
doc_processing_toolkit.providers
¶
Anthropic¶
doc_processing_toolkit.providers.anthropic
¶
anthropic_refusal_billing_by_category(logger)
¶
Whether a refusal that arrives before any output is priced by its category (0.5.2).
Controlled by DPT_ANTHROPIC_REFUSAL_BILLING. Unset, empty or
category (case-insensitive) is the default: such a refusal, alone or as
an attempt of a server-side fallback, is billed only when its
stop_details.category / trigger.category is one the registry lists
under pricing.anthropic.refusal_billing. legacy restores the
previous pricing exactly: a fallback attempt that declined before any
output is never billed, and a refusal with no fallback is always billed
from its usage. Any other value is ignored with one WARNING per distinct
value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logger
|
Logger
|
Logger instance for the one-time warning. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
import os
os.environ["DPT_ANTHROPIC_REFUSAL_BILLING"] = "legacy"
anthropic_refusal_billing_by_category(logger) # False
anthropic_retain_final_turn_enabled(logger)
¶
Whether final-turn retention is switched on for this process.
Controlled by DPT_ANTHROPIC_RETAIN_FINAL_TURN. Unset, empty or on
(case-insensitive) leaves it on, which is the default; off restores the
previous behaviour exactly — the final answer is stored as plain text and
its thinking is never replayed. Any other value is ignored with one WARNING
per distinct value, so a typo never fails a process or changes storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logger
|
Logger
|
Logger instance for the one-time warning. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
Example
import os
os.environ["DPT_ANTHROPIC_RETAIN_FINAL_TURN"] = "off"
anthropic_retain_final_turn_enabled(logger) # False
anthropic_run_thinks(model_name, thinking_config, effort_config, model_info_config, tool_loop=None, *, output_schema=False, built_in_tools=False)
¶
Whether the request this thinking config produces on this model carries thinking.
The answer follows the two steps the entry points take for the request
itself — :func:_resolve_thinking_request, then
:func:_setup_extended_thinking, whose validation can still drop the
config — so a report that asks this describes the request the run sent.
In particular a missing config on a row with
adaptive_thinking_always_on is a thinking run (the provider defaults
it to adaptive), an off request the row cannot honour is one too, and a
config validation rejects (a budget_tokens that is not a positive
integer on a row without adaptive thinking — an adaptive row turns any
budget into adaptive thinking — or a row without
supports_extended_thinking) is not, because no thinking object
goes out for it.
The entry points also drop a thinking-on config at two registry gates,
modelled here as they apply them (0.5.3; no row fails either today): the
tool loop drops thinking only when a response schema forces the tool-based
structured-output path on a row without
supports_function_calling_and_structured_outputs (output_schema);
the no-tools path sends thinking only with an enabled built-in tool
(built_in_tools) or on a row whose
supports_built_in_tools_and_structured_outputs list is non-empty.
Agent uses this predicate for the single-request path only — a run
with per-request entries takes its run-level flag from them. No logging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
thinking_config
|
Any
|
The thinking configuration in the provider's shape
(what |
required |
effort_config
|
Any
|
The caller's effort value (may be |
required |
model_info_config
|
dict
|
The loaded |
required |
tool_loop
|
Optional[bool]
|
|
None
|
output_schema
|
bool
|
Whether the run has a response schema (the tool loop's
gate only applies then). Default |
False
|
built_in_tools
|
bool
|
Whether a provider built-in tool is enabled (the
no-tools path then sends thinking whatever the row's list says).
Default |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
bool
|
|
|
bool
|
a rejected config included. |
Example
anthropic_run_thinks("claude-sonnet-5-5", None, None, info) # True
anthropic_run_thinks("claude-sonnet-5", None, None, info) # False
anthropic_run_thinks("claude-sonnet-5-5", {"type": "between_tools"}, None, info) # False
anthropic_run_thinks("claude-fable-5-1", {"type": "disabled"}, None, info) # True
anthropic_run_thinks("claude-haiku-4-5", {"budget_tokens": 0}, None, info) # False
anthropic_thinking_error_message(kind, model_name, original)
¶
Build the compatibility error text for a classified thinking 400.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
str
|
A value from :func: |
required |
model_name
|
str
|
The model the request was sent to. |
required |
original
|
Any
|
The underlying exception, quoted verbatim so the API's own wording is never hidden. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A single message naming the cause, the model and the remedy. |
anthropic_thinking_resolves_off(model_name, thinking_config, effort_config, model_info_config)
¶
Whether a thinking config ends up as "no thinking" on this model.
An "off" request is not always honoured: a model that cannot turn thinking
off, or an effort above the row's thinking_off_max_effort, runs adaptive
thinking instead (:func:_resolve_thinking_request). This answers for the
request that is actually sent, without logging; :func:anthropic_run_thinks
is the form a report on a run asks, since it covers a missing config too.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
thinking_config
|
Any
|
The caller's thinking configuration (may be |
required |
effort_config
|
Any
|
The caller's effort value (may be |
required |
model_info_config
|
dict
|
The loaded |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
bool
|
the row's off value or no |
|
bool
|
thinking-on config, for |
|
bool
|
into adaptive thinking. |
Example
anthropic_thinking_resolves_off("claude-sonnet-5", {"type": "disabled"}, None, info) # True
anthropic_thinking_resolves_off("claude-opus-5", {"type": "disabled"}, "max", info) # False
anthropic_thinking_resolves_off("claude-fable-5-1", {"type": "disabled"}, None, info) # False
anthropic_tool_signature(tools_list)
¶
Order-independent digest of a derived Anthropic tools array.
Tool names are sorted before hashing, so a server that returns the same tools in a different order does not read as drift, while an added, removed or re-described tool does. The wire order itself is not sorted — that is frozen separately, because re-ordering a live session's tools array is itself a prefix change.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tools_list
|
list
|
Anthropic-formatted tool dicts. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A hex SHA-256 digest. Empty and |
Example
anthropic_tool_signature([{"name": "b"}, {"name": "a"}]) == anthropic_tool_signature(
[{"name": "a"}, {"name": "b"}]
)
# True
apply_anthropic_block_binding(thinking_params, betas, behaviour, logger)
¶
Attach block_binding to the thinking config and add the beta header.
Both are required together: the field without the header is a 400, and the
header without the field changes nothing. The pair is applied once per entry
point, so it rides on every request of the run — the tool loop, the
pause_turn continuations and the structured-output path all reuse the
same thinking_params and betas.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thinking_params
|
Optional[dict]
|
The thinking configuration, or |
required |
betas
|
list
|
The computed beta list (not mutated). |
required |
behaviour
|
Optional[str]
|
|
required |
logger
|
Logger
|
Logger instance. |
required |
Returns:
| Type | Description |
|---|---|
Optional[dict]
|
|
list
|
|
Tuple[Optional[dict], list]
|
and a beta list with :data: |
Notes
A non-empty beta list routes the request through
client.beta.messages instead of client.messages, so enabling the
binding is never a header-only change.
Example
thinking, betas = apply_anthropic_block_binding({"type": "adaptive"}, [], "drop_block", logger)
# ({"type": "adaptive", "block_binding": {"prefix_mismatch_behavior": "drop_block"}},
# ["thinking-binding-controls-2026-08-01"])
audit_request_prefix(state, api_params, logger, *, strategy=None)
¶
Compare one request's prefix with the previous request's and log the drift.
The only mechanism that catches MCP tool-list drift and instruction rebuilds at a client site, because it runs on every model — including the ones that never run the API's own prefix check — and needs no beta header.
It changes no request bytes. It reads system, tools and the
messages out of the body that is about to be sent, digests each, and
compares with the digests it stored last time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
dict
|
A mutable dict carrying the previous request's digests. Pass the same dict for every request whose prefix should be continuous (a run, or a whole session). |
required |
api_params
|
dict
|
The request body about to be sent. Read only. |
required |
logger
|
Logger
|
Logger instance. |
required |
strategy
|
Any
|
The compaction strategy in force, named in the record so a reader can tell a deliberate rewrite from an unexplained one. |
None
|
Returns:
| Type | Description |
|---|---|
list
|
The drift records emitted for this request (empty when the prefix was |
list
|
append-only). Each is a dict with |
list
|
message rewrite |
Example
state: dict = {}
audit_request_prefix(state, {"system": "s", "tools": [], "messages": []}, logger)
# []
call_anthropic_llm_function_calling(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, tool_choice='auto', max_tokens=None, temperature=_DEFAULT_TEMPERATURE, thinking_config=None, effort_config=None, built_in_tools=None, tool_files=None, mcp_remote_servers=None, skills=None, code_execution_output_dir=None, remove_citations=False, max_tool_iterations=10, max_pause_turn_iterations=10, strict_tools=False, response_schema=None, compaction_config=None, history_messages=None, stream_callback=None, hooks_runner=None, prompt_caching=None, preserve_anthropic_uploads=False, fallbacks=None, anthropic_betas=None, anthropic_block_binding=None, strict_prefix_binding=False, prefix_audit=False, prefix_strip_fallback=False, anthropic_tool_snapshot=None, on_unsupported_part='drop', dropped_parts_sink=None, defer_tools=None, request_start_emitter=None, max_tool_result_chars=None, tool_result_preview_chars=DEFAULT_TOOL_RESULT_PREVIEW_CHARS, truncation_store=None, _retry_accumulator=None, _estimated_input_tokens=0)
async
¶
Calls the Anthropic Claude API with MCP server-based function calling support.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Anthropic
|
Initialized Anthropic client.
Must be a valid |
required |
model_name
|
str
|
Claude model name.
Must match a model in |
required |
system_prompt
|
str
|
System instructions for Claude. Guides the model's behavior throughout the conversation. |
required |
user_prompt_parts
|
list
|
Initial user message content. List containing strings (text) and/or dictionaries (media). Supported formats:
|
required |
logger
|
Logger
|
Logger instance for tracking execution. Used for debug, info, warning, and error logging throughout. |
required |
mcp_servers
|
list
|
List of MCP server connection objects. Each dict must contain:
Tools are extracted via |
required |
tool_choice
|
str or dict
|
How Claude should select tools. Options:
Tool choice exit behavior
Note: Note: When using |
'auto'
|
max_tokens
|
int
|
Maximum tokens per API call.
If |
None
|
temperature
|
float
|
Sampling temperature (0.0-1.0). Default 1.0. Note: Cannot be modified when thinking is enabled (ignored). |
_DEFAULT_TEMPERATURE
|
thinking_config
|
dict
|
Extended thinking configuration. Supported formats:
Note: Legacy configs are auto-converted to adaptive on models that support it
( Interleaved thinking (legacy) enables reasoning between tool calls.
Requires Note: When using |
None
|
effort_config
|
str
|
Computational effort level.
Options:
|
None
|
built_in_tools
|
dict
|
Anthropic built-in tools to enable.
Supported tools: Value for each key should be
Example: Container reuse: Built-in tools work alongside MCP tools in the same conversation. |
None
|
tool_files
|
list
|
Files for code execution tool.
Format: |
None
|
mcp_remote_servers
|
list
|
List of MCP server configurations for remote_mcp tool. Required fields (by Anthropic API):
Optional fields:
Example (basic): Example (with configs): |
None
|
skills
|
Union[str, List, Dict, None]
|
Agent Skills configuration.
Skills require the Supported formats:
For multi-turn conversations with Skills, the |
None
|
code_execution_output_dir
|
str
|
Directory for code execution files.
Files a response cites are downloaded on every run since 0.5.3 (until then only
when this directory or |
None
|
remove_citations
|
bool
|
Whether to remove inline citations from response text.
Applies to built-in tools like |
False
|
max_tool_iterations
|
int
|
Maximum tool calling loop iterations. Must be at least 1. Each iteration counts as a full tool calling cycle. Prevents infinite loops in agentic workflows. Default: 10 |
10
|
max_pause_turn_iterations
|
int
|
Maximum |
10
|
strict_tools
|
bool
|
Enable strict schema validation for MCP tools.
Not supported on all models.
When |
False
|
response_schema
|
BaseModel
|
Pydantic model for structured output. When provided, the final response will be validated against this schema. Two modes are supported based on model capabilities:
When tool_choice override:
For Path B, If the schema has any of these fields (case insensitive), thinking content
will be appended to them: Default: |
None
|
compaction_config
|
dict
|
Compaction configuration dict or CompactionConfig instance. When provided, enables Level 2 (intra-run) compaction between tool roundtrips. Default: None (compaction disabled). Supported keys:
Examples:: |
None
|
history_messages
|
list
|
Pre-normalised provider-native messages
from previous session turns. When provided, these are prepended to the
initial messages list before the tool-calling loop, enabling multi-turn
conversation continuity within an |
None
|
stream_callback
|
callable
|
Callback invoked for each streaming
text chunk as it arrives. Signature: |
None
|
hooks_runner
|
HookRunner
|
Bridge to the caller's hooks, supplied by
the Agent layer. The loop awaits it at each hook point, honours
|
None
|
prompt_caching
|
bool | dict
|
Enable Anthropic prompt caching for this
request. |
None
|
preserve_anthropic_uploads
|
bool
|
When |
False
|
fallbacks
|
list
|
Server-side fallback models (beta — Claude Fable 5 / Claude Opus 5). When the requested model's safety classifiers decline the request, the API retries it on the listed models in order, inside the same call. Supported values:
Each billed attempt is priced at the rates of the model that ran
it; the response's top-level |
None
|
anthropic_betas
|
list
|
Extra |
None
|
anthropic_block_binding
|
str
|
|
None
|
strict_prefix_binding
|
bool
|
Sugar for
|
False
|
prefix_audit
|
bool
|
Shadow mode. Fingerprints |
False
|
prefix_strip_fallback
|
bool
|
For a client that cannot send
the binding beta header. Strips all |
False
|
anthropic_tool_snapshot
|
dict
|
A mutable cell owned by the
caller (an |
None
|
defer_tools
|
set | Callable
|
Which client tools to hide
behind Anthropic's tool-search tool (C4). A set of tool names, or a
predicate called as |
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
max_tool_result_chars
|
Optional[int]
|
Character cap on each tool result
fed back to the model. |
None
|
tool_result_preview_chars
|
int
|
How many characters of each tool
result's |
DEFAULT_TOOL_RESULT_PREVIEW_CHARS
|
truncation_store
|
Any
|
The run's |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Comprehensive result dictionary containing:
Additional fields when Skills (or Tools) are used:
Additional fields when the
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If client invalid, MCP servers invalid, model not recognized, skills used without code_execution, or more than 8 skills |
AnthropicError
|
For retryable errors after max retries exhausted |
Example:
# Example without Skills:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
# Connect to MCP servers
gmail_params = StdioServerParameters(
command="python",
args=["mcp_servers/gmail.py"]
)
async with stdio_client(gmail_params) as (read, write):
async with ClientSession(read, write) as gmail_session:
await gmail_session.initialize()
# Configure MCP servers
mcp_servers = [
{
'session': gmail_session,
'name': 'gmail',
'description': 'Gmail operations'
}
]
# Call function
result = await call_anthropic_llm_function_calling(
client=anthropic_client,
model_name="claude-sonnet-4-6",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["Check my latest emails"],
logger=logger,
mcp_servers=mcp_servers,
tool_choice="auto",
max_tokens=4096,
max_tool_iterations=5
)
print(result['data']) # Final response
print(f"Used {result['iterations']} iterations")
print(f"Tools used: {result['tools_used']}")
asyncio.run(main())
# Example with Skills:
async def main():
result = await call_anthropic_llm_function_calling(
client=anthropic_client,
model_name="claude-sonnet-4-6",
system_prompt="You are a helpful assistant that creates documents.",
user_prompt_parts=["Create an Excel budget spreadsheet with sample data"],
logger=logger,
mcp_servers=[], # No MCP tools needed
built_in_tools={
"code_execution": BuiltInToolConfig(enabled=True, config={})
},
skills=["xlsx"], # Enable Excel skill
code_execution_output_dir="./output"
)
print(result['data'])
print(f"Skills used: {result.get('skills_used', [])}")
print(f"Files created: {result.get('downloaded_files', [])}")
Notes
- Function is asynchronous due to MCP's async nature
- Use
call_anthropic_llm_function_calling_sync()for sync contexts - Tool calling loop runs autonomously until completion or
max_iterations - MCP tools executed via their servers, built-in tools executed by Anthropic
- Tokens and costs accumulate across all iterations
- Skills require
code_executiontool to be enabled - For multi-turn conversations with Skills, pass
container_idfrom previous response
This function provides an agentic tool calling interface that
- Integrates with MCP (Model Context Protocol) servers for tool definitions
- Manages multi-turn tool calling conversations automatically
- Supports Anthropic's built-in tools (web_search, code_execution, web_fetch, context_editing, remote_mcp)
- Supports Agent Skills (xlsx, pptx, docx, pdf, custom skills)
- Supports strict tool use for guaranteed schema validation
- Supports extended thinking with interleaved reasoning between tool calls
- Supports structured outputs with function calling
- Tracks token usage and costs across all tool calling iterations
The function runs an autonomous agent loop where Claude can
- Analyze the user query and available tools
- Decide which tools to use and with what arguments
- Receive tool execution results
- Reason about results and decide next actions
- Continue until the task is complete or max iterations reached
- (With structured output) Return final response in schema-validated format
call_anthropic_llm_function_calling_sync(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, **kwargs)
¶
Synchronous wrapper for call_anthropic_llm_function_calling.
This function runs the async call_anthropic_llm_function_calling in an event loop. Useful when calling from synchronous code contexts where async/await is not available.
All functionality, parameters, and return values are identical to the async version. For detailed parameter documentation, return value structure, examples, and usage notes, please refer to the docstring for call_anthropic_llm_function_calling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Anthropic
|
Initialized Anthropic client. |
required |
model_name
|
str
|
Claude model name. |
required |
system_prompt
|
str
|
System instructions for Claude. |
required |
user_prompt_parts
|
list
|
Initial user message content. |
required |
logger
|
Logger
|
Logger instance. |
required |
mcp_servers
|
list
|
List of MCP server connection objects. |
required |
**kwargs
|
Any
|
Additional keyword arguments passed to
|
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Same return structure as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If client invalid, model doesn't support function calling, or tool combination not supported. |
AnthropicError
|
For API errors after retry exhaustion. |
RuntimeError
|
If called from within an existing async event loop. |
Example:
# Synchronous usage
result = call_anthropic_llm_function_calling_sync(
client=anthropic_client,
model_name="claude-sonnet-4-6",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["Check my latest emails"],
logger=logger,
mcp_servers=mcp_servers,
max_tool_iterations=5
)
print(result['data'])
Notes
This function uses asyncio.run() which creates a new event loop.
Do not call this from within an existing async context - use the
async version directly instead.
call_anthropic_llm_structured_output_text(client, model_name, system_prompt, user_prompt_parts, logger, response_schema=None, max_tokens=None, temperature=_DEFAULT_TEMPERATURE, built_in_tools=None, tool_files=None, remove_citations=False, mcp_remote_servers=None, thinking_config=None, effort_config=None, code_execution_output_dir=None, skills=None, max_pause_turn_iterations=10, history_messages=None, stream_callback=None, preserve_anthropic_uploads=False, fallbacks=None, prompt_caching=None, anthropic_betas=None, anthropic_block_binding=None, strict_prefix_binding=False, prefix_audit=False, prefix_strip_fallback=False, on_unsupported_part='drop', dropped_parts_sink=None, request_start_emitter=None, _retry_accumulator=None, _estimated_input_tokens=0)
¶
Calls the Anthropic Claude API using the Messages API and Tool Use for structured JSON output, handles errors, uses API response for token/cost calculation. Applies retry logic. Supports optional extended thinking and extended output. Supports text, base64 images and base64 documents. Now includes built-in tools support.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Anthropic
|
Initialized Anthropic client. |
required |
model_name
|
str
|
The Claude model name.
Must match an Anthropic model in
|
required |
system_prompt
|
str
|
The system instruction/prompt. |
required |
user_prompt_parts
|
list
|
List of strings (text) and/or dicts (media). The order matches the desired input order. Supported dictionary formats:
|
required |
response_schema
|
BaseModel
|
Pydantic model defining the expected JSON output structure.
|
None
|
logger
|
Logger
|
Logger instance for logging messages. |
required |
max_tokens
|
int
|
Maximum tokens to generate in the response.
If |
None
|
temperature
|
float
|
Sampling temperature for generation. |
_DEFAULT_TEMPERATURE
|
built_in_tools
|
dict
|
Dictionary of built-in tools to enable.
Keys should be standardized tool names. Only tools validated by
|
None
|
tool_files
|
list
|
List of files for code execution tool.
Files should be in the same format as |
None
|
remove_citations
|
bool
|
Whether to remove inline citations from the response text.
Applies where present from the use of the |
False
|
mcp_remote_servers
|
list
|
List of MCP server configurations for remote_mcp tool. Required fields:
Optional fields:
Example (basic): Example (with configs): |
None
|
thinking_config
|
dict
|
Configuration for extended or adaptive thinking. Supported formats:
|
None
|
effort_config
|
str
|
Computational effort level.
Supported values:
|
None
|
code_execution_output_dir
|
str
|
Directory path to save files created by the code execution tool.
If None and code execution creates files, files are saved to a fresh folder
'anthropic_code_execution_files_ |
None
|
skills
|
Union[str, List, Dict, None]
|
Agent Skills configuration for specialized document tasks. Skills require the code_execution tool to be enabled. Maximum 8 Skills per request. Supported formats:
Built-in Skills:
Custom Skills must include a SKILL.md file with valid YAML frontmatter:
|
None
|
max_pause_turn_iterations
|
int
|
Maximum iterations for handling pause_turn stop reason. Skills may return pause_turn for long-running operations. Default is 10. |
10
|
history_messages
|
list
|
Pre-normalised provider-native messages
from previous session turns. When provided, these are prepended to the
messages list before the API call, enabling multi-turn conversation
continuity within an |
None
|
stream_callback
|
callable
|
Callback invoked for each streaming
text chunk as it arrives. Signature: |
None
|
preserve_anthropic_uploads
|
bool
|
When |
False
|
fallbacks
|
list
|
Server-side fallback models (beta — Claude Fable 5 / Claude Opus 5). When the requested model's safety classifiers decline the request, the API retries it on the listed models in order, inside the same call. Supported values:
Each billed attempt is priced at the rates of the model that ran
it; the response's top-level |
None
|
anthropic_betas
|
list
|
Extra |
None
|
prompt_caching
|
bool | dict
|
Enable Anthropic prompt caching for this
request. |
None
|
anthropic_block_binding
|
str
|
|
None
|
strict_prefix_binding
|
bool
|
Sugar for
|
False
|
prefix_audit
|
bool
|
Shadow mode. Fingerprints |
False
|
prefix_strip_fallback
|
bool
|
For a client that cannot send
the binding beta header. Strips all |
False
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Response format varies by mode:
|
Raises:
| Type | Description |
|---|---|
AnthropicError
|
For retryable errors when the maximum number of retries is exhausted. For other errors, the 'error' key in the returned dictionary will contain the error message. |
ValueError
|
If the Anthropic client is not initialized/invalid, if no content is supplied, if "response_schema" is not a valid Pydantic model, if the model_name is not recognized, if skills are used without the code_execution tool, if more than 8 skills are included in a request, or if both structured outputs and built-in tools are requested but the model doesn't support concurrent use. |
classify_anthropic_thinking_error(error)
¶
Tell the three thinking-block 400s apart.
Three different failures produce a 400 that mentions a thinking block, and only one of them may ever be recovered from:
"prefix_binding_mismatch"— the replayed block is valid but is bound to a conversation prefix the toolkit has since rewritten. Recognised by the fixed first sentence "The block is bound to a different conversation". The trailing explanation is written for people and its wording can change, so it is never matched on."latest_assistant_modified"— the always-on tool-round check: the latest assistant message differs from what the API returned whiletool_resultblocks are being sent back. Never a binding problem."invalid_signature"— a signature that does not verify at all (tampering, truncation, a block from another account). Must never trigger a silent drop or a retry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error
|
Any
|
The exception raised by the SDK, or any object whose |
required |
Returns:
| Type | Description |
|---|---|
Optional[str]
|
One of the three strings above, or |
Optional[str]
|
thinking-block failure. |
Example
classify_anthropic_thinking_error(
ValueError("messages.1.content.0: Invalid signature in thinking block. "
"The block is bound to a different conversation.")
)
# "prefix_binding_mismatch"
enforce_toolset_defer_rules(toolset_config, tool_search_enabled, logger)
¶
Apply Anthropic's two deferral rules to one mcp_toolset entry.
mcp_remote_servers entries pass default_config and configs
through opaquely, so a caller can set defer_loading on a remote toolset
directly. Two API rules make that a 400 rather than a no-op, and both are
enforced here instead of at the provider:
defer_loadingwithout a tool-search tool leaves the deferred tools permanently undiscoverable and the request is rejected. The flag is stripped and the tools load eagerly, with one warning namingtool_search.defer_loadingtogether withcache_controlon the same entry is rejected outright. The breakpoint is removed, because a breakpoint on a deferred entry caches nothing (deferred tools are excluded from the prefix).
The entry is copied before it is changed, so the caller's own
mcp_remote_servers dicts are never mutated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
toolset_config
|
Dict[str, Any]
|
The assembled |
required |
tool_search_enabled
|
bool
|
Whether a tool-search tool is in this request's
|
required |
logger
|
Logger
|
Logger for the two warnings above. |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
Dict[str, Any]: The entry to send — the same object when nothing had to |
Dict[str, Any]
|
change, otherwise a corrected copy. |
Example
entry = enforce_toolset_defer_rules(
{"type": "mcp_toolset", "mcp_server_name": "docs", "default_config": {"defer_loading": True}},
tool_search_enabled=False,
logger=logger,
)
# {'type': 'mcp_toolset', 'mcp_server_name': 'docs', 'default_config': {}}
freeze_anthropic_tool_snapshot(snapshot, tools_list, server_map, failed_servers, logger, *, strict=False)
¶
Hold a session's tools array steady across its turns.
The toolkit re-derives tools from live MCP servers on every run, and
a server whose list_tools() raises used to be logged and skipped — the
request then went out with fewer tools, which is a tools-array change
and therefore a prefix change on a model that runs the thinking prefix
check. This freezes the first array a session produced and reuses it rather
than shipping a shrunken one.
Behaviour is unchanged for a session whose tool set does not move: the
first call fills the cell, later calls whose signature matches keep the
freshly derived list, and a run with no snapshot cell (a plain
Agent.run()) is untouched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
snapshot
|
Optional[dict]
|
The session's mutable cell, or |
required |
tools_list
|
list
|
The array just derived from the live servers. |
required |
server_map
|
dict
|
The matching tool-name to session map. |
required |
failed_servers
|
list
|
Names of servers that did not answer this time. |
required |
logger
|
Logger
|
Logger instance. |
required |
strict
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
tuple
|
|
tuple
|
was detected mid-session, otherwise the derived pair unchanged. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When strict is set and the tool surface changed mid-session. |
merge_anthropic_betas(computed, caller_betas, logger)
¶
Merge caller-supplied anthropic-beta values into the computed list.
Anthropic's guidance for libraries is to forward a caller's beta values unchanged: an options schema that rejects unknown betas stops a client reaching a new API feature months before the toolkit supports it natively.
Computed values come first and the merge is an order-preserving dedupe, so the list the toolkit built for its own features is never reordered by a caller's additions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
computed
|
list
|
The betas the toolkit derived from the request configuration. |
required |
caller_betas
|
Optional[list]
|
Extra beta values from |
required |
logger
|
Logger
|
Logger instance. |
required |
Returns:
| Type | Description |
|---|---|
list
|
The merged list. The same contents as computed when the caller |
list
|
supplied nothing. |
Notes
A non-empty result routes the request through client.beta.messages
instead of client.messages, so passing anthropic_betas is not
free on a model that would otherwise send no beta header at all.
Example
merge_anthropic_betas(["skills-2025-10-02"], ["my-beta-2026-01-01"], logger)
# ["skills-2025-10-02", "my-beta-2026-01-01"]
model_enforces_thinking_prefix_check(model_name, model_info_config)
¶
Whether the API runs the thinking prefix check on this model.
The prefix check binds a thinking block to the system prompt, the
tools array and the earlier messages that preceded it. A model that runs
it rejects (or, under "drop_block", drops) a replayed block whose prefix
the toolkit has since rewritten — which client-side compaction does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
model_info_config
|
dict
|
The loaded |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
bool
|
carry it ( |
bool
|
request of a run on those rows sends |
bool
|
|
bool
|
extended-thinking row sends them only when the |
bool
|
|
Example
model_enforces_thinking_prefix_check("claude-opus-5", load_model_information())
# False
model_produces_preserved_thinking_blocks(model_name, model_info_config)
¶
Whether this model's thinking blocks are readable only by its own generation.
Recorded separately from the prefix check because the two genuinely diverge:
a model can produce prefix-bound blocks (so older models cannot read them —
the universal model check) without running the prefix check itself.
It is the storage-time gate for final-turn retention (R4,
DPT_ANTHROPIC_RETAIN_FINAL_TURN, see :func:_retained_final_turn) and is
read by diagnostics and the model-switch guidance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
model_info_config
|
dict
|
The loaded |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
model_supports_server_compaction(model_name, model_info_config)
¶
Whether the API accepts the compact_20260112 context-management edit.
context_editing covers three edits, and the model lists differ: the
clear_tool_uses / clear_thinking edits are accepted on every row that
lists context_editing, while server-side threshold compaction is
accepted only on the models Anthropic's compatibility list names.
claude-haiku-4-5 answers the compaction edit with a 400
(does not support the 'compact_20260112' context management).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
model_info_config
|
dict
|
The loaded |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
bool
|
key (a row the registry has not classified) keeps the previous |
bool
|
behaviour, which is to send the edit. |
Example
model_supports_server_compaction("claude-haiku-4-5", load_model_information())
# False
model_supports_thinking_block_binding(model_name, model_info_config)
¶
Whether the model accepts thinking.block_binding at all.
Models that do not run the prefix check still accept the object and report
only model-check drops, "so one request body works across models" — so this
defaults to True and exists to let a row opt out.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
model_info_config
|
dict
|
The loaded |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
normalize_anthropic_server_tool_name(name)
¶
Map a server_tool_use block name onto the toolkit's tool vocabulary.
Only the tool-search variants need mapping: they report
tool_search_tool_regex / tool_search_tool_bm25 on the wire but are
configured, validated and priced as the single tool tool_search. Every
other name is returned unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Any
|
The |
required |
Returns:
| Type | Description |
|---|---|
Optional[str]
|
Optional[str]: The standardized tool name, or |
Optional[str]
|
not a non-empty string. |
Example
normalize_anthropic_server_tool_name("tool_search_tool_bm25")
# 'tool_search'
prefix_audit_enabled(prefix_audit=False)
¶
Whether the shadow prefix audit is on for this request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix_audit
|
bool
|
The |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
string ( |
bool
|
default) and the falsy strings ( |
bool
|
audit off; any other value is ignored with one WARNING per distinct |
bool
|
value and the audit stays off. The parameter can only turn the audit |
bool
|
on; there is nothing to turn off, because the audit never changes a |
bool
|
request. |
report_anthropic_tool_search_errors(response, logger)
¶
Log every tool_search_tool_result_error on a response at WARNING.
A failed tool search is not a failed run: the model simply did not receive the tool references it asked for, and the remaining (non-deferred) tools are still usable. The error code is surfaced so a caller can tell a malformed pattern from a rate limit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Any
|
An Anthropic |
required |
logger
|
Logger
|
Logger to warn on. |
required |
Returns:
| Type | Description |
|---|---|
List[str]
|
List[str]: The |
Example
report_anthropic_tool_search_errors(message, logger)
# ['execution_time_exceeded']
resolve_anthropic_block_binding(model_name, model_info_config, logger, *, thinking_params=None, anthropic_block_binding=None, strict_prefix_binding=False)
¶
Decide the thinking.block_binding.prefix_mismatch_behavior for a run.
Precedence, highest first:
- A caller-supplied
thinking={"block_binding": ...}. Anthropic's guidance for libraries is to forward it unchanged, so the toolkit adds nothing and returnsNone. anthropic_block_bindingon theAgent.strict_prefix_binding=Trueon theAgent(sugar for"error").- The
DPT_ANTHROPIC_BLOCK_BINDINGenvironment variable. - The registry flag
enforces_thinking_prefix_check(⇒"drop_block").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registry model id. |
required |
model_info_config
|
dict
|
The loaded |
required |
logger
|
Logger
|
Logger instance. |
required |
thinking_params
|
Optional[dict]
|
The thinking configuration about to be sent, or
|
None
|
anthropic_block_binding
|
Optional[str]
|
|
None
|
strict_prefix_binding
|
bool
|
|
False
|
Returns:
| Type | Description |
|---|---|
Optional[str]
|
|
Optional[str]
|
With no caller or environment setting and a thinking object present, |
Optional[str]
|
|
Optional[str]
|
two that carry |
Optional[str]
|
and |
Optional[str]
|
request body on any other row moves. |
Optional[str]
|
governs prefix mismatches only — a block the serving model cannot read |
Optional[str]
|
is always dropped, and reported only when the beta was sent. |
Example
resolve_anthropic_block_binding(
"claude-sonnet-5",
load_model_information(),
logger,
thinking_params={"type": "adaptive"},
anthropic_block_binding="drop_block",
)
# "drop_block"
resolve_anthropic_tool_search_tool(validated_tools)
¶
Resolve the configured tool-search variant into its wire tool entry.
Called once per request, before the built-in tool assembly loop, so an
unknown variant fails locally with a message naming both accepted values
instead of being swallowed by that loop's per-tool except.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
validated_tools
|
Optional[dict]
|
The |
required |
Returns:
| Type | Description |
|---|---|
Optional[Dict[str, str]]
|
Optional[Dict[str, str]]: A fresh |
Optional[Dict[str, str]]
|
for the chosen variant, or |
Optional[Dict[str, str]]
|
this request. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
entry = resolve_anthropic_tool_search_tool(
{"tool_search": BuiltInToolConfig(enabled=True, config={"variant": "bm25"})}
)
# {'type': 'tool_search_tool_bm25_20251119', 'name': 'tool_search_tool_bm25'}
strip_thinking_from_history(messages, logger, reason=None, log_level=logging.WARNING)
¶
Remove every thinking block from every replayed assistant turn.
The no-beta fallback: a client that cannot send
thinking-binding-controls-2026-08-01 can instead drop the stale
reasoning itself. Anthropic allows removing thinking blocks "from the start
of the history, from the end, or all of them" — what fails is a gap — so
removing all of them is always valid.
On a thinking-on run it is only safe at a completed-turn boundary.
Within a tool round the latest assistant message must be echoed back
untouched, so prefix_strip_fallback runs this once, on the history
carried into a run, never between roundtrips.
A stored turn's blocks are dicts on every path that echoes an assistant
message through _preserve_assistant_content, but the
stop_reason == "compaction" branch appends response.content verbatim
— SDK pydantic blocks. Both shapes are recognised.
A thinking-off run on a model that checks the thinking prefix uses it at
three points (0.5.2), because its off value cannot carry
block_binding: on the history carried into the run, after in-loop
compaction has rewritten the earlier history, and to recover once from a
prefix-mismatch 400. The last two run inside a tool round, which is probed
safe under between_tools (2026-10-02: a replay with every thinking block
removed, the open round's included, returned 200).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list
|
The message list about to be sent. Not mutated. |
required |
logger
|
Logger
|
Logger instance. |
required |
reason
|
Optional[str]
|
The message to log when blocks were removed, in place of the
|
None
|
log_level
|
int
|
The level reason is logged at. |
WARNING
|
Returns:
| Type | Description |
|---|---|
list
|
A new list with thinking blocks removed. Text and |
list
|
are kept, and an assistant turn left with no blocks at all is dropped so |
list
|
the request never carries an empty |
Example
strip_thinking_from_history(
[{"role": "assistant", "content": [{"type": "thinking", "thinking": "..."}]}],
logger,
)
# []
summarize_input_transformations(entries)
¶
Count the preserved-thinking blocks the API dropped, by reason.
Both counters count dropped blocks only: an entry is counted when its
type is "thinking_dropped", under its reason. A
"thinking_mismatch_allowed" entry — the block failed the prefix check
but the API did not enforce it for this request, so the block reached the
model and was billed (older accounts, when a caller sends the
thinking-binding-controls-2026-08-01 beta through anthropic_betas
without the block_binding field) — is counted by neither, since no
reasoning was lost. It stays in input_transformations verbatim; this
function never edits the list.
The model count is only as complete as the reporting behind it: the API
lists a model-binding drop only when the request carried the
thinking-binding-controls-2026-08-01 beta (every request of a run on a
row with enforces_thinking_prefix_check — claude-fable-5-1 and
claude-opus-5-5 — or a run that opted in with
anthropic_block_binding="drop_block"). A client-side switch to an
ungated row therefore reports 0 although the API dropped the blocks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entries
|
Optional[list]
|
|
required |
Returns:
| Type | Description |
|---|---|
Dict[str, int]
|
|
Dict[str, int]
|
Entries with an unrecognised |
Dict[str, int]
|
neither — later checks add values, and "ignore what you don't |
Dict[str, int]
|
recognise" means do not act on it, not discard it. |
Example
summarize_input_transformations(
[
{"type": "thinking_dropped", "reason": "prefix_binding_mismatch"},
{"type": "thinking_mismatch_allowed", "reason": "prefix_binding_mismatch"},
]
)
# {"prefix_binding_mismatches": 1, "model_binding_mismatches": 0}
OpenAI¶
doc_processing_toolkit.providers.openai
¶
call_openai_llm_function_calling(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, tool_choice='auto', max_tokens=None, temperature=_DEFAULT_TEMPERATURE, reasoning_config=None, verbosity_config=None, built_in_tools=None, tool_files=None, mcp_remote_servers=None, parallel_tool_calls=True, remove_citations=False, code_execution_output_dir=None, max_tool_iterations=10, response_schema=None, image_detail=None, compaction_config=None, history_messages=None, stream_callback=None, service_tier=None, hooks_runner=None, on_unsupported_part='drop', dropped_parts_sink=None, defer_tools=None, request_start_emitter=None, max_tool_result_chars=None, tool_result_preview_chars=DEFAULT_TOOL_RESULT_PREVIEW_CHARS, truncation_store=None, openai_transport=None, _retry_accumulator=None, _estimated_input_tokens=0)
async
¶
OpenAI function calling with MCP server integration using Responses API.
This function provides agentic tool calling capabilities with automatic conversation management, token tracking, and cost calculation. It supports both local MCP servers (via ClientSession) and OpenAI's built-in tools (web_search, code_interpreter, remote_mcp).
The function implements a tool calling loop that continues until the model stops requesting tool calls or max_tool_iterations is reached. Reasoning items from o-series and GPT-5 models are automatically preserved across iterations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Any
|
OpenAI client instance (required). Must be an initialized
AsyncOpenAI client: the loop reads the response stream with
|
required |
model_name
|
str
|
OpenAI model name (e.g., "gpt-4.1", "gpt-5", "o4-mini"). Must match a model in model_information.json with supports_function_calling: true. |
required |
system_prompt
|
str
|
System instructions for the model. Passed as 'instructions' to the Responses API. |
required |
user_prompt_parts
|
list
|
User message content as list of parts. Supported formats:
|
required |
logger
|
Logger
|
Logger instance (required) for logging messages. |
required |
mcp_servers
|
list
|
List of local MCP server connection objects. Each dict must contain:
Tools are extracted via session.list_tools() and converted to OpenAI format. |
required |
tool_choice
|
str or dict
|
How model should select tools.
When using response_schema with a model that does NOT support native structured outputs (Path B), tool_choice is automatically overridden to "required" to ensure the model calls the submit_final_response tool. |
'auto'
|
max_tokens
|
int
|
Maximum output tokens per response.
If None, uses model's default from model_information.json.
Automatically increased by half (up to model max, at most
|
None
|
temperature
|
float
|
Sampling temperature (default: 1.0). Higher values (e.g., 0.8) make output more random, lower values (e.g., 0.2) make it more focused and deterministic. |
_DEFAULT_TEMPERATURE
|
reasoning_config
|
dict
|
Reasoning configuration for reasoning models (o-series and GPT-5 series). Validated via validate_reasoning_config_openai().
Not all models support all effort levels - see model_information.json. "mode" support and the pro-mode effort values are registry-driven ("supported_reasoning_modes" / "supported_reasoning_values_pro_mode"); pro mode requires effort of at least "medium" — an unsupported effort in pro mode is dropped so the API default applies. |
None
|
verbosity_config
|
str
|
Output verbosity level. Validated via validate_verbosity_config_openai().
Not supported on all models - check supports_verbosity_configuration. |
None
|
image_detail
|
str
|
Image detail level applied uniformly to all
images in the request (both user prompt images and tool result images).
Validated via validate_image_detail_openai() against
|
None
|
built_in_tools
|
dict
|
Dictionary of built-in tools to enable. Keys should be standardized tool names. Only tools validated by 'validate_built_in_tools' will be configured. Supported tools: "web_search", "code_execution", "remote_mcp" The value for each key should be a BuiltInToolConfig object with 'enabled' (bool) and 'config' (dict) fields.
⚠️ Note: When using built-in tools, parallel_tool_calls is auto-disabled. |
None
|
tool_files
|
list
|
Files for code execution tool.
|
None
|
mcp_remote_servers
|
list
|
Remote MCP server or OpenAI Connector configurations for the remote_mcp built-in tool.
Available connectors:
|
None
|
parallel_tool_calls
|
bool
|
Allow multiple function calls per turn. Default: True. Set to False for sequential tool use. ⚠️ Automatically disabled when built-in tools are used. |
True
|
remove_citations
|
bool
|
Remove inline citations from response (useful when web_search tool is used). Default: False. |
False
|
code_execution_output_dir
|
str
|
Directory to save files created
by the code execution tool. If None and code execution creates files,
files are saved to a fresh 'openai_code_execution_files_ |
None
|
max_tool_iterations
|
int
|
Maximum tool calling iterations (must be at least 1). Each iteration counts as a full tool calling cycle. Default: 10. The loop ends when no function calls are returned or this limit is reached. |
10
|
response_schema
|
BaseModel
|
Pydantic model for structured output. When provided, the final response will be validated against this schema. Two modes are supported based on model capabilities:
When tool_choice override: For Path B, tool_choice is overridden to "required" to ensure tool use. This override is logged as a warning. If the schema has any of these fields (case insensitive), reasoning content will be appended to them: "internal_reasoning", "thoughts", "reasoning" Default: None (no structured output, 'data' contains plain text response) |
None
|
compaction_config
|
dict
|
Compaction configuration dict or CompactionConfig instance. When provided, enables Level 2 (intra-run) compaction between tool roundtrips. Default: None (compaction disabled). Supported keys:
Examples: |
None
|
history_messages
|
list
|
Pre-normalised provider-native messages
from previous session turns. When provided, these are prepended to the
initial input list before the tool-calling loop, enabling multi-turn
conversation continuity within an |
None
|
stream_callback
|
callable
|
Callback invoked for each streaming
event as it arrives. Signature: |
None
|
service_tier
|
str
|
A tier name the model's registry row publishes under
|
None
|
hooks_runner
|
HookRunner
|
Bridge to the caller's hooks, supplied by
the Agent layer. The loop awaits it at each hook point, honours
|
None
|
defer_tools
|
set | Callable
|
Which client functions to hide
behind OpenAI's hosted tool search (C4). A set of tool names, or a
predicate called as |
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
max_tool_result_chars
|
Optional[int]
|
Character cap on each tool result
fed back to the model. |
None
|
tool_result_preview_chars
|
int
|
How many characters of each tool
result's |
DEFAULT_TOOL_RESULT_PREVIEW_CHARS
|
truncation_store
|
Any
|
The run's |
None
|
openai_transport
|
str
|
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Result containing:
|
dict
|
Additional fields when the "web_search" built-in tool is used: - distinct_url_list (list): List of distinct URLs retrieved by web_search tool |
Raises:
| Type | Description |
|---|---|
ValueError
|
If:
|
APIError
|
For API errors after retries exhausted |
Notes
Tool Choice Exit Behavior:
"auto": Normal behavior - loop until model returns final text response ormax_iterationsreached"none": No tools used (tools disabled)"required": Exit immediately after first tool call(s), since the model will never return a final text response with this setting{"type": "allowed_tools", ...}: Exit immediately after first tool call(s), since the model is forced to use one of the allowed tools on every turn{"type": "function", "name": "tool_name"}: Exit when the specified tool is called, since the model is forced to use that tool on every turn
max_iterations remains as a failsafe for all tool_choice modes.
Critical implementation details:
- Reasoning models (GPT-5, o3, o4-mini) require preserving reasoning items in responses - this is handled automatically
- Strict mode is enabled by default for all function definitions
- Built-in tools disable parallel function calling
- Token usage includes reasoning tokens for applicable models
MAX_TOKENStruncation is handled with auto-retry and limit increase
Examples:
result = await call_openai_llm_function_calling(
client=openai_client,
model_name="gpt-4.1",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["What's the weather in Tokyo?"],
logger=logger,
mcp_servers=[{"session": weather_session, "name": "weather"}],
tool_choice="auto",
max_tool_iterations=5
)
print(result['data'])
call_openai_llm_function_calling_sync(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers=None, **kwargs)
¶
Synchronous wrapper for the async call_openai_llm_function_calling function.
This function provides a synchronous interface to the async function calling implementation. It uses asyncio.run() to execute the async function in an event loop, making it suitable for use in synchronous codebases.
This is a convenience wrapper - all functionality and parameters are identical to call_openai_llm_function_calling. For the complete list of supported keyword arguments and their documentation, please refer to the async function's docstring.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Any
|
OpenAI client instance (required). Must be an initialized AsyncOpenAI client, as for the async function this wraps. |
required |
model_name
|
str
|
OpenAI model name (e.g., "gpt-4.1", "gpt-5", "o4-mini"). |
required |
system_prompt
|
str
|
System instructions for the model. |
required |
user_prompt_parts
|
list
|
User message content as list of text strings and/or media dictionaries. |
required |
logger
|
Logger
|
Logger instance (required) for logging messages. |
required |
mcp_servers
|
list
|
List of MCP server connection objects. |
None
|
**kwargs
|
Any
|
Additional keyword arguments passed to call_openai_llm_function_calling. See call_openai_llm_function_calling for the complete list of supported arguments including:
|
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Same return value as call_openai_llm_function_calling. See that function's docstring for the complete key list; the main keys are:
|
Raises:
| Type | Description |
|---|---|
APIError
|
If OpenAI returns an API-level error. |
APITimeoutError
|
If the request times out. |
Exception
|
For unexpected wrapper/runtime errors. |
Notes
This function creates a new event loop via asyncio.run(). If you're already running in an async context, use call_openai_llm_function_calling directly to avoid nested event loop issues.
Examples:
result = call_openai_llm_function_calling_sync(
client=openai_client,
model_name="gpt-4.1",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["What's 2+2?"],
logger=logger,
mcp_servers=[{"session": calc_session, "name": "calculator"}]
)
print(result['data'])
call_openai_llm_structured_output_text(client, model_name, system_prompt, user_prompt_parts, logger, response_schema=None, max_tokens=None, temperature=_DEFAULT_TEMPERATURE, reasoning_config=None, verbosity_config=None, built_in_tools=None, tool_files=None, remove_citations=False, mcp_remote_servers=None, code_execution_output_dir=None, image_detail=None, history_messages=None, stream_callback=None, service_tier=None, on_unsupported_part='drop', dropped_parts_sink=None, request_start_emitter=None, _retry_accumulator=None, _estimated_input_tokens=0)
¶
Call the OpenAI Responses API with structured JSON output.
Handles errors, performs token/cost calculation using response metadata. Supports text, base64 images, and base64 documents. Includes built-in tools support.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
OpenAI
|
Initialized OpenAI client. |
required |
model_name
|
str
|
The OpenAI model name (e.g., "gpt-4o") - Must match one of the OpenAI Models in the |
required |
system_prompt
|
str
|
The system instruction/prompt. |
required |
user_prompt_parts
|
list
|
List containing strings (for text) and/or dictionaries for media. The order of the list should match the desired input order for the model. Supported dictionary formats:
|
required |
response_schema
|
BaseModel
|
Pydantic model defining the expected JSON output structure.
|
None
|
logger
|
Logger
|
Logger instance for logging messages. |
required |
max_tokens
|
int
|
Maximum number of tokens to generate in the response. If None, uses the model's maximum output tokens from model_information.json. Defaults to None. |
None
|
temperature
|
float
|
Sampling temperature for generation. |
_DEFAULT_TEMPERATURE
|
reasoning_config
|
dict | None
|
Optional reasoning configuration for OpenAI reasoning models (o-series and gpt-5-xx series). Not supported on all models and not all supported models support all reasoning options. Defaults to None. Example: Default values: Default values for "effort" and "summary" are "medium" and "auto" respectively for all models before gpt-5.1 (if 'reasoning_config' is None).
|
None
|
verbosity_config
|
str
|
Output verbosity level - "low", "medium", or "high". Not supported on all models. Defaults to None. Controls how many output tokens are generated. Default value is "medium" for all supported models (if 'verbosity_config' is None). High verbosity: thorough explanations and extensive code; Low verbosity: concise answers.
|
None
|
image_detail
|
str
|
Image detail level applied uniformly to all images
in the request. Validated via validate_image_detail_openai() against
|
None
|
built_in_tools
|
dict
|
Dictionary of built-in tools to enable. Keys should be standardized tool names (as per the list below). Only tools that have been validated by the 'validate_built_in_tools' function will be configured. Supported tools: "web_search", "code_execution", "remote_mcp" The value for each key should be a BuiltInToolConfig object with 'enabled' (bool) and 'config' (dict) fields.
|
None
|
tool_files
|
list
|
List of files for code execution tool. Files should be in the same format as user_prompt_parts. Supported format: {'type': 'base64', 'media_type': str, 'data': str}. File type validation performed by OpenAI API. Files uploaded automatically via OpenAI Files API. |
None
|
remove_citations
|
bool
|
Whether to remove inline citations from the response text (where present from the use of the "web_search" tool). Default False. |
False
|
mcp_remote_servers
|
list
|
List of MCP server or OpenAI Connector configurations for remote_mcp tool.
Available connectors:
|
None
|
code_execution_output_dir
|
str
|
Directory path to save files created by the code execution tool.
If None and code execution creates files, files are saved to a fresh folder
'openai_code_execution_files_
|
None
|
history_messages
|
list
|
Pre-normalised provider-native messages
from previous session turns. When provided, these are prepended to the
messages list before the API call, enabling multi-turn conversation
continuity within an |
None
|
stream_callback
|
callable
|
Callback invoked during streaming with
|
None
|
on_unsupported_part
|
str
|
|
'drop'
|
dropped_parts_sink
|
list
|
Caller-supplied list extended in
place with one record per dropped part, so the drops are visible
even on an error return. Default: |
None
|
request_start_emitter
|
RequestStartEmitter
|
Opt-in
|
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
service_tier
|
str
|
A tier name the model's registry row publishes under
|
None
|
Returns:
dict: Response format varies by mode. Every mode carries the common fields
'input_tokens', 'output_tokens', 'reasoning_tokens',
'cached_input_tokens', 'cost', 'requested_tier',
'served_tier', 'tier_downgraded', 'built_in_tools_invoked',
'token_source' and 'error':
- Plain text mode (when both response_schema and built_in_tools are None):
``{'data': str | None, 'input_tokens': int, 'output_tokens': int, 'reasoning_tokens': int, 'cached_input_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'built_in_tools_invoked': list, 'token_source': str, 'error': str | None}``
- Note: 'data' contains the model's raw text response (extracted from auto-injected SimpleTextResponse schema).
- Note: Returns None for 'data' if the response is empty or malformed.
- Structured output only mode:
``{'data': dict | None, 'input_tokens': int, 'output_tokens': int, 'reasoning_tokens': int, 'cached_input_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'built_in_tools_invoked': list, 'token_source': str, 'error': str | None}``
- Note: 'data' is the plain ``dict`` parsed from the model's JSON. ``response_schema``
is used to VALIDATE that dict (``model_validate``); the validated model instance is
discarded, so a Pydantic instance is never returned.
- Note: Returns None for 'data' if the response is empty or malformed.
- Built-in tools only mode:
``{'data': str | None, 'response': response_object, 'distinct_urls': list, 'input_tokens': int, 'output_tokens': int, 'reasoning_tokens': int, 'cached_input_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'built_in_tools_invoked': list, 'token_source': str, 'error': str | None}``
- Note: 'data' contains the model's raw text response.
- Note: 'response' contains the full Open AI response object from last API call.
- Note: Returns None for 'data' if the response is empty or malformed.
- Concurrent structured output + built-in tools mode (for supported models):
``{'data': dict | None, 'response': response_object, 'distinct_urls': list, 'input_tokens': int, 'output_tokens': int, 'reasoning_tokens': int, 'cached_input_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'built_in_tools_invoked': list, 'token_source': str, 'error': str | None}``
- Note: 'data' is the plain ``dict`` parsed from the model's JSON. ``response_schema``
is used to VALIDATE that dict (``model_validate``); the validated model instance is
discarded, so a Pydantic instance is never returned.
- Note: 'response' contains the full Open AI response object from last API call.
- Note: Returns None for 'data' if the response is empty or malformed.
- Common token and tier fields (all modes):
- 'reasoning_tokens' (int): Reasoning tokens reported by the model. A
SUBSET of 'output_tokens' — reported for observability, never added
to the billed totals. ``0`` when the response carries no
``output_tokens_details``.
- 'cached_input_tokens' (int): Cached prompt tokens, a SUBSET of
'input_tokens' that ``cost`` already re-prices at the cached rate.
- 'requested_tier' (str or None): Service tier requested, after registry
validation.
- 'served_tier' (str or None): Service tier OpenAI reports it SERVED —
the tier ``cost`` is billed at.
- 'tier_downgraded' (bool): Whether the request was served at a tier
other than the one it asked for (and billed at the tier that ran).
- 'built_in_tools_invoked' (list): Deduplicated, sorted built-in tool
names with observed evidence that they actually ran (``web_search``
searches counted, ``code_interpreter`` containers or created files
observed, ``mcp_call`` output items). Empty when built-in tools were
configured but never invoked, and on the error returns. Unlike this
field, the built-in tool list handed to ``calculate_cost`` remains the
CONFIGURED echo.
- Additional fields for built-in tools and concurrent modes:
- 'cost_estimated' (bool): Whether overall cost calculation includes estimates
- 'tool_costs_estimated' (dict): Per-tool estimation flags (e.g., ``{"web_search": True, "code_execution": False}``)
- 'downloaded_files' (list, optional): List of downloaded file info dicts when code_execution tool creates files
Raises:
| Type | Description |
|---|---|
APIError
|
For retryable errors when the maximum number of retries is exhausted. For other errors, the 'error' key in the returned dictionary will contain the error message. |
ValueError
|
If the OpenAI client is not initialized or invalid, if no content is supplied, if model_name is not recognized, or if both structured outputs and built-in tools are requested but the model doesn't support concurrent use. |
Google¶
doc_processing_toolkit.providers.google
¶
StreamedResponse
¶
Wraps accumulated streaming chunks to match generate_content() response interface.
This provides the same .text, .usage_metadata, and .candidates properties as the non-streaming response, ensuring downstream code works unchanged. When accumulated_parts is provided, candidates[0].content is rebuilt with all parts from all chunks so that thought signatures and function_call parts are preserved for conversation history.
accumulated_grounding_metadata / accumulated_url_context_metadata
do the same for built-in tool evidence: the wrapper used to read both off
the final chunk alone, which silently dropped a grounded search whose
metadata arrived earlier in the stream — under-reporting
built_in_tools_invoked and under-BILLING builtin_search_count.
call_google_llm_function_calling(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, tool_choice='validated', max_tokens=None, temperature=None, thinking_budget=None, thinking_level=None, video_metadata=None, built_in_tools=None, tool_files=None, remove_citations=False, media_resolution=None, media_resolution_list=None, max_tool_iterations=10, response_schema=None, compaction_config=None, history_messages=None, stream_callback=None, code_execution_output_dir=None, service_tier=None, file_active_timeout_s=None, file_poll_interval_s=None, file_poll_backoff=None, hooks_runner=None, on_unsupported_part='drop', dropped_parts_sink=None, request_start_emitter=None, max_tool_result_chars=None, tool_result_preview_chars=DEFAULT_TOOL_RESULT_PREVIEW_CHARS, truncation_store=None, _retry_accumulator=None, _estimated_input_tokens=0, media_uploads_sink=None)
async
¶
Call Google Gemini with MCP-based function calling.
Provides an agentic tool-calling interface for Google Gemini models. Manages multi-turn function-calling conversations with proper thought signature handling for Gemini 3 models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Any
|
Google GenAI client ( |
required |
model_name
|
str
|
Gemini model name (e.g., |
required |
system_prompt
|
str
|
System instructions for the model. |
required |
user_prompt_parts
|
list
|
Strings and/or dicts for media. The order of the list matches the desired input order. Supported dictionary formats:
|
required |
logger
|
Logger
|
Logger instance for logging messages. |
required |
mcp_servers
|
list
|
List of MCP server connection objects. Each dict must contain:
Tools are extracted via |
required |
tool_choice
|
str or dict
|
How model should select tools.
Tool Choice Exit Behavior:
Note: When using |
'validated'
|
max_tokens
|
int
|
Maximum output tokens. If not provided, uses model default. |
None
|
temperature
|
float
|
Sampling temperature. NOTE: Gemini 3 recommends keeping temperature at 1.0. Lower values may cause looping or degraded performance. |
None
|
thinking_budget
|
int
|
Thinking budget for Gemini 2.5 models.
Validated via
Note: Cannot be used together with |
None
|
thinking_level
|
str
|
Thinking level for Gemini 3 models.
Validated via
Note: Cannot be used together with |
None
|
video_metadata
|
dict
|
Video preprocessing metadata. Applied to all video inputs. Supported fields:
|
None
|
built_in_tools
|
dict
|
Built-in tools to combine with the
custom MCP tools (Preview — Gemini 3 models only). Supported:
Validation: If both For built-in tools only: Use
Supported built-in tools:
Preview limitation: with server-side tool invocations
circulated, the final response currently carries no
Default: |
None
|
tool_files
|
list
|
Files uploaded via the Google Files API
for the Supported formats (when available):
Default: |
None
|
remove_citations
|
bool
|
Remove inline citations.
Default: |
False
|
media_resolution
|
str
|
Global media resolution.
Validated via
|
None
|
media_resolution_list
|
list
|
Per-part media resolution.
Validated via |
None
|
max_tool_iterations
|
int
|
Maximum tool calling iterations. Must be at least 1. Each iteration counts as a full tool calling cycle. Default: 10. |
10
|
response_schema
|
BaseModel
|
Pydantic model for structured output. When provided, the final response will be validated against this schema. Two modes are supported based on model capabilities:
When If the schema has any of these fields (case insensitive), thinking
content will be appended to them: Default: |
None
|
compaction_config
|
dict
|
Compaction configuration dict or CompactionConfig instance. When provided, enables Level 2 (intra-run) compaction between tool roundtrips. Default: None (compaction disabled). Supported keys:
Examples:: |
None
|
history_messages
|
list
|
Pre-normalised provider-native
|
None
|
stream_callback
|
callable
|
Callback invoked for each streaming
text chunk as it arrives. Signature: |
None
|
code_execution_output_dir
|
str
|
Directory path to save files created
by the code execution tool. If |
None
|
service_tier
|
str
|
A tier name the model's registry row publishes under
|
None
|
file_active_timeout_s
|
float
|
Ceiling, in seconds, on the wait for a
Files API upload to reach |
None
|
file_poll_interval_s
|
float
|
Seconds between |
None
|
file_poll_backoff
|
float
|
Multiplier applied to the poll interval
after each check, bounds |
None
|
hooks_runner
|
HookRunner
|
Bridge to the caller's hooks, supplied by
the Agent layer. The loop awaits it at each hook point, honours
|
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
max_tool_result_chars
|
Optional[int]
|
Character cap on each tool result
fed back to the model. |
None
|
tool_result_preview_chars
|
int
|
How many characters of each tool
result's |
DEFAULT_TOOL_RESULT_PREVIEW_CHARS
|
truncation_store
|
Any
|
The run's |
None
|
media_uploads_sink
|
list
|
Receives one record per Files API upload
the initial user content makes ( |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Result containing:
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If Google GenAI SDK not available, client invalid, model
doesn't support function calling, both MCP tools AND built-in tools
provided on a model whose registry row flags
|
GoogleAPIError
|
For API errors after retries. |
Notes
Key Features:
- Integrates with MCP servers for tool definitions
- Manages multi-turn tool calling conversations
- Handles thought signatures for Gemini 3 models (MANDATORY)
- Supports thinking configuration (levels for Gemini 3, budgets for 2.5)
- Supports multimodal inputs (images, video, audio, documents, YouTube)
- Tracks token usage and costs
- Dynamic
max_tokensrecovery on truncation (at mostGOOGLE_MAX_TOKENS_RECOVERY_MAX_PASSESraises)
Critical:
- Validates
supports_function_callingfrommodel_information.json - Gemini 3 models REQUIRE thought signatures for function calling
- Signatures must be preserved even with
thinking_level="minimal" - Temperature 1.0 is recommended for Gemini 3 (lower may cause issues)
- Parallel function responses must NOT be interleaved
- Built-in tools + custom functions are SUPPORTED on models whose
registry row flags
supports_concurrent_built_in_and_custom_toolstrue (every Gemini 3 text row); aValueErroris raised only when that flag is false thinking_budgetandthinking_levelare mutually exclusive
Examples:
result = await call_google_llm_function_calling(
client=genai.Client(),
model_name="gemini-3-flash-preview",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["What's the weather in London?"],
logger=logger,
mcp_servers=[{"session": mcp_session, "name": "weather"}],
tool_choice="auto",
thinking_level="high"
)
print(result['data'])
call_google_llm_function_calling_sync(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, **kwargs)
¶
Synchronous wrapper for call_google_llm_function_calling.
Runs the async call_google_llm_function_calling in an event loop
using asyncio.run(). Use this when you need to call the function
calling API from synchronous code.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Any
|
Google GenAI client ( |
required |
model_name
|
str
|
Gemini model name (e.g., |
required |
system_prompt
|
str
|
System instructions for the model. |
required |
user_prompt_parts
|
list
|
Initial user message content. |
required |
logger
|
Logger
|
Logger instance. |
required |
mcp_servers
|
list
|
List of MCP server connection objects. |
required |
**kwargs
|
Any
|
Additional keyword arguments passed to
|
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Same return structure as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If invalid configuration is provided. |
GoogleAPIError
|
For API errors after retries. |
RuntimeError
|
If called from an already-running event loop.
In that case, use |
Notes
All supported keyword arguments can be found by examining the async
call_google_llm_function_calling function, including:
tool_choice: How model should select toolsmax_tokens: Maximum output tokenstemperature: Sampling temperaturethinking_budget: Thinking budget for Gemini 2.5 modelsthinking_level: Thinking level for Gemini 3 modelsvideo_metadata: Video preprocessing metadatabuilt_in_tools: Built-in tools combined with custom MCP tools (Preview, Gemini 3)tool_files: File uploads for the code_execution built-in toolremove_citations: Remove inline citations from responsemedia_resolution: Global media resolution for all media partsmedia_resolution_list: Per-part media resolution overridemax_tool_iterations: Maximum tool calling iterationsresponse_schema: Pydantic model for structured outputfile_active_timeout_s/file_poll_interval_s/file_poll_backoff: Files API ACTIVE-wait policy for media uploads
This function creates a new event loop via asyncio.run(). If you
are already in an async context, use
call_google_llm_function_calling directly with await instead.
Examples:
result = call_google_llm_function_calling_sync(
client=genai.Client(),
model_name="gemini-3-flash-preview",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["What's the weather?"],
logger=logger,
mcp_servers=[{"session": mcp_session, "name": "weather"}],
tool_choice="auto"
)
print(result['data'])
call_google_llm_structured_output_text(client, model_name, system_prompt, user_prompt_parts, logger, response_schema=None, temperature=_DEFAULT_TEMPERATURE, max_tokens=None, thinking_budget=None, thinking_level=None, video_metadata=None, built_in_tools=None, tool_files=None, remove_citations=False, media_resolution=None, media_resolution_list=None, code_execution_output_dir=None, history_messages=None, in_session=False, stream_callback=None, service_tier=None, file_active_timeout_s=None, file_poll_interval_s=None, file_poll_backoff=None, on_unsupported_part='drop', dropped_parts_sink=None, request_start_emitter=None, _retry_accumulator=None, _estimated_input_tokens=0, _truncation_retry=False, media_uploads_sink=None)
¶
Call the Google Gemini API with structured output support.
Calls the Google Gemini API using the new client SDK, requests structured JSON output, handles errors, and performs token/cost calculation using API metadata. Supports text, PIL images, video bytes, audio bytes, document bytes (uploaded via File API), and YouTube URLs. Also supports optional extended thinking for specific models and built-in tools.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Client
|
Initialized Google GenAI client. |
required |
model_name
|
str
|
The Gemini model name (e.g., "gemini-1.5-pro-latest") - Must match one of the Google Models in the |
required |
system_prompt
|
str
|
The system instruction/prompt. |
required |
user_prompt_parts
|
list
|
List containing strings (for text) and/or dictionaries for media. The order of the list matches the desired input order. Supported dictionary formats:
|
required |
response_schema
|
BaseModel
|
Pydantic model defining the expected JSON output structure.
|
None
|
logger
|
Logger
|
Logger instance for logging messages. |
required |
temperature
|
float
|
Sampling temperature for generation. Left unset, |
_DEFAULT_TEMPERATURE
|
max_tokens
|
int
|
Maximum number of tokens to generate in the response. If None, Google will use the model's default maximum. If specified, must be an integer less than the model's maximum output tokens from |
None
|
thinking_budget
|
int
|
Optional thinking budget. Not supported for all models. Defaults to None.
|
None
|
thinking_level
|
str
|
Optional thinking level ("minimal", "low", "medium" or "high"). Not supported on all models. Defaults to None.
|
None
|
video_metadata
|
dict
|
Optional video preprocessing metadata for video inputs. Applies only to video content types. Defaults to None. Supported fields:
Example: Note: This metadata will be applied to ALL video inputs in user_prompt_parts. For different metadata per video, call the function separately. |
None
|
built_in_tools
|
dict
|
Dictionary of built-in tools to enable. Keys should be standardized tool names (as per the list below). Only tools that have been validated by the |
None
|
tool_files
|
list
|
List of files for code execution tool. Files should be in the same format as user_prompt_parts. Supported formats:
|
None
|
remove_citations
|
bool
|
Whether to remove inline citations from the response text (where present from the use of the "web_search" tool). Default False. |
False
|
media_resolution
|
str
|
Global media resolution for all media parts. Defaults to None (model default). Supported values (model-dependent):
|
None
|
media_resolution_list
|
list
|
Per-part media resolution override. Not supported on all models. Defaults to None. List of resolution strings matching user_prompt_parts order (for media parts only). Use None to use global/default media resolution. Non-media parts will be ignored and don't need an entry. Supported values (model-dependent):
|
None
|
code_execution_output_dir
|
str
|
Directory path to save files created by the code execution tool.
If None and code execution creates files, files are saved to a fresh folder
'google_code_execution_files_
|
None
|
in_session
|
bool
|
When |
False
|
history_messages
|
list
|
Pre-normalised provider-native
|
None
|
stream_callback
|
callable
|
Callback invoked during streaming with
|
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
service_tier
|
str
|
A tier name the model's registry row publishes under
|
None
|
file_active_timeout_s
|
float
|
Ceiling, in seconds, on the wait for a
Files API upload to reach |
None
|
file_poll_interval_s
|
float
|
Seconds between |
None
|
file_poll_backoff
|
float
|
Multiplier applied to the poll interval
after each check, bounds |
None
|
_truncation_retry
|
bool
|
Internal marker set when this call is the
single automatic retry of a response that hit |
False
|
media_uploads_sink
|
list
|
Receives one record per Files API upload
this call makes ( |
None
|
Returns: dict: Response format varies by mode:
- Plain text mode (when both response_schema and built_in_tools are None):
``{'data': str | None, 'input_tokens': int, 'output_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'token_source': str, 'error': str | None}``
- Note: 'data' contains the model's raw text response (extracted from auto-injected ``SimpleTextResponse`` schema).
- Note: Returns None for 'data' if the response is empty or malformed.
- Structured output only mode:
``{'data': dict | None, 'input_tokens': int, 'output_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'token_source': str, 'error': str | None}``
- Note: 'data' is the plain ``dict`` parsed from the model's JSON. ``response_schema``
is used to VALIDATE that dict (``model_validate``); the validated model instance is
discarded, so a Pydantic instance is never returned.
- Note: Returns None for 'data' if the response is empty or malformed.
- Built-in tools only mode:
``{'data': str | None, 'response': response_object, 'distinct_urls': list, 'input_tokens': int, 'output_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'token_source': str, 'error': str | None}``
- Note: 'data' contains the model's raw text response.
- Note: 'response' contains the full Google response object from last API call.
- Note: Returns None for 'data' if the response is empty or malformed.
- Concurrent structured output + built-in tools mode (for supported models):
``{'data': dict | None, 'response': response_object, 'distinct_urls': list, 'input_tokens': int, 'output_tokens': int, 'cost': float, 'requested_tier': str | None, 'served_tier': str | None, 'tier_downgraded': bool, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'token_source': str, 'error': str | None}``
- Note: 'data' is the plain ``dict`` parsed from the model's JSON. ``response_schema``
is used to VALIDATE that dict (``model_validate``); the validated model instance is
discarded, so a Pydantic instance is never returned.
- Note: 'response' contains the full Google response object from last API call.
- Note: Returns None for 'data' if the response is empty or malformed.
Every mode additionally returns:
- 'built_in_tools_invoked' (list): Deduped, sorted built-in tool names with
evidence in the RESPONSE that they actually ran — ``grounding_metadata``
(``google_search_grounding``), ``url_context_metadata``
(``google_url_context``), ``executable_code`` / ``code_execution_result``
parts or saved artifacts (``code_execution``). This is observed usage, not
configuration. ``[]`` when nothing ran.
- 'built_in_tools_used' (list): The CONFIGURED echo — the built-in tool names
that passed registry validation and were sent in the request (same field the
function-calling entry point returns). It merely repeats configuration and
is no evidence anything ran; on error returns it names the built-ins the
failed request carried. ``[]`` when none were configured.
- 'requested_tier' (str or None): Service tier requested, after registry
validation.
- 'served_tier' (str or None): Service tier Google reports it SERVED (read
from the ``x-gemini-service-tier`` response header) — the tier 'cost' is
billed at.
- 'tier_downgraded' (bool): Whether a requested priority tier was silently
served at the standard tier.
Additional fields for built-in tools and concurrent modes:
- 'cost_estimated' (bool): Whether overall cost calculation includes estimates
- 'tool_costs_estimated' (dict): Per-tool estimation flags (e.g., ``{"web_search": True, "code_execution": False}``)
- 'downloaded_files' (list, optional): List of downloaded file info dicts when the code_execution tool creates files
Raises:
| Type | Description |
|---|---|
GoogleAPIError
|
For retryable errors when the maximum number of retries is exhausted. For other errors, the 'error' key in the returned dictionary will contain the error message. |
ValueError
|
If the Google client is not available or invalid, if the input data is invalid, if the model_name is not recognized, or if both structured outputs and built-in tools are requested but the model doesn't support concurrent use. |
Fireworks¶
doc_processing_toolkit.providers.fireworks
¶
call_fireworks_llm_function_calling(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, built_in_tools=None, tool_choice='auto', max_tokens=None, temperature=0.3, reasoning_effort=None, max_tool_iterations=10, response_schema=None, compaction_config=None, history_messages=None, stream_callback=None, hooks_runner=None, on_unsupported_part='drop', dropped_parts_sink=None, request_start_emitter=None, max_tool_result_chars=None, tool_result_preview_chars=DEFAULT_TOOL_RESULT_PREVIEW_CHARS, truncation_store=None, _retry_accumulator=None, _estimated_input_tokens=0)
async
¶
Fireworks AI function calling with MCP server integration.
Uses the Chat Completions API (OpenAI-compatible) for tool calling, with client-side MCP tool execution. This function provides an agentic tool calling loop that iteratively calls tools until the model produces a final response or reaches the iteration limit.
API Choice: This implementation uses the Chat Completions API (not the Responses API) because it provides full control over tool execution via our MCP server connections. The Responses API delegates tool execution to Fireworks servers which doesn't work with local MCP servers.
Important Limitation: Fireworks does NOT support concurrent use of
built-in tools (remote_mcp via Responses API) with custom local tools
(Chat Completions API). The supports_concurrent_built_in_and_custom_tools
is set to false in model_information.json for all Fireworks models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Fireworks
|
Initialized Fireworks AI client (required). Can also be an OpenAI client configured with Fireworks base_url. |
required |
model_name
|
str
|
Fireworks model name (e.g., "accounts/fireworks/models/kimi-k2-instruct-0905").
Must match one of the Fireworks models in |
required |
system_prompt
|
str
|
System instructions for the model. |
required |
user_prompt_parts
|
list
|
List containing strings (for text) and/or dictionaries for media. The order of the list should match the desired input order for the model. Supported dictionary formats:
|
required |
logger
|
Logger
|
Logger instance for logging messages (required). |
required |
mcp_servers
|
list
|
List of MCP server connection objects. Each dict must contain:
|
required |
built_in_tools
|
dict
|
[PLACEHOLDER - NOT CURRENTLY SUPPORTED] This parameter is reserved for future functionality when Fireworks adds built-in tool support to the Chat Completions API. Current Status: Fireworks built-in tools (remote_mcp) are ONLY available via the Responses API, which does not support the function calling loop pattern used by this function. Therefore, built_in_tools cannot be used with this function at this time. Validation: If both mcp_servers AND built_in_tools are provided,
For remote MCP support: Use Default: None |
None
|
tool_choice
|
str or dict
|
How model should select tools.
Default: "auto" Tool Choice Exit Behavior:
Note: max_iterations remains as a failsafe for all tool_choice modes. When using response_schema with a model that does NOT support native structured outputs (Path B), tool_choice is automatically overridden to "required" to ensure the model calls the submit_final_response tool. |
'auto'
|
max_tokens
|
int
|
Maximum output tokens per response. If response is truncated due to max_tokens, the function will automatically increase by 50% (up to model maximum) and retry. Default: None (uses model default) |
None
|
temperature
|
float
|
Sampling temperature for generation. Default: 0.3 (low temperature recommended for tool calling to reduce hallucinated parameter values and ensure deterministic tool selection) |
0.3
|
reasoning_effort
|
str
|
Reasoning effort level for reasoning models.
Validated against
|
None
|
max_tool_iterations
|
int
|
Maximum number of tool calling iterations (must be at least 1). Each iteration counts as a full tool calling cycle. The loop will terminate after this many iterations even if the model continues requesting tool calls. Default: 10 |
10
|
response_schema
|
BaseModel
|
Pydantic model for structured output. When provided, the final response will be validated against this schema. Two modes are supported based on model capabilities:
When tool_choice override: For Path B, tool_choice is overridden to "required" to ensure tool use. This override is logged as a warning. If the schema has any of these fields (case insensitive), reasoning content will be appended to them: "internal_reasoning", "thoughts", "reasoning" Note: Fireworks does NOT support strict mode for tools. Default: None (no structured output, 'data' contains plain text response) |
None
|
compaction_config
|
dict
|
Compaction configuration dict or CompactionConfig instance. When provided, enables Level 2 (intra-run) compaction between tool roundtrips. Default: None (compaction disabled). Supported keys:
Examples: |
None
|
history_messages
|
list
|
Pre-normalised provider-native messages
from previous session turns. When provided, these are prepended to the
initial messages list before the tool-calling loop, enabling multi-turn
conversation continuity within an |
None
|
stream_callback
|
callable
|
Callback invoked for each streaming
text chunk as it arrives. Signature: |
None
|
hooks_runner
|
HookRunner
|
Bridge to the caller's hooks, supplied by
the Agent layer. The loop awaits it at each hook point, honours
|
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
max_tool_result_chars
|
Optional[int]
|
Character cap on each tool result
fed back to the model. |
None
|
tool_result_preview_chars
|
int
|
How many characters of each tool
result's |
DEFAULT_TOOL_RESULT_PREVIEW_CHARS
|
truncation_store
|
Any
|
The run's |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Result dictionary containing:
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If:
|
FireworksBaseAPIError
|
For retryable API errors when max retries exhausted. |
Notes
- Use low temperature (0.1-0.3) for tool calling (default: 0.3)
- Reasoning models require preserving
reasoning_contentacross turns reasoning_effortvalidated viavalidate_reasoning_effort_fireworks()- Reasoning content is combined from both
reasoning_contentfield AND<think></think>tags in the response - Tool results are TEXT ONLY (no multimodal support)
- Uses Chat Completions API (not Responses API)
- Built-in tools (remote_mcp) NOT supported in this implementation
- PDF/Document content NOT supported (Document Inlining deprecated)
Examples:
import asyncio
from fireworks import AsyncFireworks
client = AsyncFireworks()
result = asyncio.run(call_fireworks_llm_function_calling(
client=client,
model_name="accounts/fireworks/models/kimi-k2-instruct-0905",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["What is the weather in Tokyo?"],
logger=logger,
mcp_servers=[{"session": mcp_session, "name": "weather"}]
))
print(result['data'])
call_fireworks_llm_function_calling_sync(client, model_name, system_prompt, user_prompt_parts, logger, mcp_servers, **kwargs)
¶
Synchronous wrapper for call_fireworks_llm_function_calling.
This function provides a synchronous interface for the async
call_fireworks_llm_function_calling function by running it in an
event loop using asyncio.run().
Use this wrapper when calling from synchronous code that cannot use async/await syntax directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Fireworks
|
Initialized Fireworks AI client (required). |
required |
model_name
|
str
|
Fireworks model name (required). |
required |
system_prompt
|
str
|
System instructions for the model (required). |
required |
user_prompt_parts
|
list
|
User message content as list of parts (required). |
required |
logger
|
Logger
|
Logger instance (required). |
required |
mcp_servers
|
list
|
List of MCP server connection objects (required). |
required |
**kwargs
|
Any
|
Additional keyword arguments passed to
See |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Same return structure as |
Raises:
| Type | Description |
|---|---|
Exception
|
Same exceptions as |
Examples:
from fireworks import Fireworks
client = Fireworks()
result = call_fireworks_llm_function_calling_sync(
client=client,
model_name="accounts/fireworks/models/kimi-k2-instruct-0905",
system_prompt="You are a helpful assistant.",
user_prompt_parts=["What is the weather in Tokyo?"],
logger=logger,
mcp_servers=[{"session": mcp_session, "name": "weather"}],
temperature=0.2
)
print(result['data'])
call_fireworks_llm_structured_output_text(client, model_name, system_prompt, user_prompt_parts, logger, response_schema=None, max_tokens=None, temperature=1.0, mcp_remote_servers=None, reasoning_effort=None, history_messages=None, stream_callback=None, on_unsupported_part='drop', dropped_parts_sink=None, request_start_emitter=None, _retry_accumulator=None, _estimated_input_tokens=0)
¶
Call the Fireworks AI API with structured output or MCP support.
Handles errors and performs token/cost calculation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
Fireworks
|
Initialized Fireworks AI client. |
required |
model_name
|
str
|
The Fireworks model name (e.g., "accounts/fireworks/models/...") - Must match one of the Fireworks Models in the |
required |
system_prompt
|
str
|
The system instruction/prompt. |
required |
user_prompt_parts
|
list
|
List containing strings (for text) and/or dictionaries for media. The order of the list should match the desired input order for the model. Supported dictionary formats:
|
required |
response_schema
|
BaseModel
|
Pydantic model defining the expected JSON output structure for structured output mode. Note: When response_schema is None and mcp_servers is not provided, the function operates in "plain text mode" - it auto-injects a SimpleTextResponse schema and returns the model's raw text response in the 'data' field. If the supplied 'response_schema' has any of the following fields (case insensitive), they will be populated with the model's internal reasoning if available.
|
None
|
logger
|
Logger
|
Logger instance for logging messages. |
required |
max_tokens
|
int
|
Maximum number of tokens to generate in the response. If None, uses the model's maximum output tokens from |
None
|
temperature
|
float
|
Sampling temperature for generation. |
1.0
|
mcp_remote_servers
|
list
|
MCP server configurations for remote tool access.
If provided, function will use Response API instead of Chat Completions API.
|
None
|
reasoning_effort
|
str
|
Reasoning effort level - "low", "medium", "high", or "none". Not supported on all models. Defaults to None. Controls reasoning behavior for supported models. When enabled, the model's reasoning appears in the reasoning_content field of the response (or in Not supported on all models - validated against model's |
None
|
history_messages
|
list
|
Pre-normalised provider-native messages
from previous session turns. When provided, these are prepended to the
messages list before the API call, enabling multi-turn conversation
continuity within an |
None
|
stream_callback
|
callable
|
Callback invoked during streaming with
|
None
|
_retry_accumulator
|
RetryAccumulator
|
Internal parameter managed
by the |
None
|
_estimated_input_tokens
|
int
|
Internal parameter used by the retry
decorator to approximate costs for billable errors lacking usage data.
Default: |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Response format varies by mode:
Every mode also returns Every mode also returns |
Raises:
| Type | Description |
|---|---|
FireworksBaseAPIError
|
For retryable errors when the maximum number of retries is exhausted. For other errors, the 'error' key in the returned dictionary will contain the error message. |
ValueError
|
If the Fireworks AI client is not initialized/invalid, if
no content is supplied, if |
Notes
Two operational modes:
- Structured Output Mode: Uses Chat Completions API with JSON schema
- MCP Mode: Uses native Fireworks Response API with MCP server integration
Additional fields for MCP mode:
cost_estimated(bool): Whether overall cost calculation includes estimatestool_costs_estimated(dict): Per-tool estimation flags (e.g., {"web_search": True, "code_execution": False})