Skip to content

Python Anthropic: per-run additional_beta_flags leaks into request kwargs #5764

@rg-ve

Description

@rg-ve

Description

agent-framework-anthropic leaks per-run additional_beta_flags into the raw Anthropic request kwargs.

Passing additional_beta_flags per run is consumed by _prepare_betas(...), but the key remains in the final request kwargs and causes:

TypeError: AsyncMessages.create() got an unexpected keyword argument 'additional_beta_flags'

Workaround: set beta flags on the AnthropicClient constructor instead of per-run options.

Environment

  • Repo: microsoft/agent-framework
  • Local commit tested: 4ad96b64e755f5d25d5b859e1c7b43b64088a56f
  • Python packages installed editable from local repo:
    • python/packages/core
    • python/packages/anthropic
  • agent-framework-core: 1.3.0
  • agent-framework-anthropic: 1.0.0b260507
  • anthropic: 0.80.0
  • Python: 3.14
  • Model tested: claude-opus-4-7

Minimal repro

import asyncio
import os
from typing import Annotated

from agent_framework import Agent, tool
from agent_framework.anthropic import AnthropicClient

@tool(approval_mode="never_require")
def lookup_ticket(ticket_id: Annotated[str, "Ticket id"]) -> str:
    """Look up a test ticket."""
    return '{"ticket_id":"40076","status":"open","priority":"high"}'

async def main():
    client = AnthropicClient(
        api_key=os.environ["ANTHROPIC_API_KEY"],
        model="claude-opus-4-7",
    )

    agent = Agent(
        client=client,
        name="AnthropicOptionsRepro",
        instructions="Use lookup_ticket exactly once for ticket 40076, then summarize it.",
        tools=[lookup_ticket],
        default_options={
            "model": "claude-opus-4-7",
            "max_tokens": 4096,
            "thinking": {"type": "adaptive", "display": "omitted"},
            "output_config": {"effort": "low"},
            "additional_beta_flags": ["extended-cache-ttl-2025-04-11"],
            "tools": [lookup_ticket],
        },
    )

    async for chunk in agent.run("Validate ticket 40076 now.", stream=True):
        if chunk.text:
            print(chunk.text, end="", flush=True)

asyncio.run(main())

Expected: additional_beta_flags should be consumed into betas only.

Actual: it is also forwarded as a raw kwarg to AsyncMessages.create(...), which rejects it.

Root cause

From agent_framework_anthropic/_chat_client.py:

  • _prepare_options(...) copies all options except instructions and response_format into run_options.
  • _prepare_betas(...) consumes additional_beta_flags into betas.
  • additional_beta_flags is not removed from run_options before calling AsyncMessages.create(...).

Compatibility note: Opus 4.7 thinking shape

With additional_beta_flags moved to the AnthropicClient constructor as a workaround, a live streaming local-tool loop succeeds with:

thinking={"type": "adaptive", "display": "omitted"}
output_config={"effort": "low"}

This is the expected Opus 4.7 API shape. thinking={"type":"enabled","budget_tokens":...} is expected to return a 400 on Opus 4.7 and is not being reported as a bug here.

There is a separate type/doc freshness gap: agent_framework_anthropic._chat_client.ThinkingConfig currently documents only enabled / disabled plus budget_tokens, while Opus 4.7 uses adaptive thinking. The runtime pass-through works, so this is documentation/typing freshness rather than the runtime failure above.

Expected fix

Pop/filter additional_beta_flags from run_options after consuming it into betas, before dispatching to Anthropic.

Metadata

Metadata

Assignees

Labels

Type

No fields configured for Bug.

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions