Skip to content

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

False only when the variable is legacy.

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

False only when the variable is off.

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 thinking_config= carries; may be None).

required
effort_config Any

The caller's effort value (may be None).

required
model_info_config dict

The loaded model_information.json.

required
tool_loop Optional[bool]

True for a run with local tools (the tool loop's gate applies), False for a run without (the no-tools path's gate applies), None to require both.

None
output_schema bool

Whether the run has a response schema (the tool loop's gate only applies then). Default False.

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.

False

Returns:

Name Type Description
bool bool

True when the run sends a thinking-on configuration;

bool

False when it sends the row's off value or no thinking field,

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:classify_anthropic_thinking_error.

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 None).

required
effort_config Any

The caller's effort value (may be None).

required
model_info_config dict

The loaded model_information.json.

required

Returns:

Name Type Description
bool bool

True when the config asks for thinking off and the run sends

bool

the row's off value or no thinking field. False for a

bool

thinking-on config, for None, and for an off request the row turns

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 None both digest to the same value.

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 None.

required
betas list

The computed beta list (not mutated).

required
behaviour Optional[str]

"drop_block", "error" or None. None is a complete no-op and returns the inputs unchanged.

required
logger Logger

Logger instance.

required

Returns:

Type Description
Optional[dict]

(thinking_params, betas). Unchanged objects when behaviour is

list

None; otherwise a copied thinking config carrying block_binding

Tuple[Optional[dict], list]

and a beta list with :data:ANTHROPIC_BLOCK_BINDING_BETA appended.

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 event, field, and for a

list

message rewrite first_changed_index.

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 anthropic.Anthropic instance.

required
model_name str

Claude model name. Must match a model in model_information.json. Example: "claude-sonnet-4-6". Model must have supports_function_calling: true in the descriptions.

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:

  • Text: str
  • Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
  • Document: {'type': 'base64', 'media_type': 'application/pdf', 'data': str}
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:

  • 'session': Active MCP ClientSession
  • 'name': str (server name for identification)

Tools are extracted via session.list_tools() and converted to Anthropic format.

required
tool_choice str or dict

How Claude should select tools. Options:

  • "auto" (default): Claude decides whether to use tools
  • "any": Claude must use at least one tool
  • "none": Claude cannot use any tools
  • {"type": "tool", "name": "tool_name"}: Force specific tool

Tool choice exit behavior

  • "auto": Normal behavior - loop until model returns final text response or max_iterations reached
  • "none": No tools used (not applicable for function calling)
  • "any": Exit immediately after first tool call(s), since the model will never return a final text response with this setting
  • {"type": "tool", "name": "tool_name"}: Exit when the specified tool is called, since the model is forced to use that tool on every turn

Note: max_iterations remains as a failsafe for all tool_choice modes.

Note: "any" and specific tool not compatible with extended thinking. When thinking is enabled, incompatible choices are overridden to "auto".

When using response_schema with a model that does NOT support native structured outputs (Path B), tool_choice is automatically overridden to "any" to ensure the model calls the submit_final_response tool.

'auto'
max_tokens int

Maximum tokens per API call. If None, uses model's maximum from model_information.json. Tokens accumulate across all tool calling iterations.

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:

  • Adaptive (recommended for claude-opus-4-6): {"type": "adaptive"} Claude dynamically decides when and how much to think. No beta header required. Automatically enables interleaved thinking. Use effort_config to control thinking depth instead of budget_tokens.
  • Legacy: {"budget_tokens": 10000, "interleaved_thinking": False} Explicit budget-based thinking for older models.
  • Off: {"type": "disabled"} or {"type": "between_tools"} (the same request). What is sent depends on the model's registry row: its thinking_off_type, no thinking field on a model that thinks only when asked, or adaptive with a warning on a model that cannot turn thinking off or when the effort is above the row's thinking_off_max_effort.

Note: Legacy configs are auto-converted to adaptive on models that support it (supports_adaptive_thinking=True in model_information.json) with a deprecation warning.

Interleaved thinking (legacy) enables reasoning between tool calls. Requires interleaved-thinking-2025-05-14 beta header. Compatible with tool use. Tool choice must be "auto" only.

Note: When using response_schema with a model that does NOT support native structured outputs (Path B), thinking is automatically disabled because Path B requires tool_choice="any" which is incompatible with extended thinking.

None
effort_config str

Computational effort level. Options: "low", "medium", "high", "max" (Opus 4.6 only). Controls how much effort the model uses for text responses, tool calls, and thinking depth. Effort is generally available (no beta header required). Passed via output_config.effort. With adaptive thinking, effort is the recommended way to control thinking depth:

  • "max": Absolute maximum capability, no constraints (Opus 4.6 only)
  • "high" (default): Claude almost always thinks deeply
  • "medium": Moderate thinking, may skip for simple problems
  • "low": Minimal thinking, skips for simple tasks
None
built_in_tools dict

Anthropic built-in tools to enable. Supported tools: "web_search", "code_execution", "web_fetch", "context_editing", "remote_mcp".

Value for each key should be BuiltInToolConfig object with:

  • enabled (bool)
  • config (dict, optional)

Example: {"web_search": BuiltInToolConfig(enabled=True, config={"max_uses": 5})}

Container reuse: {"code_execution": BuiltInToolConfig(enabled=True, config={"container_id": "<prior_container_id>"})} reuses an existing Anthropic code execution container so files uploaded via tool_files in a prior run and REPL state persist (up to 30 days).

Built-in tools work alongside MCP tools in the same conversation.

None
tool_files list

Files for code execution tool. Format: [{'type': 'base64', 'media_type': str, 'data': str}]. Files uploaded via Anthropic Files API, deleted after completion.

None
mcp_remote_servers list

List of MCP server configurations for remote_mcp tool. Required fields (by Anthropic API):

  • "type" (str): Type - currently only "url" is supported
  • "url" (str): The URL of the MCP server. Must start with https://
  • "name" (str, optional): Unique identifier for this server. Default: auto-generated

Optional fields:

  • "authorization_token" (str): OAuth authorization token if required by the MCP server
  • "default_config" (dict): Default configuration for all tools from this server
    • "enabled" (bool): Whether tools are enabled by default. Default: True
    • "defer_loading" (bool): If True, tool descriptions not sent initially. Default: False
  • "configs" (dict): Per-tool configuration overrides. Keys are tool names. Example: {"specific_tool": {"enabled": True, "defer_loading": False}}
  • "cache_control" (dict): Cache breakpoint configuration for this toolset
  • "allowed_tools" (list): The tool names to expose (a tuple or set works too), translated into default_config / configs (0.5.1); anything but a list of names is reported as the run's error

Example (basic):

[{"type": "url", "url": "https://example.com/mcp", "name": "example", "authorization_token": "token"}]

Example (with configs):

[{"type": "url", "url": "https://mcp.example.com/sse", "name": "my-mcp",
    "default_config": {"enabled": False},
    "configs": {"tool1": {"enabled": True}, "tool2": {"enabled": True}}}]
None
skills Union[str, List, Dict, None]

Agent Skills configuration. Skills require the code_execution tool to be enabled. Max 8 skills per request.

Supported formats:

  • Built-in skill name (str): "xlsx", "pptx", "docx", "pdf"
  • Multiple built-in skills (List[str]): ["xlsx", "pptx"]
  • Custom skill directory path (str): "/path/to/custom_skill/"
  • Mixed skills (List): ["/path/to/skill/", "xlsx"]
  • Advanced dict format: {"type": "anthropic", "skill_id": "xlsx", "version": "latest"}

For multi-turn conversations with Skills, the container_id from the response should be passed to continue using the same container.

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 skills was set). A name this run already wrote is written as 'name (2).ext', and with no directory they go to a fresh 'anthropic_code_execution_files_<timestamp>_<random>' folder in the current directory, one per run.

None
remove_citations bool

Whether to remove inline citations from response text. Applies to built-in tools like web_search and web_fetch. Default: False

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 pause_turn iterations. Both Skills and server tools (web_search, code_execution) may return pause_turn for long-running operations. This limit applies per-iteration within the main tool calling loop, not globally. Default: 10

10
strict_tools bool

Enable strict schema validation for MCP tools. Not supported on all models. When True, adds strict: true to tool definitions and ensures Claude's tool calls always match schemas exactly. Strict tool use is generally available (no beta header required). Default: False

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:

  • Path A (native): For models with supports_function_calling_and_structured_outputs: true (model_information.json), uses output_config.format parameter for native structured outputs (GA, no beta header).
  • Path B (tool-based): For other models, creates a submit_final_response tool. The model calls this tool when ready to provide the final structured response. NOTE: Path B is incompatible with extended thinking - if both are specified, thinking_config will be automatically disabled with a warning.

When tool_choice override: For Path B, tool_choice is overridden to {"type": "any"} to ensure tool use. This override is logged as a warning.

If the schema has any of these fields (case insensitive), thinking 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:

  • strategy (str): "summarize" | "sliding_window" | "tool_result_clearing" | "combined". Default: "summarize".
  • trigger_threshold (float|int): Float 0.0–1.0 as percentage of context window, or int for absolute token count. Default: 0.8 (80%).
  • summary_model (str|None): Model for summarization calls. Default: None (uses agent model).
  • summary_prompt (str|None): Inline custom summarization prompt. Use {conversation} placeholder. Takes precedence over summary_prompt_file.
  • summary_prompt_file (str|None): File path to custom summarization prompt. Default: None.
  • keep_recent_messages (int): Messages to preserve in sliding_window / combined. Default: 5.
  • keep_recent_tool_results (int): Tool results to preserve in tool_result_clearing. Default: 3.
  • clear_tool_inputs (bool): Also clear tool call parameters. Default: False.
  • archive_history (bool): Save original conversation to JSON before compacting. Default: True.
  • archive_dir (str): Directory for archive files. Default: "./compaction_archives".
  • include_archive_path_in_summary (bool): Include archive file path in summary output. Default: True.
  • min_messages_before_compaction (int): Minimum messages before triggering. Default: 4.
  • max_compactions_per_session (int|None): Limit compaction count. Default: None.
  • combined_order (list): Strategy order for combined. Default: ["tool_result_clearing", "sliding_window", "summarize"].

Examples::

# Summarize at 60% context usage
{"strategy": "summarize", "trigger_threshold": 0.6}

# Sliding window keeping last 6 messages
{"strategy": "sliding_window", "trigger_threshold": 0.8, "keep_recent_messages": 6}

# Combined strategy with archiving
{"strategy": "combined", "trigger_threshold": 5000, "archive_history": True}
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 AgentSession. Default: None.

None
stream_callback callable

Callback invoked for each streaming text chunk as it arrives. Signature: stream_callback(event_type, data) where event_type is "text_delta" and data is the text fragment. Used by Agent.stream() to emit real-time events. Default: None.

None
hooks_runner HookRunner

Bridge to the caller's hooks, supplied by the Agent layer. The loop awaits it at each hook point, honours pause/abort/skip_tool directives, drains queued inject_message directives, and reports per-request usage to it. Default: None (no hooks).

None
prompt_caching bool | dict

Enable Anthropic prompt caching for this request. True places cache_control breakpoints with the 5-minute TTL; {"ttl": "1h"} selects the 1-hour TTL (billed at the 1h write rate). Cache reads/writes are reported in cached_input_tokens / cache_write_tokens. Default: None (no caching breakpoints).

None
preserve_anthropic_uploads bool

