Files
Giles Odigwe 8be7c93063 Python: Preserve structured instructions when merging chat options (#7730)
* Python: Preserve structured instructions when merging chat options

`instructions` is declared as `str` on `ChatOptions`, but chat clients may widen it
to a provider-native structured form. Three merge paths combined it with an f-string,
which coerced any non-string value to its `repr`, turning structured metadata into
literal text before any client could see it:

- `merge_chat_options` (`_types.py`)
- `_merge_options` (`_agents.py`, agent defaults + per-run options)
- provider-contributed instructions in `_prepare_session_and_messages` (`_agents.py`)

The last of these is the reported case: once any context provider (for example
`SkillsProvider`) contributes instructions, structured instructions were replaced by
their `repr`, so the model received Python dict syntax as its system prompt and
Anthropic prompt caching silently stopped working.

Add a shared `_append_instructions` helper that concatenates strings as before and
otherwise extends element-wise, always appending so the leading portion stays
unchanged for providers that treat it as a stable, structure-sensitive prefix. A lone
mapping is treated as a single element rather than iterated into its keys.

On the Anthropic side, `_extract_structured_instructions` now normalizes bare strings
into text blocks, since appended instructions arrive alongside caller-supplied blocks.

Fixes #7700

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90

* Python: address review feedback on structured instructions fix

Parameterize the Anthropic regression test over both the with- and
without-SkillsProvider configurations so the structure-preserving behavior
is asserted in the baseline case too.

Normalize structured instructions in `_get_instructions_from_options` so
telemetry records the instruction text for provider-native block shapes,
extracting only `text` values to keep provider metadata out of spans.

Use `cast` for the structured `default_options` in both regression tests so
the test type checkers resolve the client options type correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90
2026-08-19 10:25:54 +00:00

1.7 KiB

Get Started with Microsoft Agent Framework Anthropic

Please install this package via pip:

pip install agent-framework-anthropic --pre

Anthropic Integration

The Anthropic integration enables communication with the Anthropic API, allowing your Agent Framework applications to leverage Anthropic's capabilities.

The package also includes Anthropic-hosted transport wrappers for:

  • Microsoft Foundry via AnthropicFoundryClient
  • Amazon Bedrock via AnthropicBedrockClient
  • Google Vertex AI via AnthropicVertexClient

Basic Usage Example

See the Anthropic agent examples which demonstrate:

  • Connecting to a Anthropic endpoint with an agent
  • Streaming and non-streaming responses

Structured system blocks for prompt caching

Use instructions with Anthropic-native system blocks when you need structured system prompt content, such as prompt-cache cache_control metadata. Do not combine structured instructions blocks with a leading system message.

from anthropic.types.beta import BetaTextBlockParam

from agent_framework_anthropic import AnthropicClient

client = AnthropicClient()
system_blocks: list[BetaTextBlockParam] = [
    {"type": "text", "text": "Stable instructions", "cache_control": {"type": "ephemeral", "ttl": "1h"}},
]

response = await client.get_response("Hello", options={"instructions": system_blocks})

Instructions contributed later in a run — by a context provider such as SkillsProvider, or by per-run options — are appended as an additional text block after the configured blocks. The blocks you supply keep their structure and their position, so a cache_control breakpoint stays valid.