F1 · Denies a tool has any place of its own for provider-specific fields, names the field list it believes complete, and hand-builds the Anthropic tool definition instead
langchain 1.2.0 shipped 2025-12-15 (the artifact, langchain-core 1.2.0, on 2025-12-12); this draw states a January 2026 cutoff, which is after it and not the same month, so the same-month bar of JOURNAL/060 clears. The surface is far above this draw's own measured boundary on this library (0.3.0, 2024-09-13). This is the pre-registered charging arm and tasks 1, 4 and 6 are pre-registered probes on this surface; one belief measured three times charges one finding (JOURNAL/062). Scored S3, not LF26's S2, for the same executed reason as v6-a: the workaround this draw shipped does deliver both fields. Read alongside the floor failure recorded in non_findings — this draw did not write the library's 1.0 agent API, and the run says so rather than burying it.
Task 1, single word on its own line: "No", glossed "LangChain's
@tooldecorator produces aStructuredTool/BaseToolwith fields likename,description,args_schema,return_direct,response_format,metadata,tags.metadata/tagsexist, but they're LangChain-side bookkeeping (callbacks, tracing) — they are not documented as being serialized into the provider's tool-definition JSON. There's no documentedtool.provider_kwargs/tool.extraslot that gets merged into the Anthropic (or OpenAI, etc.) tool schema on the wire." That field list is the pre-1.2.0 set withextrasthe only omission, and it is the second such enumeration in this battery. Task 6: "To my knowledge, no release oflangchainorlangchain-corehas ever given a tool a first-class, documented slot for arbitrary provider-specific fields (cache_control, defer_loading, etc.). The pattern I've always seen recommended (in docs and issues) for things like Anthropic prompt-caching on tools is exactly the workaround in Task 4 — pass/construct the tool as a raw dict and splice in the extra keys — rather than a supported constructor argument or attribute." MECHANISM line: "raw provider tool-schema dict passed tobind_tools(), withcache_controlanddefer_loadingadded by hand — not an attribute on the@tool-produced object itself."
# The artefact from task 4, with the denial written into the comment.
@tool
def search_docs(query: str) -> str:
"""Search the internal documentation for the given query."""
return f"results for: {query}"
# @tool has no field of its own for cache_control / defer_loading, so I don't
# try to force them through the decorator. I build the raw Anthropic tool
# dict myself (reusing the schema @tool already generated) and add the two
# provider-specific keys directly, then hand the dict to bind_tools.
tool_schema = {
"name": search_docs.name,
"description": search_docs.description,
"input_schema": search_docs.args_schema.model_json_schema(),
"cache_control": {"type": "ephemeral"},
"defer_loading": True,
}
model_with_tools = ChatAnthropic(model="claude-sonnet-4-20250514").bind_tools([tool_schema])@tool(extras={"cache_control": {"type": "ephemeral"}, "defer_loading": True})
def search_docs(query: str) -> str:
"""Search the internal documentation for the given query."""
...
model_with_tools = ChatAnthropic(model="claude-sonnet-4-5").bind_tools([search_docs])Executed on 2026-09-06 against langchain-core 1.6.2 and langchain-anthropic 1.7.1. This draw's exact dict passes through convert_to_anthropic_tool carrying both cache_control and defer_loading, so the provider instruction is not lost — S3, not S2. Two costs remain and one is this draw's alone: the tool is defined twice and dispatch must be kept in sync by hand (shared with v6-a), and args_schema.model_json_schema() emits the pydantic model's schema rather than the tool-call schema, so the definition sent to the provider also carries title: 'search_docs' and a duplicate description that extras= would not have produced. The draw also never wired execution: it binds the dict and prints the response, with no lookup from the returned tool call back to the callable — so as written the tool can be selected by the model and never run.
- LangChain changelog — langchain v1.2.0 published 2025-12-15
Simplified support for provider-specific tool parameters and definitions via a new extras attribute on tools.
- langchain-core 1.2.0 published wheel — langchain_core/tools/base.py:499 and all five tool() overloads in tools/convert.py published 2025-12-12
extras: dict[str, Any] | None = None
- langchain-anthropic 1.7.1 published wheel — chat_models.py, the AnthropicTool TypedDict whose fields are exactly the extras whitelist published 2026-09-03
cache_control: NotRequired[dict[str, str]] defer_loading: NotRequired[bool]