When True, skip cleanup of uploaded tool-file ids (Files API) and uploaded custom-skill ids at the end of this call so they remain attached to the Anthropic code execution container for subsequent runs that reuse the same container id. Set by the Agent layer when any container-reuse signal is present (a runtime anthropic_container_id, a BuiltInToolConfig.config["container_id"], or AgentSession(reuse_anthropic_container=True)). Default: False.

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:

  • None (default): fallback is enabled automatically for models that publish permitted fallback targets in model_information.json (allowed_fallback_models — e.g. claude-fable-5 and claude-opus-5 fall back to claude-opus-4-8). Disabled for all other models.
  • []: explicitly disable fallback.
  • List of model name strings or {"model": str} dicts: custom fallback chain (max 3, validated against the model's permitted targets).
  • Any other value (e.g. the API's newer scalar "default" mode) is not supported by this toolkit: a warning is logged and fallback is disabled for the request.

Each billed attempt is priced at the rates of the model that ran it; the response's top-level model field reports the model that produced the returned message.

None
anthropic_betas list

Extra anthropic-beta header values to send. Merged with the list the toolkit computed for this request — computed values first, order-preserving dedupe — so a caller can reach a new API feature before the toolkit supports it natively. None and [] both mean "no change". Side effect: a non-empty merged list routes the request through the beta endpoint (client.beta.messages), which is not free on a model that would otherwise send no beta header. Default: None.

None
anthropic_block_binding str

"drop_block", "error", "off" or None. Sets thinking.block_binding.prefix_mismatch_behavior and adds the thinking-binding-controls-2026-08-01 beta on every request of the run. None (the default) defers to DPT_ANTHROPIC_BLOCK_BINDING and then to the registry flag enforces_thinking_prefix_check, which four rows carry (claude-fable-5-1, claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5): on those the default sends "drop_block" plus the beta on every thinking request, on every other row it sends nothing unless set here ("drop_block" turns it on for any extended-thinking row, which is what makes a model-binding drop visible in input_transformations). prefix_mismatch_behavior has no effect on a model-binding drop: a block the serving model cannot read is always dropped, and reported only when the beta was sent. A caller-supplied thinking={"block_binding": ...} always wins.

None
strict_prefix_binding bool

Sugar for anthropic_block_binding="error" — a prefix mismatch fails the request instead of dropping the stale blocks. Intended for CI. Default: False.

False
prefix_audit bool

Shadow mode. Fingerprints system, tools and each message before every request and logs what changed against the previous request, without altering a single request byte. Also enabled process-wide by DPT_PREFIX_AUDIT. Default: False.

False
prefix_strip_fallback bool

For a client that cannot send the binding beta header. Strips all thinking and redacted_thinking blocks from all replayed assistant turns, once, at the completed-turn boundary before the first request — never mid-tool-round, where Anthropic rejects any change to the latest assistant message. Default: False.

False
anthropic_tool_snapshot dict

A mutable cell owned by the caller (an AgentSession) that freezes the derived tools array for the life of the session. On the first run it is filled; on later runs a shrunken or drifted tool list is replaced by the frozen one instead of silently continuing with fewer tools. Also carries the shadow-audit state across turns. Default: None (no freezing — a one-off run derives its tools as before).

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 predicate(tool_name, server_name) — the second argument is the MCP server the tool came from, or None. Matching entries are stamped defer_loading: true, so their schemas stay out of the cached system+tools prefix until the model searches for them. Requires built_in_tools={"tool_search": ...}; without it every tool loads eagerly and one warning is logged. Server tools — including the tool-search tool itself — are never deferred, and a deferred entry never keeps a cache_control breakpoint. Default: None.

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0
max_tool_result_chars Optional[int]

Character cap on each tool result fed back to the model. None derives it from the registry (utils.resolve_max_tool_result_chars: one character per token of context window); 0 turns it off. A longer result is cut with a visible … [truncated: N of M characters shown; ...] marker and one WARNING (utils.cap_tool_result).

None
tool_result_preview_chars int

How many characters of each tool result's str() the tool_call_result stream and hook events carry. 500 (the default) is the preview they always carried; 0 carries the whole result plus result_data, the result as JSON data (utils.tool_result_event_fields). Every event also says result_truncated. What the model is sent is unaffected: that copy is max_tool_result_chars's.

DEFAULT_TOOL_RESULT_PREVIEW_CHARS
truncation_store Any

The run's utils.TruncatedResultStore when Agent(truncated_result_read_chars=) is set: a result the size cap cuts is kept there in full, its marker names read_truncated_result, and that tool's own slices are not cut again. None (the default) keeps the original marker.

None

Returns:

Name Type Description
dict dict

Comprehensive result dictionary containing:

  • data: Final response - parsed JSON dict (if response_schema) or text str (if no schema)
  • response (object): Final Anthropic API response object
  • messages (list): Complete conversation history (all turns)
  • completed_iterations (int): Number of completed loop iterations
  • custom_tools (list): All custom MCP tool names used
  • built_in_tools (list): Built-in tool names CONFIGURED for the run (the echo of what was enabled, not evidence that any of them ran)
  • built_in_tools_invoked (list): Built-in tool names with evidence they actually ran — the server_tool_use / mcp_tool_use blocks the loop observed, unioned with the tools the final response and the observed request counters show (a code-execution container that ran, non-zero search / fetch counts). Sorted and deduplicated; empty on the error path and whenever the model declined to use a configured tool.
  • input_tokens (int): Total input tokens across all iterations
  • output_tokens (int): Total output tokens across all iterations
  • cached_input_tokens (int): Cache-read tokens summed across iterations, a SUBSET of input_tokens already re-priced at the cache-read rate.
  • cache_write_tokens (int): Tokens written to the prompt cache across iterations, billed at the cache-write rate.
  • request_cost_records (list): One record per billed API request, each with input_tokens, output_tokens, reasoning_tokens, cached_input_tokens, cache_write_tokens, served_model, requested_tier, served_tier and cost. cost below is the sum of these token costs plus the per-run tool costs.
  • cost (float): Estimated total cost in USD
  • cost_estimated (bool): Whether cost includes estimates
  • tool_costs_estimated (dict): Per-tool estimation flags
  • token_source (str): Token counting source ("api_response", "fallback")
  • token_totals_by_model (dict): Billed tokens attributed to the model that served them, e.g. {"claude-opus-4-8": {"input_tokens": 412, "output_tokens": 264}}. Contains only the requested model unless server-side fallback ran (Claude Fable 5). Empty on the error path.
  • iteration_metrics (list): Metrics for each tool calling iteration.

    Each entry contains:

    • iteration_number (int): The iteration number
    • model (str): The model that served this iteration's final call (differs from the requested model only after a server-side fallback)
    • input_tokens (int): Input tokens for this iteration
    • output_tokens (int): Output tokens for this iteration
    • reasoning_tokens (int): Thinking tokens for this iteration
    • cached_input_tokens (int): Cache-read tokens for this iteration
    • cache_write_tokens (int): Cache-write tokens for this iteration
    • cost (float): Estimated cost for this iteration
    • duration_ms (int): Duration of this iteration in milliseconds
    • tool_calls (list): List of tool calls made in this iteration
    • stop_reason (str): Finish reason for this iteration
    • compaction_triggered (bool), compaction_strategy (str or None), compaction_tokens_cleared (int): Compaction bookkeeping for this iteration (omitted on the record emitted for an early exit)
    • retry_count (int), retry_cost (float), retry_input_tokens (int), retry_output_tokens (int), retry_details (list): Retry bookkeeping for this iteration
  • compaction_count (int): Number of compaction events during the run.

  • compaction_archives (list): File paths to archived conversations.
  • compaction_input_tokens (int): Input tokens consumed by summarization.
  • compaction_output_tokens (int): Output tokens from summarization.
  • compaction_cost (float): Cost of summarization calls.
  • error (str or None): Error message if execution failed

  • Note: The error return (built when an unexpected exception ends the run) omits cached_input_tokens, cache_write_tokens, request_cost_records and container_id; every other key above is present.

Additional fields when Skills (or Tools) are used:

  • skills_used (list): List of skill IDs that were used
  • pause_turn_iterations (int): Number of pause_turn iterations if any
  • downloaded_files (list): List of file info dicts for files downloaded from the code execution tool
  • container_id (str): Container ID for multi-turn continuation

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 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_execution tool to be enabled
  • For multi-turn conversations with Skills, pass container_id from 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

  1. Analyze the user query and available tools
  2. Decide which tools to use and with what arguments
  3. Receive tool execution results
  4. Reason about results and decide next actions
  5. Continue until the task is complete or max iterations reached
  6. (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 call_anthropic_llm_function_calling. Supported kwargs include:

  • tool_choice (str or dict): Tool selection mode
  • max_tokens (int): Maximum tokens per API call
  • temperature (float): Sampling temperature
  • thinking_config (dict): Extended thinking configuration
  • effort_config (str): Computational effort level
  • built_in_tools (dict): Built-in tools configuration
  • tool_files (list): Files for code execution
  • skills (list): Agent Skills configuration
  • code_execution_output_dir (str): Output directory for files
  • remove_citations (bool): Remove inline citations
  • max_tool_iterations (int): Maximum loop iterations
  • max_pause_turn_iterations (int): Maximum pause_turn iterations
  • strict_tools (bool): Enable strict schema validation
  • response_schema (BaseModel): Pydantic model for structured output
  • fallbacks (list): Server-side fallback models (beta — Claude Fable 5 / Claude Opus 5)
{}

Returns:

Name Type Description
dict dict

Same return structure as call_anthropic_llm_function_calling. See async function docstring for complete details.

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 model_information.json.

  • Example: "claude-sonnet-4-6".
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:

  • base64 Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
  • Document: {'type': 'base64', 'media_type': 'application/pdf', 'data': str}
required
response_schema BaseModel

Pydantic model defining the expected JSON output structure.

  • Note: Concurrent use with built_in_tools is gated per model on descriptions.<model>.supports_built_in_tools_and_structured_outputs in model_information.json; a model whose row does not list the requested built-in raises ValueError before any request is sent.
  • Note: When both response_schema and built_in_tools are None, 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/thinking if available (requires thinking_config to be set and model must support new structured outputs with extended thinking).

    • "internal_reasoning"
    • "thoughts"
    • "reasoning"
None
logger Logger

Logger instance for logging messages.

required
max_tokens int

Maximum tokens to generate in the response. If None, uses the model's maximum from model_information.json.

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 validate_built_in_tools will be configured. Supported tools: "web_search", "code_execution", "remote_mcp", "web_fetch", "context_editing" The value for each key should be a BuiltInToolConfig object with enabled (bool) and config (dict) fields.

  • Example: {"web_search": BuiltInToolConfig(enabled=True, config={"max_uses": 5})}
  • Container reuse: {"code_execution": BuiltInToolConfig(enabled=True, config={"container_id": "<prior_container_id>"})} reuses an existing Anthropic code execution container so files uploaded via tool_files in a prior run and REPL state persist (up to 30 days).
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 Anthropic API. Files uploaded automatically via Anthropic Files API.

None
remove_citations bool

Whether to remove inline citations from the response text. Applies where present from the use of the "web_search" tool.

False
mcp_remote_servers list

List of MCP server configurations for remote_mcp tool. Required fields:

  • "type" (str): Type - currently only "url" is supported
  • "url" (str): The URL of the MCP server. Must start with https://
  • "name" (str, optional): Unique identifier for this server. Default: auto-generated

Optional fields:

  • "authorization_token" (str): OAuth authorization token if required by the MCP server
  • "default_config" (dict): Default configuration for all tools from this server
    • "enabled" (bool): Whether tools are enabled by default. Default: True
    • "defer_loading" (bool): If True, tool descriptions not sent initially. Default: False
  • "configs" (dict): Per-tool configuration overrides. Keys are tool names. Example: {"specific_tool": {"enabled": True, "defer_loading": False}}
  • "cache_control" (dict): Cache breakpoint configuration for this toolset
  • "allowed_tools" (list): The tool names to expose (a tuple or set works too), translated into default_config / configs (0.5.1); anything but a list of names raises TypeError

Example (basic):

[{"type": "url", "url": "https://example.com/mcp", "name": "example", "authorization_token": "token"}]

Example (with configs):

[{"type": "url", "url": "https://mcp.example.com/sse", "name": "my-mcp",
"default_config": {"enabled": False},
"configs": {"tool1": {"enabled": True}, "tool2": {"enabled": True}}}]
None
thinking_config dict

Configuration for extended or adaptive thinking. Supported formats:

  • Adaptive (recommended for claude-opus-4-6): {"type": "adaptive"} Claude dynamically decides when and how much to think. No beta header required. Automatically enables interleaved thinking. Use effort_config to control thinking depth instead of budget_tokens.
  • Legacy: {"budget_tokens": 10000, "interleaved_thinking": True} Explicit budget-based thinking for older models.
  • Off: {"type": "disabled"} or {"type": "between_tools"} (the same request). What is sent depends on the model's registry row: its thinking_off_type, no thinking field on a model that thinks only when asked, or adaptive with a warning on a model that cannot turn thinking off or when the effort is above the row's thinking_off_max_effort.

  • Note: Legacy configs are auto-converted to adaptive on models that support it (supports_adaptive_thinking=True in model_information.json) with a deprecation warning. budget_tokens is deprecated on adaptive-capable models and will be removed.

None
effort_config str

Computational effort level. Supported values: "low", "medium", "high", or "max" (Opus 4.6 only). Controls how much effort the model uses for text responses, tool calls, and thinking depth. Effort is generally available (no beta header required). Passed via output_config.effort. With adaptive thinking, effort is the recommended way to control thinking depth:

  • "max": Absolute maximum capability, no constraints (Opus 4.6 only)
  • "high" (default): Claude almost always thinks deeply
  • "medium": Moderate thinking, may skip for simple problems
  • "low": Minimal thinking, skips for simple tasks
  • Example: "high"
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__' in the current working directory, one per run (0.5.3); a name this run already wrote is written as 'name (2).ext'. Files are downloaded on every run since 0.5.3; until then the tool-calling path (local tools present) downloaded only when this directory or skills was set. - Example: "/path/to/output/dir"

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 skill name (str): "xlsx", "pptx", "docx", or "pdf"
  • Multiple built-in skills (List[str]): ["xlsx", "pptx"]
  • Custom skill directory path (str): "/path/to/custom_skill/" (must contain SKILL.md)
  • Mixed skills (List): ["/path/to/skill/", "xlsx", "/path/to/skill2/"]
  • Advanced dict format: {"type": "anthropic", "skill_id": "xlsx", "version": "20251013"}

Built-in Skills:

  • "xlsx": Create and analyze Excel spreadsheets
  • "pptx": Create and edit PowerPoint presentations
  • "docx": Create and edit Word documents
  • "pdf": Generate PDF documents

Custom Skills must include a SKILL.md file with valid YAML frontmatter:

  • name: Max 64 chars, lowercase letters/numbers/hyphens, no "anthropic"/"claude"
  • description: Max 1024 chars, non-empty

  • Example: skills=["xlsx", "/path/to/my_custom_skill/"]

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 AgentSession. Default: None.

None
stream_callback callable

Callback invoked for each streaming text chunk as it arrives. Signature: stream_callback(event_type, data) where event_type is "text_delta" and data is the text fragment. Used by Agent.stream() to emit real-time events. Default: None.

None
preserve_anthropic_uploads bool

When True, skip cleanup of uploaded tool-file ids (Files API) and uploaded custom-skill ids at the end of this call so they remain attached to the Anthropic code execution container for subsequent runs that reuse the same container id. Set by the Agent layer when any container-reuse signal is present (a runtime anthropic_container_id, a BuiltInToolConfig.config["container_id"], or AgentSession(reuse_anthropic_container=True)). Default: False.

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:

  • None (default): fallback is enabled automatically for models that publish permitted fallback targets in model_information.json (allowed_fallback_models — e.g. claude-fable-5 and claude-opus-5 fall back to claude-opus-4-8). Disabled for all other models.
  • []: explicitly disable fallback.
  • List of model name strings or {"model": str} dicts: custom fallback chain (max 3, validated against the model's permitted targets).
  • Any other value (e.g. the API's newer scalar "default" mode) is not supported by this toolkit: a warning is logged and fallback is disabled for the request.

Each billed attempt is priced at the rates of the model that ran it; the response's top-level model field reports the model that produced the returned message.

None
anthropic_betas list

Extra anthropic-beta header values to send. Merged with the list the toolkit computed for this request — computed values first, order-preserving dedupe — so a caller can reach a new API feature before the toolkit supports it natively. None and [] both mean "no change". Side effect: a non-empty merged list routes the request through the beta endpoint (client.beta.messages), which is not free on a model that would otherwise send no beta header. Default: None.

None
prompt_caching bool | dict

Enable Anthropic prompt caching for this request. True places cache_control breakpoints with the 5-minute TTL; {"ttl": "1h"} selects the 1-hour TTL (billed at the 1h write rate). Cache reads/writes are reported in cached_input_tokens / cache_write_tokens. Default: None (no caching breakpoints).

None
anthropic_block_binding str

"drop_block", "error", "off" or None. Sets thinking.block_binding.prefix_mismatch_behavior and adds the thinking-binding-controls-2026-08-01 beta on every request of the run. None (the default) defers to DPT_ANTHROPIC_BLOCK_BINDING and then to the registry flag enforces_thinking_prefix_check, which four rows carry (claude-fable-5-1, claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5): on those the default sends "drop_block" plus the beta on every thinking request, on every other row it sends nothing unless set here ("drop_block" turns it on for any extended-thinking row, which is what makes a model-binding drop visible in input_transformations). prefix_mismatch_behavior has no effect on a model-binding drop: a block the serving model cannot read is always dropped, and reported only when the beta was sent. A caller-supplied thinking={"block_binding": ...} always wins.

None
strict_prefix_binding bool

Sugar for anthropic_block_binding="error" — a prefix mismatch fails the request instead of dropping the stale blocks. Intended for CI. Default: False.

False
prefix_audit bool

Shadow mode. Fingerprints system, tools and each message before every request and logs what changed against the previous request, without altering a single request byte. Also enabled process-wide by DPT_PREFIX_AUDIT. Default: False.

False
prefix_strip_fallback bool

For a client that cannot send the binding beta header. Strips all thinking and redacted_thinking blocks from all replayed assistant turns, once, at the completed-turn boundary before the first request — never mid-tool-round, where Anthropic rejects any change to the latest assistant message. Default: False.

False
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0

Returns:

Name Type Description
dict 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, 'cached_input_tokens': int, 'cache_write_tokens': int, 'cost': float, 'token_source': str, 'container_id': str | None, 'built_in_tools_invoked': list, '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, 'cached_input_tokens': int, 'cache_write_tokens': int, 'cost': float, 'token_source': str, 'container_id': str | None, 'built_in_tools_invoked': list, '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, 'cached_input_tokens': int, 'cache_write_tokens': int, 'cost': float, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'token_source': str, 'container_id': str | None, 'built_in_tools_invoked': list, 'error': str | None}

    • Note: 'data' contains the model's raw text response.
    • Note: 'response' contains the full Anthropic 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, 'cached_input_tokens': int, 'cache_write_tokens': int, 'cost': float, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'token_source': str, 'container_id': str | None, 'built_in_tools_invoked': list, '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 Anthropic response object from last API call.
    • Note: Returns None for 'data' if the response is empty or malformed.
  • Present in every mode:

  • 'built_in_tools_invoked' (list): Built-in tool names with evidence they actually ran — server_tool_use / mcp_tool_use blocks in the response, a code-execution container that demonstrably ran, and non-zero search / fetch request counters; an mcp_tool_use block also adds the neutral "remote_mcp". Sorted, deduplicated, and empty whenever the model declined to use a configured tool or the call errored. The built_in_tools argument (and the built_in_tools_used field other paths return) remains the CONFIGURED echo: it says what was enabled, never what ran.

  • Present on every successful return:

  • 'cached_input_tokens' (int): Cache-read tokens, a SUBSET of 'input_tokens' that 'cost' already re-prices at the cache-read rate.

  • 'cache_write_tokens' (int): Tokens written to the prompt cache, billed at the cache-write rate for the configured TTL.
  • 'container_id' (str or None): Anthropic code execution container id for this run, usable for container reuse on a later call. None when no container was created.

  • Note: The error returns are narrower than the listings above - they carry only 'data', 'input_tokens', 'output_tokens', 'cost', 'token_source', 'built_in_tools_invoked' and 'error'.

  • 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": False, "code_execution": True})
  • 'downloaded_files' (list, optional): List of downloaded file info dicts when the "code_execution" tool is used and files are created
  • 'distinct_urls' (list, optional): List of distinct URLs when the "web_search" tool is used

  • Additional fields when skills are used:

  • 'skills_used' (list): List of skill IDs that were used in the request

  • 'pause_turn_iterations' (int, optional): Number of pause_turn iterations if any occurred

  • Conditional fields:

  • 'request_cost_records' (list, optional): Present only when the run paused (pause_turn); one priced record per continuation plus the final request.

  • 'messages' (list, optional): Present only when the final turn is retained natively (a row with produces_preserved_thinking_blocks and DPT_ANTHROPIC_RETAIN_FINAL_TURN not off): the request messages plus the signed final assistant turn, for session storage.

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 while tool_result blocks 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 str() carries the API message.

required

Returns:

Type Description
Optional[str]

One of the three strings above, or None when the error is not a

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_loading without 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 naming tool_search.
  • defer_loading together with cache_control on 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 {"type": "mcp_toolset", ...} entry.

required
tool_search_enabled bool

Whether a tool-search tool is in this request's tools array.

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 None to disable freezing.

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 True (strict prefix binding), drift raises instead of being frozen over.

False

Returns:

Type Description
tuple

(tools_list, server_map) — the frozen pair when drift or a failure

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 anthropic_betas. None and [] both mean "no change".

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 model_information.json.

required

Returns:

Type Description
bool

True only when the row carries

bool

descriptions.<model>.enforces_thinking_prefix_check: true. Two rows

bool

carry it (claude-fable-5-1 and claude-opus-5-5), so every

bool

request of a run on those rows sends thinking.block_binding and the

bool

thinking-binding-controls-2026-08-01 beta; any other

bool

extended-thinking row sends them only when the Agent opts in with

bool

anthropic_block_binding="drop_block".

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 model_information.json.

required

Returns:

Type Description
bool

True only when the row sets

bool

descriptions.<model>.produces_preserved_thinking_blocks: true.

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 model_information.json.

required

Returns:

Type Description
bool

False only when the row sets

bool

descriptions.<model>.supports_server_compaction: false. An absent

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 model_information.json.

required

Returns:

Type Description
bool

False only when the row sets

bool

descriptions.<model>.supports_thinking_block_binding: false.

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 name attribute of a server_tool_use block.

required

Returns:

Type Description
Optional[str]

Optional[str]: The standardized tool name, or None when name is

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 Agent(prefix_audit=...) value.

False

Returns:

Type Description
bool

True when the parameter is set or DPT_PREFIX_AUDIT is a truthy

bool

string (1/true/yes/on, case-insensitive). Unset (the

bool

default) and the falsy strings (0/false/no/off) leave the

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 Message.

required
logger Logger

Logger to warn on.

required

Returns:

Type Description
List[str]

List[str]: The error_code values seen, in block order.

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:

  1. A caller-supplied thinking={"block_binding": ...}. Anthropic's guidance for libraries is to forward it unchanged, so the toolkit adds nothing and returns None.
  2. anthropic_block_binding on the Agent.
  3. strict_prefix_binding=True on the Agent (sugar for "error").
  4. The DPT_ANTHROPIC_BLOCK_BINDING environment variable.
  5. 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 model_information.json.

required
logger Logger

Logger instance.

required
thinking_params Optional[dict]

The thinking configuration about to be sent, or None when this request sends none. A request with no thinking object has nothing to attach the field to, so the answer is always None — inventing one would turn thinking on and change behaviour materially.

None
anthropic_block_binding Optional[str]

"drop_block", "error", "off" or None (= let the env and the registry decide).

None
strict_prefix_binding bool

True means "error".

False

Returns:

Type Description
Optional[str]

"drop_block", "error", or None when nothing should be sent.

Optional[str]

With no caller or environment setting and a thinking object present,

Optional[str]

None is the answer for every row except the

Optional[str]

two that carry enforces_thinking_prefix_check (claude-fable-5-1

Optional[str]

and claude-opus-5-5), which resolve to "drop_block"; so no

Optional[str]

request body on any other row moves. prefix_mismatch_behavior

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 validate_built_in_tools output — tool name to :class:~doc_processing_toolkit.schemas.BuiltInToolConfig.

required

Returns:

Type Description
Optional[Dict[str, str]]

Optional[Dict[str, str]]: A fresh {"type": ..., "name": ...} dict

Optional[Dict[str, str]]

for the chosen variant, or None when tool search is not enabled for

Optional[Dict[str, str]]

this request.

Raises:

Type Description
ValueError

If config["variant"] is not "regex" or "bm25".

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 prefix_strip_fallback wording. The count of removed blocks is appended.

None
log_level int

The level reason is logged at. WARNING by default.

WARNING

Returns:

Type Description
list

A new list with thinking blocks removed. Text and tool_use blocks

list

are kept, and an assistant turn left with no blocks at all is dropped so

list

the request never carries an empty content array.

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]

AgentResult.input_transformations (or any list of entries).

required

Returns:

Type Description
Dict[str, int]

{"prefix_binding_mismatches": int, "model_binding_mismatches": int}.

Dict[str, int]

Entries with an unrecognised type or reason are counted as

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 async with, which the sync client's stream manager does not support.

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:

  • str: Text content
  • dict: Image {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
  • dict: Document {'type': 'base64', 'media_type': 'application/pdf', 'data': str, 'filename': str}
required
logger Logger

Logger instance (required) for logging messages.

required
mcp_servers list

List of local MCP server connection objects. Each dict must contain:

  • 'session': Active MCP ClientSession (required)
  • 'name': str (server name for identification)

Tools are extracted via session.list_tools() and converted to OpenAI format.

required
tool_choice str or dict

How model should select tools.

  • "auto" (default): Model decides when to call tools
  • "required" or "any": Must call at least one tool
  • "none": Cannot call tools
  • {"type": "tool", "name": "..."}: Force specific function
  • {"type": "allowed_tools", "names": [...]}: Restrict to subset

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 OPENAI_MAX_TOKENS_RECOVERY_MAX_PASSES times a run) if response is truncated.

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().

  • Example:

    {"effort": "low"|"medium"|"high"|"xhigh", "summary": "auto"|"concise"|"detailed", "mode": "standard"|"pro" (GPT-5.6 models only)}

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().

  • "low": Concise answers
  • "medium": Balanced (default for supported models)
  • "high": Thorough explanations and extensive code

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 supported_image_detail_values in model_information.json. Defaults to None (which uses "high"). This is a request-level setting — it is not configurable per image.

  • "low": Faster, lower cost, less detail
  • "high": Default. Higher detail, higher cost
  • "auto": Model decides optimal detail level
  • "original": Native resolution (gpt-5.4+ only)
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.

  • Examples:

    • {"web_search": BuiltInToolConfig(enabled=True, config={"search_context_size": "low"})}
    • {"code_execution": BuiltInToolConfig(enabled=True, config={"memory_limit": "4g"})}

⚠️ Note: When using built-in tools, parallel_tool_calls is auto-disabled.

None
tool_files list

Files for code execution tool.

  • Format: [{'type': 'base64', 'media_type': str, 'data': str, 'filename': str}]
  • Files are uploaded via OpenAI Files API and attached to code_interpreter.
  • Cleaned up automatically after the request completes.
None
mcp_remote_servers list

Remote MCP server or OpenAI Connector configurations for the remote_mcp built-in tool.

  • Remote MCP Server Example:

    [
        {
            "server_label": "deepwiki",
            "server_url": "https://mcp.deepwiki.com/mcp",
            "server_description": "Deep Wiki knowledge base",
            "require_approval": "never",
            "allowed_tools": ["search", "get_article"],
            "authorization": "Bearer token123"
        }
    ]
    
  • Required fields for MCP: server_label, server_url

  • Optional fields for MCP: server_description, require_approval, allowed_tools, authorization, headers

  • OpenAI Connector Example:

    [
        {
            "server_label": "Google Calendar",
            "connector_id": "connector_googlecalendar",
            "authorization": "ya29.A0AS3H6...",  # OAuth token (required)
            "require_approval": "never",
            "allowed_tools": ["search_events", "create_event"]
        }
    ]
    
  • Required fields for Connector: server_label, connector_id, authorization

  • Optional fields for Connector: require_approval, allowed_tools
  • allowed_tools is a list of tool names ([] exposes none) or OpenAI's {"tool_names": [...], "read_only": bool} object; any other value raises TypeError (0.5.1).

Available connectors:

  • connector_dropbox, connector_gmail,
  • connector_googlecalendar, connector_googledrive, connector_microsoftteams,
  • connector_outlookcalendar, connector_outlookemail, connector_sharepoint
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__' folder in cwd, one per run (0.5.3); a name this run already wrote is written as 'name (2).ext'.

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:

  • Path A (native): For models with 'supports_function_calling_and_structured_outputs: true' in model_information.json, uses text.format parameter for native structured outputs.
  • Path B (tool-based): For other models, creates a 'submit_final_response' tool. The model calls this tool when ready to provide the final structured response.

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:

  • strategy (str): "summarize" | "sliding_window" | "tool_result_clearing" | "combined". Default: "summarize".
  • trigger_threshold (float|int): Float 0.0–1.0 as percentage of context window, or int for absolute token count. Default: 0.8 (80%).
  • summary_model (str|None): Model for summarization calls. Default: None (uses agent model).
  • summary_prompt (str|None): Inline custom summarization prompt. Use {conversation} placeholder. Takes precedence over summary_prompt_file.
  • summary_prompt_file (str|None): File path to custom summarization prompt. Default: None.
  • keep_recent_messages (int): Messages to preserve in sliding_window / combined. Default: 5.
  • keep_recent_tool_results (int): Tool results to preserve in tool_result_clearing. Default: 3.
  • clear_tool_inputs (bool): Also clear tool call parameters. Default: False.
  • archive_history (bool): Save original conversation to JSON before compacting. Default: True.
  • archive_dir (str): Directory for archive files. Default: "./compaction_archives".
  • include_archive_path_in_summary (bool): Include archive file path in summary output. Default: True.
  • min_messages_before_compaction (int): Minimum messages before triggering. Default: 4.
  • max_compactions_per_session (int|None): Limit compaction count. Default: None.
  • combined_order (list): Strategy order for combined. Default: ["tool_result_clearing", "sliding_window", "summarize"].

Examples:

# Summarize at 60% context usage
{"strategy": "summarize", "trigger_threshold": 0.6}

# Sliding window keeping last 6 messages
{"strategy": "sliding_window", "trigger_threshold": 0.8, "keep_recent_messages": 6}

# Combined strategy with archiving
{"strategy": "combined", "trigger_threshold": 5000, "archive_history": True}
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 AgentSession. Default: None.

None
stream_callback callable

Callback invoked for each streaming event as it arrives. Signature: stream_callback(event_type, data) where event_type is "text_delta" for output text or "thinking_delta" for streamed reasoning summaries. Passed through to _run_tool_calling_loop_openai for real-time event emission. Used by Agent.stream(). Default: None.

None
service_tier str

A tier name the model's registry row publishes under service_tiers; anything else is dropped with a warning. "priority" is sent as service_tier="fast" (OpenAI renamed priority processing to Fast mode); "flex" and "ultrafast" (gpt-6-astra only, 6x Standard) are sent verbatim. Billing follows the tier the response reports it SERVED, read from the completed response's service_tier echo (the tier name on GPT-5.6 rows, the wire value on GPT-6 rows; both are recognised). A request not served at the tier it asked for is billed at the tier that ran and surfaced as tier_downgraded — cheaper than asked for "priority" or "ultrafast", dearer for "flex". Default: None.

None
hooks_runner HookRunner

Bridge to the caller's hooks, supplied by the Agent layer. The loop awaits it at each hook point, honours pause/abort/skip_tool directives, drains queued inject_message directives, and reports per-request usage to it. Default: None (no hooks).

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 predicate(tool_name, server_name) — the second argument is the MCP server the tool came from, or None. Matching entries are stamped defer_loading: true, so only their name and description reach the model until it searches for them; the loaded definitions are injected at the end of the context window, so the cached prefix survives. Requires built_in_tools={"tool_search": ...}; without it every function loads eagerly and one warning is logged. Hosted tools are never deferred. Default: None.

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0
max_tool_result_chars Optional[int]

Character cap on each tool result fed back to the model. None derives it from the registry (utils.resolve_max_tool_result_chars: one character per token of context window); 0 turns it off. A longer result is cut with a visible … [truncated: N of M characters shown; ...] marker and one WARNING (utils.cap_tool_result).

None
tool_result_preview_chars int

How many characters of each tool result's str() the tool_call_result stream and hook events carry. 500 (the default) is the preview they always carried; 0 carries the whole result plus result_data, the result as JSON data (utils.tool_result_event_fields). Every event also says result_truncated. What the model is sent is unaffected: that copy is max_tool_result_chars's.

DEFAULT_TOOL_RESULT_PREVIEW_CHARS
truncation_store Any

The run's utils.TruncatedResultStore when Agent(truncated_result_read_chars=) is set: a result the size cap cuts is kept there in full, its marker names read_truncated_result, and that tool's own slices are not cut again. None (the default) keeps the original marker.

None
openai_transport str

"http" (the default) or "websocket" (0.5.2). With "websocket" the run's requests go over one WebSocket to the Responses API, opened at the first request and closed when the attempt ends: each request after the first sends only its new items with previous_response_id while the history before them is unchanged. Results, events, hooks, billing and retries are the same as over HTTP; a loop of several requests is faster and a run of one or two is slower (the socket takes one to two seconds to open). None reads DPT_OPENAI_TRANSPORT. An unrecognised value is ignored with one warning, and without the websockets package the run uses HTTP. See docs/concepts/openai_websocket_transport.md.

None

Returns:

Name Type Description
dict dict

Result containing:

  • data (dict or str): Final response - the parsed JSON dict when response_schema was supplied (a plain dict: the schema validates the output, it is never returned as a model instance), otherwise the response text
  • response: Full API response object from last iteration
  • messages (list): Complete conversation history (input_list)
  • completed_iterations (int): Number of completed loop iterations
  • custom_tools (list): All custom MCP tool names used
  • built_in_tools_used (list): Built-in tools CONFIGURED for the run — the echo of the requested built-in tool names, whether or not the model ever reached for them.
  • built_in_tools_invoked (list): Deduplicated, sorted built-in tool names with observed evidence that they actually ran: web_search searches counted off the response, code_interpreter containers or created files observed, and mcp_call output items for remote_mcp. Empty when built-in tools were configured but never invoked. A tool_search_call output item counts as observed tool_search usage and costs nothing — hosted tool search is not separately metered.
  • deferred_tools (list): The client function names actually stamped defer_loading: true this run, in wire order. Empty whenever deferral did not apply, for any reason.
  • input_tokens (int): Total input tokens across all iterations
  • output_tokens (int): Total output tokens across all iterations
  • reasoning_tokens (int): Total reasoning tokens (for reasoning models)
  • cached_input_tokens (int): Cached prompt tokens summed across iterations, a SUBSET of input_tokens already re-priced at the cached rate
  • request_cost_records (list): One record per billed API request, each with input_tokens, output_tokens, reasoning_tokens, cached_input_tokens, served_model, requested_tier, served_tier and cost. cost below is the sum of these token costs plus the per-run tool costs. A record also carries estimated: True (0.5.2) when a failure event ended its request on the first attempt after part of the reply had streamed: its output_tokens are a count of the streamed text, priced at standard rates with no input tokens, and cost_estimated below is True.
  • tier_downgraded (bool): Whether any request of the run was served at a tier other than the one it asked for (and billed at the tier that ran)
  • cost (float): Estimated cost in USD
  • cost_estimated (bool): Whether cost includes estimates
  • tool_costs_estimated (dict): Per-tool cost estimation flags
  • downloaded_files (list, optional): List of file info dicts for files downloaded from the code execution tool
  • token_source (str): Source of token counts ('api_response')
  • iteration_metrics (list): Metrics for each tool calling iteration. Each item contains

    • iteration_number (int): The iteration number
    • input_tokens (int): Input tokens for this iteration
    • output_tokens (int): Output tokens for this iteration
    • reasoning_tokens (int): Thinking tokens for this iteration
    • cached_input_tokens (int): Cached prompt tokens for this iteration
    • cost (float): Estimated cost for this iteration
    • duration_ms (int): Duration of this iteration in milliseconds
    • tool_calls (list): List of tool calls made in this iteration
    • stop_reason (str): Finish reason for this iteration
    • compaction_triggered (bool), compaction_strategy (str or None), compaction_tokens_cleared (int): Compaction bookkeeping for this iteration (omitted on the record emitted for an early exit)
    • retry_count (int), retry_cost (float), retry_input_tokens (int), retry_output_tokens (int), retry_details (list): Retry bookkeeping for this iteration
    • compaction_count (int): Number of compaction events during the run.
    • compaction_archives (list): File paths to archived conversations.
    • compaction_input_tokens (int): Input tokens consumed by summarization.
    • compaction_output_tokens (int): Output tokens from summarization.
    • compaction_cost (float): Cost of summarization calls.
    • error (str or None): Error message if failed
  • Note: The error return (built when an unexpected exception ends the run) omits cached_input_tokens, request_cost_records and tier_downgraded; every other key above is present.

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:

  • OpenAI SDK not available
  • Client is None or invalid
  • Model doesn't support function calling (supports_function_calling: false)
  • Invalid combination of built-in and MCP tools
APIError

For API errors after retries exhausted

Notes

Tool Choice Exit Behavior:

  • "auto": Normal behavior - loop until model returns final text response or max_iterations reached
  • "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_TOKENS truncation 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:

  • tool_choice
  • max_tokens
  • temperature
  • reasoning_config
  • verbosity_config
  • built_in_tools
  • tool_files
  • mcp_remote_servers
  • parallel_tool_calls
  • remove_citations
  • code_execution_output_dir
  • max_tool_iterations
  • response_schema
  • image_detail
{}

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:

  • data (dict or str): Parsed JSON dict when response_schema was supplied, otherwise the final response text
  • response: Full API response object
  • messages (list): Complete conversation history
  • completed_iterations (int): Number of completed tool calling iterations
  • custom_tools (list): Custom MCP tool names that were called
  • built_in_tools_used (list): Built-in tools CONFIGURED for the run
  • built_in_tools_invoked (list): Built-in tools observed to have run
  • input_tokens (int): Total input tokens
  • output_tokens (int): Total output tokens
  • cost (float): Estimated cost in USD
  • error (str or None): Error message if failed

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 model_information.json config file.

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:

  • base64 Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
  • Document: {'type': 'base64', 'media_type': 'application/pdf', 'data': str, 'filename': str}
required
response_schema BaseModel

Pydantic model defining the expected JSON output structure.

  • Note: Concurrent use with built_in_tools is gated per model on descriptions.<model>.supports_built_in_tools_and_structured_outputs in model_information.json; a model whose row does not list the requested built-in raises ValueError before any request is sent.
  • Note: When both response_schema and built_in_tools are None, 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.

    • "internal_reasoning"
    • "thoughts"
    • "reasoning"
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:

{"effort": "none" (gpt-5.1 gpt-5.2 models only) | "minimal" (gpt-5 models only) | "low" | "medium" | "high" | "xhigh" (only supported for models after and including gpt-5.1-codex-max),
"summary": "auto" | "concise" (supported for all models after  and including gpt-5) | "detailed",
"mode": "standard" | "pro" (GPT-5.6 models only)}

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).

  • For gpt-5.1 and gpt-5.2, default values for "effort" and "summary" are "none" and "auto" respectively (if 'reasoning_config' is None).
  • For gpt-5-pro, default values (and the only allowed values) for "effort" and "summary" are "high" and "auto" respectively (if 'reasoning_config' is None).
  • For gpt-5.2-pro, default values for "effort" and "summary" are "medium" and "auto" respectively (if 'reasoning_config' is None). The only allowed values for "effort" are "medium", "high" and "xhigh".
  • For gpt-5.6 models (sol/terra/luna), "mode" selects standard or pro-grade reasoning; default "effort" is "medium" in both modes. Mode support and the pro-mode effort values are registry-driven ("supported_reasoning_modes" and "supported_reasoning_values_pro_mode" in model_information.json — pro mode requires at least "medium"); an unsupported effort in pro mode is dropped so the API default applies.
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.

  • Example: "low"
None
image_detail str

Image detail level applied uniformly to all images in the request. Validated via validate_image_detail_openai() against supported_image_detail_values in model_information.json. Defaults to None (which uses "high"). This is a request-level setting — it is not configurable per image.

  • "low": Faster, lower cost, less detail
  • "high": Default. Higher detail, higher cost
  • "auto": Model decides optimal detail level
  • "original": Native resolution (gpt-5.4+ only)
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.

  • Example: {"web_search": BuiltInToolConfig(enabled=True, config={"search_context_size": "low"})}
  • Example: {"code_execution": BuiltInToolConfig(enabled=True, config={"memory_limit": "4g"})}
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.

  • Remote MCP Server Example:

    [
        {
            "server_label": "deepwiki",
            "server_url": "https://mcp.deepwiki.com/mcp",
            "server_description": "Deep Wiki knowledge base",
            "require_approval": "never",
            "allowed_tools": ["search", "get_article"],
            "authorization": "Bearer token123"
        }
    ]
    
    • Required fields for MCP: server_label, server_url
    • Optional fields for MCP: server_description, require_approval, allowed_tools, authorization, headers
  • OpenAI Connector Example:

    [
        {
            "server_label": "Google Calendar",
            "connector_id": "connector_googlecalendar",
            "authorization": "ya29.A0AS3H6...",  # OAuth token (required)
            "require_approval": "never",
            "allowed_tools": ["search_events", "create_event"]
        }
    ]
    
    • Required fields for Connector: server_label, connector_id, authorization
    • Optional fields for Connector: require_approval, allowed_tools
    • allowed_tools is a list of tool names ([] exposes none) or OpenAI's {"tool_names": [...], "read_only": bool} object; any other value raises TypeError (0.5.1).

Available connectors:

  • connector_dropbox, connector_gmail, connector_googlecalendar,
  • connector_googledrive, connector_microsoftteams, connector_outlookcalendar,
  • connector_outlookemail, connector_sharepoint
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__' in the current working directory, one per run (0.5.3); a name this run already wrote is written as 'name (2).ext'.

  • Example: "/path/to/output/dir"
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 AgentSession. Default: None.

None
stream_callback callable

Callback invoked during streaming with (event_type: str, content: str, metadata: dict | None) arguments. Emits "text_delta" events for output text and "thinking_delta" events for streamed reasoning summaries. This path is always schema-constrained when response_schema is given (Path A), so its text_delta events carry {"structured_output": True} as metadata (B11) whenever the callback accepts a third argument. Default: None.

None
on_unsupported_part str

"drop" (default) warns and filters a prompt part the model cannot accept; "raise" refuses the run with UnsupportedPartError before any request is sent (B12). Default: "drop".

'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.

None
request_start_emitter RequestStartEmitter

Opt-in request_start emitter (B10); one event immediately before the provider send. Default: None.

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0
service_tier str

A tier name the model's registry row publishes under service_tiers; anything else is dropped with a warning. "priority" is sent as service_tier="fast" (OpenAI renamed priority processing to Fast mode); "flex" and "ultrafast" (gpt-6-astra only, 6x Standard) are sent verbatim. Billing follows the tier the response reports it SERVED, read from the completed response's service_tier echo (the tier name on GPT-5.6 rows, the wire value on GPT-6 rows; both are recognised). A request not served at the tier it asked for is billed at the tier that ran and surfaced as tier_downgraded — cheaper than asked for "priority" or "ultrafast", dearer for "flex". Default: None.

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 (google.genai.Client). Must be initialized with valid API key.

required
model_name str

Gemini model name (e.g., "gemini-3-flash-preview"). Must match a model in model_information.json with supports_function_calling=true.

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:

  • Base64 Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)

  • Video: {'type': 'video', 'media_type': str, 'data': bytes}

    • (media_type='video/mp4' | 'video/mpeg' | 'video/mov' | 'video/avi' | 'video/x-flv' | 'video/mpg' | 'video/webm' | 'video/wmv' | 'video/3gpp')
  • Audio: {'type': 'audio', 'media_type': str, 'data': bytes}

    • (media_type='audio/wav' | 'audio/mp3', | 'audio/aiff' | 'audio/aac' | 'audio/ogg' | 'audio/flac')
  • Document: {'type': 'document', 'media_type': str, 'data': bytes}

    • (media_type='application/pdf' | 'application/x-javascript' | 'text/javascript' | 'application/x-python' | 'text/x-python' | 'text/plain' | 'text/html' | 'text/css' | 'text/md' | 'text/csv' | 'text/xml' | 'text/rtf')
  • YouTube: {'type': 'youtube', 'url': str}

required
logger Logger

Logger instance for logging messages.

required
mcp_servers list

List of MCP server connection objects. Each dict must contain:

  • 'session': Active MCP ClientSession
  • 'name': str (server name for identification)

Tools are extracted via session.list_tools() and converted to Google format.

required
tool_choice str or dict

How model should select tools.

  • "auto" (default): Model decides whether to use functions
  • "any": Must use at least one tool (guarantees function call)
  • "none": Cannot use tools
  • "validated": Ensures schema adherence (preview feature)
  • {"type": "tool", "name": [...]}: Force specific tool(s)

Tool Choice Exit Behavior:

  • "auto", "validated": Normal behavior — loop until model returns final text response or max_iterations reached
  • "none": No tools used (tools disabled)
  • "any": Exit immediately after first tool call(s), since the model will never return a final text response with this setting
  • {"type": "tool", "name": "tool_name"}: Exit when the specified tool is called, since the model is forced to use that tool on every turn.
  • {"type": "tool", "name": ["tool1", "tool2"]}: Exit immediately after first tool call(s), since the model is restricted to only the specified tools and will not return a final text response.

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 "any" to ensure the model calls the submit_final_response tool.

'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 validate_thinking_budget_google from utils.py.

  • Gemini 2.5 Flash: 0–24,576 (0 disables, -1 = dynamic)
  • Gemini 2.5 Pro: 128–32,768 (cannot disable, -1 = dynamic)
  • Gemini 2.5 Flash Lite: 512–24,576 (0/None disables, -1 = dynamic)

Note: Cannot be used together with thinking_level.

None
thinking_level str

Thinking level for Gemini 3 models. Validated via validate_thinking_level_google from utils.py.

  • "minimal": Matches "no thinking" for most queries
  • "low": Minimizes latency and cost
  • "medium": Balanced thinking (Flash only)
  • "high": Maximizes reasoning depth (default)

Note: Cannot be used together with thinking_budget. IMPORTANT: Even with thinking_level="minimal", thought signatures are still MANDATORY for Gemini 3 function calling.

None
video_metadata dict

Video preprocessing metadata. Applied to all video inputs. Supported fields:

  • "start_offset" (str): Start time (e.g., "10s", "1250s")
  • "end_offset" (str): End time (e.g., "20s", "1570s")
  • "fps" (float): Frame rate (0.0, 24.0]. Default is 1.0.

  • Example: {"start_offset": "10s", "end_offset": "30s", "fps": 12.0}

None
built_in_tools dict

Built-in tools to combine with the custom MCP tools (Preview — Gemini 3 models only). Supported: google_search_grounding, code_execution, google_url_context. Custom declarations and built-ins are sent as SEPARATE Tool objects with include_server_side_tool_invocations=True — the construction the API requires since mid-2026 (the earlier merged single-Tool shape is silently accepted but the built-ins never execute); the caller's function-calling mode is preserved. Models whose registry entry has supports_concurrent_built_in_and_custom_tools: false reject the combination at validation time.

Validation: If both mcp_servers AND built_in_tools are provided, validate_builtin_tools_concurrency raises a ValueError unless the model's supports_concurrent_built_in_and_custom_tools entry in model_information.json is true — every Gemini 3 text row carries it (the registry is the list; do not rely on a count here, it moves with each release). Gemini 3 image rows and all Gemini 2.5 rows are false.

For built-in tools only: Use call_google_llm_structured_output_text with the built_in_tools parameter when you only need built-in tools without MCP server integration.

Supported built-in tools:

  • "google_search_grounding": Web search capability
  • "code_execution": Code execution sandbox
  • "google_url_context": URL content retrieval

Preview limitation: with server-side tool invocations circulated, the final response currently carries no executable_code or inline_data parts, so code-execution file artifacts are not extractable in combination mode today — downloaded_files comes back empty. Extraction already runs per iteration, so artifacts appear automatically once the API returns those parts.

Default: None

None
tool_files list

Files uploaded via the Google Files API for the code_execution built-in tool. Only used when code_execution is in built_in_tools (tool combination).

Supported formats (when available):

  • Base64 image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
  • Document: {'type': 'document', 'media_type': 'application/pdf', 'data': bytes}

Default: None

None
remove_citations bool

Remove inline citations. Default: False.

False
media_resolution str

Global media resolution. Validated via validate_media_resolution_google from utils.py. Supported values (model-dependent):

  • "MEDIA_RESOLUTION_UNSPECIFIED": Default setting
  • "MEDIA_RESOLUTION_LOW": Lower detail, faster, lower cost
  • "MEDIA_RESOLUTION_MEDIUM": Balanced
  • "MEDIA_RESOLUTION_HIGH": Higher detail (recommended)
None
media_resolution_list list

Per-part media resolution. Validated via validate_per_part_media_resolution_google from utils.py. List of resolution strings matching user_prompt_parts order (media parts only). Requires Gemini 3 model. Per-part values override global media_resolution. Additional value: "MEDIA_RESOLUTION_ULTRA_HIGH" (Gemini 3 per-part only).

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:

  • Path A (native): For models with supports_function_calling_and_structured_outputs: true in model_information.json, uses response_schema in generation_config for native structured outputs.
  • Path B (tool-based): For other models, creates a submit_final_response tool. The model calls this tool when ready to provide the final structured response.

When tool_choice override: For Path B, tool_choice is overridden to "any" to ensure tool use. This override is logged as a warning.

If the schema has any of these fields (case insensitive), thinking 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:

  • strategy (str): "summarize" | "sliding_window" | "tool_result_clearing" | "combined". Default: "summarize".
  • trigger_threshold (float|int): Float 0.0–1.0 as percentage of context window, or int for absolute token count. Default: 0.8 (80%).
  • summary_model (str|None): Model for summarization calls. Default: None (uses agent model).
  • summary_prompt (str|None): Inline custom summarization prompt. Use {conversation} placeholder. Takes precedence over summary_prompt_file.
  • summary_prompt_file (str|None): File path to custom summarization prompt. Default: None.
  • keep_recent_messages (int): Messages to preserve in sliding_window / combined. Default: 5.
  • keep_recent_tool_results (int): Tool results to preserve in tool_result_clearing. Default: 3.
  • clear_tool_inputs (bool): Also clear tool call parameters. Default: False.
  • archive_history (bool): Save original conversation to JSON before compacting. Default: True.
  • archive_dir (str): Directory for archive files. Default: "./compaction_archives".
  • include_archive_path_in_summary (bool): Include archive file path in summary output. Default: True.
  • min_messages_before_compaction (int): Minimum messages before triggering. Default: 4.
  • max_compactions_per_session (int|None): Limit compaction count. Default: None.
  • combined_order (list): Strategy order for combined. Default: ["tool_result_clearing", "sliding_window", "summarize"].

Examples::

# Summarize at 60% context usage
{"strategy": "summarize", "trigger_threshold": 0.6}

# Sliding window keeping last 6 messages
{"strategy": "sliding_window", "trigger_threshold": 0.8, "keep_recent_messages": 6}

# Combined strategy with archiving
{"strategy": "combined", "trigger_threshold": 5000, "archive_history": True}
None
history_messages list

Pre-normalised provider-native Content objects from previous session turns. When provided, these are prepended to the initial contents list before the tool-calling loop, enabling multi-turn conversation continuity within an AgentSession. Default: None.

None
stream_callback callable

Callback invoked for each streaming text chunk as it arrives. Signature: stream_callback(event_type, data) where event_type is "text_delta" and data is the text fragment. Passed through to _run_tool_calling_loop_google for real-time event emission. Used by Agent.stream(). Default: None.

None
code_execution_output_dir str

Directory path to save files created by the code execution tool. If None and code execution creates files, they are saved to a fresh folder google_code_execution_files_<timestamp>_<random> in the current working directory, one per run (0.5.3); a name this run already wrote is written as name (2).ext. Default: None.

None
service_tier str

A tier name the model's registry row publishes under service_tiers ("priority", "flex"); anything else is dropped with a warning. Google takes the name verbatim on the wire. Billing follows the tier Google reports it SERVED, resolved from usageMetadata.serviceTier in the response body and then the x-gemini-service-tier response header. When neither is readable — which is every streamed request on google-genai 2.24.0 — the request is billed at standard rates and marked served_tier="unverifiable" with served_tier_source="none", so the recorded cost may be UNDER-stated. A request not served at the tier it asked for is surfaced as tier_downgraded. Default: None.

None
file_active_timeout_s float

Ceiling, in seconds, on the wait for a Files API upload to reach ACTIVE before the request proceeds (B15). It applies to every media part of this call. Without it the wait is 60 s for images (and for documents on this path) and 120 s for video and audio, which a ten-minute MP4 exceeds. Bounds 1-3600; out of range raises. Falls back to DPT_GOOGLE_FILE_ACTIVE_TIMEOUT_S and then to the per-part default. Default: None.

None
file_poll_interval_s float

Seconds between files.get state checks while waiting. Bounds 0.05-60, must not exceed the timeout. Falls back to DPT_GOOGLE_FILE_POLL_INTERVAL_S and then to the per-part default (1 s for images, 2 s otherwise). Default: None.

None
file_poll_backoff float

Multiplier applied to the poll interval after each check, bounds 1-10. 1.0 keeps the fixed cadence that shipped before B15. Falls back to DPT_GOOGLE_FILE_POLL_BACKOFF. Default: None.

None
hooks_runner HookRunner

Bridge to the caller's hooks, supplied by the Agent layer. The loop awaits it at each hook point, honours pause/abort/skip_tool directives, drains queued inject_message directives, and reports per-request usage to it. Default: None (no hooks).

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0
max_tool_result_chars Optional[int]

Character cap on each tool result fed back to the model. None derives it from the registry (utils.resolve_max_tool_result_chars: one character per token of context window); 0 turns it off. A longer result is cut with a visible … [truncated: N of M characters shown; ...] marker and one WARNING (utils.cap_tool_result).

None
tool_result_preview_chars int

How many characters of each tool result's str() the tool_call_result stream and hook events carry. 500 (the default) is the preview they always carried; 0 carries the whole result plus result_data, the result as JSON data (utils.tool_result_event_fields). Every event also says result_truncated. What the model is sent is unaffected: that copy is max_tool_result_chars's.

DEFAULT_TOOL_RESULT_PREVIEW_CHARS
truncation_store Any

The run's utils.TruncatedResultStore when Agent(truncated_result_read_chars=) is set: a result the size cap cuts is kept there in full, its marker names read_truncated_result, and that tool's own slices are not cut again. None (the default) keeps the original marker.

None
media_uploads_sink list

Receives one record per Files API upload the initial user content makes (part_index, uri, name, mime_type, size, sha256, uploaded_at, expiration_time), for AgentResult.media_uploads. Default: None (nothing recorded).

None

Returns:

Name Type Description
dict dict

Result containing:

  • data (dict or str): Final response - the parsed JSON dict when response_schema was supplied (a plain dict: the schema validates the output, it is never returned as a model instance), otherwise the response text
  • response: Full API response object (last response)
  • messages (list): Complete conversation history
  • completed_iterations (int): Number of completed loop iterations
  • custom_tools (list): All custom MCP tool names used
  • built_in_tools_used (list): The CONFIGURED echo — built-in tools active under tool combination, i.e. what was validated into the request. It says nothing about whether the model used them, and is only included when built_in_tools was supplied.
  • built_in_tools_invoked (list): Deduped, sorted built-in tools with evidence in the responses that they actually RAN (grounding metadata, url_context_metadata, executable_code / code_execution_result parts, extracted artifacts, counted searches), unioned across every iteration of the loop. Always present; [] when nothing ran or on the error return.
  • distinct_urls (list): Sorted grounding URLs seen across every iteration, from grounding_metadata.grounding_chunks. Always present; [] when no grounded search ran. Google returns its own redirect URLs (vertexaisearch.cloud.google.com/...), which are reported verbatim.
  • downloaded_files (list): File artifacts produced by built-in tools (code execution outputs, inline_data blobs), extracted per iteration; only included when artifacts were produced.
  • input_tokens (int): Total input tokens
  • output_tokens (int): Total output tokens, including the thought tokens Google reports separately. They are billed at the output rate per request, and reasoning_tokens / thinking_tokens below name the share of this total they account for — never an addition to it
  • thinking_tokens (int): Thinking tokens (if thinking enabled), a SUBSET of output_tokens
  • cached_input_tokens (int): Cached prompt tokens summed across iterations, a SUBSET of input_tokens already re-priced at the cached rate
  • request_cost_records (list): One record per billed API request, each with input_tokens, output_tokens, reasoning_tokens, cached_input_tokens, served_model, requested_tier, served_tier and cost. cost below is the sum of these token costs plus the per-run tool costs.
  • tier_downgraded (bool): Whether a requested priority tier was silently served at the standard tier on any request of the run
  • cost (float): Estimated cost in USD
  • cost_estimated (bool): Whether cost includes estimates
  • tool_costs_estimated (dict): Per-tool cost estimation flags
  • token_source (str): Source of token counts ("api_response")
  • iteration_metrics (list): Per-iteration metrics, each with iteration_number, input_tokens, output_tokens, reasoning_tokens, cached_input_tokens, cost, duration_ms, tool_calls, stop_reason, the input_token_breakdown / output_token_breakdown / tool_use_prompt_token_details breakdowns, and compaction (compaction_triggered, compaction_strategy, compaction_tokens_cleared) plus retry (retry_count, retry_cost, retry_input_tokens, retry_output_tokens, retry_details) bookkeeping. Early exits (content filter, malformed function call, blocked prompt, a forced-tool exit, ...) also emit one record for the pass that was in flight, so a billed request is never missing from this list.
  • compaction_count (int): Number of compaction events during the run.
  • compaction_archives (list): File paths to archived conversations.
  • compaction_input_tokens (int): Input tokens consumed by summarization.
  • compaction_output_tokens (int): Output tokens from summarization.
  • compaction_cost (float): Cost of summarization calls.
  • error (str or None): Error message if failed

  • Note: The error return (built when an unexpected exception ends the run) omits cached_input_tokens, request_cost_records and tier_downgraded; every other key above is present.

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 supports_concurrent_built_in_and_custom_tools false (the combination is supported on every Gemini 3 text row), both thinking_budget AND thinking_level provided, or invalid thinking configuration.

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_tokens recovery on truncation (at most GOOGLE_MAX_TOKENS_RECOVERY_MAX_PASSES raises)

Critical:

  • Validates supports_function_calling from model_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_tools true (every Gemini 3 text row); a ValueError is raised only when that flag is false
  • thinking_budget and thinking_level are 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 (google.genai.Client).

required
model_name str

Gemini model name (e.g., "gemini-3-flash-preview").

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 call_google_llm_function_calling.

{}

Returns:

Name Type Description
dict dict

Same return structure as call_google_llm_function_calling. See async function docstring for complete details.

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 call_google_llm_function_calling directly with await.

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 tools
  • max_tokens: Maximum output tokens
  • temperature: Sampling temperature
  • thinking_budget: Thinking budget for Gemini 2.5 models
  • thinking_level: Thinking level for Gemini 3 models
  • video_metadata: Video preprocessing metadata
  • built_in_tools: Built-in tools combined with custom MCP tools (Preview, Gemini 3)
  • tool_files: File uploads for the code_execution built-in tool
  • remove_citations: Remove inline citations from response
  • media_resolution: Global media resolution for all media parts
  • media_resolution_list: Per-part media resolution override
  • max_tool_iterations: Maximum tool calling iterations
  • response_schema: Pydantic model for structured output
  • file_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 model_information.json config file.

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:

  • Base64 Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)

  • Video: {'type': 'video', 'media_type': str, 'data': bytes}

    • (media_type='video/mp4' | 'video/mpeg' | 'video/mov' | 'video/avi' | 'video/x-flv' | 'video/mpg' | 'video/webm' | 'video/wmv' | 'video/3gpp')
  • Audio: {'type': 'audio', 'media_type': str, 'data': bytes}

    • (media_type='audio/wav' | 'audio/mp3', | 'audio/aiff' | 'audio/aac' | 'audio/ogg' | 'audio/flac')
  • Document: {'type': 'document', 'media_type': str, 'data': bytes}

    • (media_type='application/pdf' | 'application/x-javascript' | 'text/javascript' | 'application/x-python' | 'text/x-python' | 'text/plain' | 'text/html' | 'text/css' | 'text/md' | 'text/csv' | 'text/xml' | 'text/rtf')
  • YouTube: {'type': 'youtube', 'url': str}

required
response_schema BaseModel

Pydantic model defining the expected JSON output structure.

  • Note: Concurrent use with built_in_tools is gated per model on descriptions.<model>.supports_built_in_tools_and_structured_outputs in model_information.json; a model whose row does not list the requested built-in raises ValueError before any request is sent.
  • Note: When both response_schema and built_in_tools are None, 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.

    • "internal_reasoning"
    • "thoughts"
    • "reasoning"
None
logger Logger

Logger instance for logging messages.

required
temperature float

Sampling temperature for generation. Left unset, 1.0 is sent to a row whose registry hyperparameters accept it and nothing to one that does not; only a value the caller supplies logs DROPPING temperature when the row rejects it.

_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 model_information.json. Defaults to None.

None
thinking_budget int

Optional thinking budget. Not supported for all models. Defaults to None.

  • For the "gemini-2.5-flash" and "gemini-2.5-flash-preview" models, the thinking budget can be an integer value between 0 and 24,576 (inclusive). A value of 0 disables extended thinking, while a value of None enables dynamic thinking (model decides how much thinking is needed).
  • For the "gemini-2.5-pro" model, the thinking budget can be an integer value between 128 and 32,768 (inclusive). It is not possible to disable thinking for this model, and a value of None will also enable dynamic thinking.
  • For the "gemini-2.5-flash-lite" and "gemini-2.5-flash-lite-preview" models, the thinking budget can be an integer value between 512 and 24,576 (inclusive). A value of 0 or None disables extended thinking, while a value of -1 enables dynamic thinking.
  • Invalid Values outside these ranges, will be set to a value of -1, which enables dynamic thinking.

  • Note: Cannot be used together with thinking_level parameter. Using both will result in a 400 error.

None
thinking_level str

Optional thinking level ("minimal", "low", "medium" or "high"). Not supported on all models. Defaults to None.

  • "minimal": Matches the "no thinking" setting for most queries. The model may think very minimally for complex coding tasks. Minimizes latency for chat or high throughput applications.
  • "low": Minimizes latency and cost, best for simple tasks.
  • "medium": Balanced thinking for most tasks.
  • "high": Maximizes reasoning depth (default for supported models).
  • Note: Cannot be used together with thinking_budget parameter. Using both will result in a 400 error.
None
video_metadata dict

Optional video preprocessing metadata for video inputs. Applies only to video content types. Defaults to None. Supported fields:

  • "start_offset" (str): Start time of video clip in duration format (e.g., "10s", "1250s", "3.5s"). Optional.
  • "end_offset" (str): End time of video clip in duration format (e.g., "20s", "1570s", "10.2s"). Optional.
  • "fps" (float): Frame rate for video analysis, range (0.0, 24.0]. Default is 1.0 if not specified. Optional.

Example: {"start_offset": "10s", "end_offset": "30s", "fps": 12.0}

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 validate_built_in_tools function will be configured. Supported tools: "web_search", "code_execution", "url_context" The value for each key should be a BuiltInToolConfig object with enabled (bool) and config (dict) fields. Example: {"web_search": BuiltInToolConfig(enabled=True, config={})}

None
tool_files list

List of files for code execution tool. Files should be in the same format as user_prompt_parts. Supported formats:

  • {'type': 'base64', 'media_type': str, 'data': str} for images (any image/* MIME type),
  • or {'type': 'document', 'media_type': str, 'data': bytes} for documents. Files uploaded automatically via Google 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
media_resolution str

Global media resolution for all media parts. Defaults to None (model default). Supported values (model-dependent):

  • "MEDIA_RESOLUTION_UNSPECIFIED": Default setting (varies by model)
  • "MEDIA_RESOLUTION_LOW": Lower detail, faster processing, lower cost
  • "MEDIA_RESOLUTION_MEDIUM": Balance of detail, cost, and latency
  • "MEDIA_RESOLUTION_HIGH": Higher detail (recommended for most use cases)
  • Example: "MEDIA_RESOLUTION_HIGH"
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):

  • "MEDIA_RESOLUTION_UNSPECIFIED": Default setting (varies by model)
  • "MEDIA_RESOLUTION_LOW": Lower detail, faster processing, lower cost
  • "MEDIA_RESOLUTION_MEDIUM": Balance of detail, cost, and latency
  • "MEDIA_RESOLUTION_HIGH": Higher detail (recommended for most use cases)
  • "MEDIA_RESOLUTION_ULTRA_HIGH": Highest detail (Gemini 3 per-part only)
  • Example: ["MEDIA_RESOLUTION_HIGH", "MEDIA_RESOLUTION_LOW"] for 3 parts (text, image1, image2). The first text part is ignored.
  • Note: Requires Gemini 3 model. Per-part values override global media_resolution.
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__' in the current working directory, one per run (0.5.3); a name this run already wrote is written as 'name (2).ext'.

  • Example: "/path/to/output/dir"
None
in_session bool

When True, indicates this call is part of a multi-turn AgentSession. Uploaded files are not deleted in the finally block so they remain available for subsequent turns. Default: False.

False
history_messages list

Pre-normalised provider-native Content objects from previous session turns. When provided, these are prepended to the contents list before the API call, enabling multi-turn conversation continuity within an AgentSession. Default: None.

None
stream_callback callable

Callback invoked during streaming with (event_type: str, content: str) arguments. Currently emits "text_delta" events as text chunks arrive. Default: None.

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0
service_tier str

A tier name the model's registry row publishes under service_tiers ("priority", "flex"); anything else is dropped with a warning. Google takes the name verbatim on the wire. Billing follows the tier Google reports it SERVED, resolved from usageMetadata.serviceTier in the response body and then the x-gemini-service-tier response header. When neither is readable — which is every streamed request on google-genai 2.24.0 — the request is billed at standard rates and marked served_tier="unverifiable" with served_tier_source="none", so the recorded cost may be UNDER-stated. A request not served at the tier it asked for is surfaced as tier_downgraded. Default: None.

None
file_active_timeout_s float

Ceiling, in seconds, on the wait for a Files API upload to reach ACTIVE before the request proceeds (B15). It applies to every media part of this call. Without it the wait is 60 s for images (and for documents on this path) and 120 s for video and audio, which a ten-minute MP4 exceeds. Bounds 1-3600; out of range raises. Falls back to DPT_GOOGLE_FILE_ACTIVE_TIMEOUT_S and then to the per-part default. Default: None.

None
file_poll_interval_s float

Seconds between files.get state checks while waiting. Bounds 0.05-60, must not exceed the timeout. Falls back to DPT_GOOGLE_FILE_POLL_INTERVAL_S and then to the per-part default (1 s for images, 2 s otherwise). Default: None.

None
file_poll_backoff float

Multiplier applied to the poll interval after each check, bounds 1-10. 1.0 keeps the fixed cadence that shipped before B15. Falls back to DPT_GOOGLE_FILE_POLL_BACKOFF. Default: None.

None
_truncation_retry bool

Internal marker set when this call is the single automatic retry of a response that hit finish_reason=MAX_TOKENS. The retry re-issues the request with max_tokens raised 1.5x (capped at the model's request limit); True prevents a second such retry. Not intended for direct use. Default: False.

False
media_uploads_sink list

Receives one record per Files API upload this call makes (part_index, uri, name, mime_type, size, sha256, uploaded_at, expiration_time), for AgentResult.media_uploads. Default: None (nothing recorded).

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 model_information.json.

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:

  • base64 Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
  • Note: PDF/Document inlining has been DEPRECATED on Fireworks platform.
required
logger Logger

Logger instance for logging messages (required).

required
mcp_servers list

List of MCP server connection objects. Each dict must contain:

  • 'session': Active MCP ClientSession (required)
  • 'name': str (server name for identification) Tools are extracted via session.list_tools() and converted to Fireworks format.
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, validate_builtin_tools_concurrency will raise a ValueError because supports_concurrent_built_in_and_custom_tools is false for all Fireworks models in model_information.json.

For remote MCP support: Use call_fireworks_llm_structured_output_text with the mcp_servers parameter instead, as that function uses the Responses API which supports remote MCP servers.

Default: None

None
tool_choice str or dict

How model should select tools.

  • "auto" (default): Model decides whether to call tools
  • "required": Must use at least one tool
  • "none": Cannot use tools
  • {"type": "tool", "name": "tool_name"}: Force specific tool call

Default: "auto"

Tool Choice Exit Behavior:

  • "auto": Normal behavior - loop until model returns final text response or max_iterations reached
  • "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": "function", "function": {"name": "tool_name"}}: Exit when the specified tool is called, since the model is forced to use that tool

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 supported_reasoning_values in model_information.json.

  • "low": Faster, less thorough reasoning
  • "medium": Balanced reasoning
  • "high": More thorough reasoning Not supported on all models. Default: None
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:

  • Path A (native): For models with supports_function_calling_and_structured_outputs: true in model_information.json, uses response_format parameter for native structured outputs.
  • Path B (tool-based): For other models, creates a submit_final_response tool. The model calls this tool when ready to provide the final structured response.

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:

  • strategy (str): "summarize" | "sliding_window" | "tool_result_clearing" | "combined". Default: "summarize".
  • trigger_threshold (float|int): Float 0.0–1.0 as percentage of context window, or int for absolute token count. Default: 0.8 (80%).
  • summary_model (str|None): Model for summarization calls. Default: None (uses agent model).
  • summary_prompt (str|None): Inline custom summarization prompt. Use {conversation} placeholder. Takes precedence over summary_prompt_file.
  • summary_prompt_file (str|None): File path to custom summarization prompt. Default: None.
  • keep_recent_messages (int): Messages to preserve in sliding_window / combined. Default: 5.
  • keep_recent_tool_results (int): Tool results to preserve in tool_result_clearing. Default: 3.
  • clear_tool_inputs (bool): Also clear tool call parameters. Default: False.
  • archive_history (bool): Save original conversation to JSON before compacting. Default: True.
  • archive_dir (str): Directory for archive files. Default: "./compaction_archives".
  • include_archive_path_in_summary (bool): Include archive file path in summary output. Default: True.
  • min_messages_before_compaction (int): Minimum messages before triggering. Default: 4.
  • max_compactions_per_session (int|None): Limit compaction count. Default: None.
  • combined_order (list): Strategy order for combined. Default: ["tool_result_clearing", "sliding_window", "summarize"].

Examples:

# Summarize at 60% context usage
{"strategy": "summarize", "trigger_threshold": 0.6}

# Sliding window keeping last 6 messages
{"strategy": "sliding_window", "trigger_threshold": 0.8, "keep_recent_messages": 6}

# Combined strategy with archiving
{"strategy": "combined", "trigger_threshold": 5000, "archive_history": True}
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 AgentSession. Default: None.

None
stream_callback callable

Callback invoked for each streaming text chunk as it arrives. Signature: stream_callback(event_type, data) where event_type is "text_delta" and data is the text fragment. Passed through to _run_tool_calling_loop_fireworks for real-time event emission. Used by Agent.stream(). Default: None.

None
hooks_runner HookRunner

Bridge to the caller's hooks, supplied by the Agent layer. The loop awaits it at each hook point, honours pause/abort/skip_tool directives, drains queued inject_message directives, and reports per-request usage to it. Default: None (no hooks).

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0
max_tool_result_chars Optional[int]

Character cap on each tool result fed back to the model. None derives it from the registry (utils.resolve_max_tool_result_chars: one character per token of context window); 0 turns it off. A longer result is cut with a visible … [truncated: N of M characters shown; ...] marker and one WARNING (utils.cap_tool_result).

None
tool_result_preview_chars int

How many characters of each tool result's str() the tool_call_result stream and hook events carry. 500 (the default) is the preview they always carried; 0 carries the whole result plus result_data, the result as JSON data (utils.tool_result_event_fields). Every event also says result_truncated. What the model is sent is unaffected: that copy is max_tool_result_chars's.

DEFAULT_TOOL_RESULT_PREVIEW_CHARS
truncation_store Any

The run's utils.TruncatedResultStore when Agent(truncated_result_read_chars=) is set: a result the size cap cuts is kept there in full, its marker names read_truncated_result, and that tool's own slices are not cut again. None (the default) keeps the original marker.

None

Returns:

Name Type Description
dict dict

Result dictionary containing:

  • data (dict or str): Final response - the parsed JSON dict when response_schema was supplied (a plain dict: the schema validates the output, it is never returned as a model instance), otherwise the response text with reasoning tags removed
  • response: Last API response object
  • messages (list): Complete conversation history with all tool calls/results
  • completed_iterations (int): Number of completed loop iterations
  • custom_tools (list): All custom MCP tool names used
  • mcp_tools (list): [PLACEHOLDER] Only included when built_in_tools is defined. Reserved for future functionality to distinguish MCP tools from built-in tools.
  • built_in_tools_invoked (list): Built-in tools observed to have run. Always [] here: this path drives the Chat Completions API, which exposes no Fireworks built-in tool. The one built-in Fireworks has (remote_mcp) lives on the Response API path — see call_fireworks_llm_structured_output_text with mcp_remote_servers.
  • input_tokens (int): Total prompt tokens across all iterations
  • output_tokens (int): Total completion tokens across all iterations
  • cached_input_tokens (int): Cached prompt tokens summed across iterations, a SUBSET of input_tokens already re-priced at the cached rate
  • request_cost_records (list): One record per billed API request, each with input_tokens, output_tokens, reasoning_tokens, cached_input_tokens, served_model, requested_tier, served_tier and cost. cost below is the sum of these token costs plus the per-run tool costs.
  • reasoning_content (str): Combined reasoning content from:

  • reasoning_content field on message objects

  • <think>...</think> tags in response content
  • cost (float): Calculated cost in USD
  • cost_estimated (bool): Whether cost includes estimates
  • tool_costs_estimated (dict): Per-tool cost estimation flags
  • token_source (str): Source of token counts ("api_response" or "unknown")
  • iteration_metrics (list): Metrics for each tool calling iteration. Each entry contains:

    • iteration_number (int): The iteration number
    • input_tokens (int): Input tokens for this iteration
    • output_tokens (int): Output tokens for this iteration
    • reasoning_tokens (int): Thinking tokens for this iteration
    • cached_input_tokens (int): Cached prompt tokens for this iteration
    • cost (float): Estimated cost for this iteration
    • duration_ms (int): Duration of this iteration in milliseconds
    • tool_calls (list): List of tool calls made in this iteration
    • stop_reason (str): Finish reason for this iteration
    • compaction_triggered (bool), compaction_strategy (str or None), compaction_tokens_cleared (int): Compaction bookkeeping for this iteration (omitted on the record emitted for an early exit)
    • retry_count (int), retry_cost (float), retry_input_tokens (int), retry_output_tokens (int), retry_details (list): Retry bookkeeping for this iteration
    • compaction_count (int): Number of compaction events during the run.
    • compaction_archives (list): File paths to archived conversations.
    • compaction_input_tokens (int): Input tokens consumed by summarization.
    • compaction_output_tokens (int): Output tokens from summarization.
    • compaction_cost (float): Cost of summarization calls.
    • error (str or None): Error message if failed
  • Note: The error return (built when an unexpected exception ends the run) omits cached_input_tokens and request_cost_records; every other key above is present.

Raises:

Type Description
ValueError

If:

  • Fireworks SDK not available
  • Client is invalid or None
  • Model doesn't support function calling (check supports_function_calling)
  • Both mcp_servers AND built_in_tools provided (not supported - Fireworks has supports_concurrent_built_in_and_custom_tools: false)
  • Model name not recognized in model_information.json
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_content across turns
  • reasoning_effort validated via validate_reasoning_effort_fireworks()
  • Reasoning content is combined from both reasoning_content field 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 call_fireworks_llm_function_calling. Supported kwargs include:

  • built_in_tools (dict): [PLACEHOLDER] Reserved for future built-in tools support
  • tool_choice (str or dict): Tool selection mode ("auto", "required", "none")
  • max_tokens (int): Maximum output tokens
  • temperature (float): Sampling temperature (default: 0.3)
  • reasoning_effort (str): Reasoning effort level ("low", "medium", "high")
  • max_tool_iterations (int): Maximum tool calling iterations (default: 10)
  • response_schema (BaseModel): Pydantic model for structured output

See call_fireworks_llm_function_calling for full parameter documentation.

{}

Returns:

Name Type Description
dict dict

Same return structure as call_fireworks_llm_function_calling. See async function docstring for complete details.

Raises:

Type Description
Exception

Same exceptions as call_fireworks_llm_function_calling.

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 model_information.json config file.

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:

  • base64 Image: {'type': 'base64', 'media_type': str, 'data': str} (any image/* MIME type)
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.

  • "internal_reasoning"
  • "thoughts"
  • "reasoning"
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. Note: If the remote MCP servers are provided, max_tokens will always default to the model's maximum output tokens, regardless of the value of this parameter.

None
temperature float

Sampling temperature for generation.

1.0
mcp_remote_servers list

MCP server configurations for remote tool access.

  • Format:
    [{"url": "server_url", "type": "sse", "server_label": "label"}] or [{"url": "server_url", "type": "mcp", "server_label": "label"}]
    

If provided, function will use Response API instead of Chat Completions API. allowed_tools is refused with a ValueError: Fireworks ignores it (0.5.1; use a client-side mcp_remote_client through Agent).

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 tags), separate from the final answer in content.

Not supported on all models - validated against model's supported_reasoning_values in model_information.json.

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 AgentSession. Default: None.

None
stream_callback callable

Callback invoked during streaming with (event_type: str, content: str) arguments. Currently emits "text_delta" events as text chunks arrive. Default: None.

None
_retry_accumulator RetryAccumulator

Internal parameter managed by the @retry_on_api_error decorator. Captures partial cost data from failed retry attempts for accurate billing. The decorator's before_sleep callback extracts this from kwargs on each retry. Not intended for direct use. Default: None.

None
_estimated_input_tokens int

Internal parameter used by the retry decorator to approximate costs for billable errors lacking usage data. Default: 0.

0

Returns:

Name Type Description
dict dict

Response format varies by mode:

  • Plain text mode (when response_schema is None and mcp_remote_servers not provided): {'data': str | None, 'input_tokens': int, 'output_tokens': int, 'cached_input_tokens': int, 'cost': float, 'token_source': str, 'built_in_tools_invoked': list, '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: {'data': dict | None, 'input_tokens': int, 'output_tokens': int, 'cached_input_tokens': int, 'cost': float, 'token_source': str, 'built_in_tools_invoked': list, '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.

  • MCP mode: {'data': str | None, 'response': response_object, 'input_tokens': int, 'output_tokens': int, 'cached_input_tokens': int, 'cost': float, 'cost_estimated': bool, 'tool_costs_estimated': dict, 'token_source': str, 'built_in_tools_invoked': list, 'error': str | None}

  • Note: 'data' contains the model's raw text response.

  • Note: 'response' contains the full Fireworks response object from last API call.
  • Note: Returns None for 'data' if the response is empty or malformed.

Every mode also returns cached_input_tokens (int) — the cached prompt-token count Fireworks reported, a SUBSET of input_tokens that cost already re-prices at the model's cached_input registry rate (never added on top). It is read from usage.prompt_tokens_details.cached_tokens with a flat usage.cached_prompt_tokens fallback (MCP mode also accepts the Responses-style usage.input_tokens_details), and is 0 when the deployment reports no cached tokens or usage metadata is missing entirely.

Every mode also returns built_in_tools_invoked (list) — the built-in tools observed to have run. It is ["remote_mcp"] only in MCP mode and only when the Response API output carries an MCP tool-invocation item; a configured-but-unused server, and every non-MCP mode, yields []. The config-time echo in tool_usage['tools_used'] is unchanged.

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 response_schema is not a valid Pydantic model or if the model_name is not recognized.

Notes

Two operational modes:

  1. Structured Output Mode: Uses Chat Completions API with JSON schema
  2. MCP Mode: Uses native Fireworks Response API with MCP server integration

Additional fields for MCP mode:

  • 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})