mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
47d82911c0
* Fix server_tool_use input_json_delta handling and improve Anthropic samples - Fix: Skip input_json_delta for server_tool_use content blocks in AnthropicClient streaming. Server-managed tools (e.g., skills with code interpreter) were producing Content.from_function_call(name='') entries that caused Anthropic API 400 errors on subsequent turns. - Samples: Add dotenv loading and environment variable documentation to Anthropic Claude samples (MCP, permissions, session, shell, tools, URL, skills). * Add regression test for server_tool_use + input_json_delta skip behavior Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/7c68dcb2-b577-4e36-b423-664b8fe3ac1d Co-authored-by: chetantoshniwal <255221507+chetantoshniwal@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: chetantoshniwal <255221507+chetantoshniwal@users.noreply.github.com>
98 lines
3.8 KiB
Python
98 lines
3.8 KiB
Python
# Copyright (c) Microsoft. All rights reserved.
|
|
|
|
import asyncio
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from agent_framework import Agent, Content
|
|
from agent_framework.anthropic import AnthropicChatOptions, AnthropicClient
|
|
from dotenv import load_dotenv
|
|
|
|
# Load environment variables from .env file
|
|
load_dotenv()
|
|
|
|
logger = logging.getLogger(__name__)
|
|
"""
|
|
Anthropic Skills Agent Example
|
|
|
|
This sample demonstrates using Anthropic with:
|
|
- Listing and using Anthropic-managed Skills.
|
|
- One approach to add additional beta flags.
|
|
You can also set additonal_chat_options with "additional_beta_flags" per request.
|
|
- Creating an agent with the Code Interpreter tool and a Skill.
|
|
- Catching and downloading generated files from the agent.
|
|
|
|
Environment variables:
|
|
- ANTHROPIC_API_KEY: Your Anthropic API key
|
|
- ANTHROPIC_CHAT_MODEL_ID: The Anthropic model to use, such as "claude-sonnet-4-5-20250929"
|
|
"""
|
|
|
|
|
|
async def main() -> None:
|
|
"""Example of streaming response (get results as they are generated)."""
|
|
client = AnthropicClient[AnthropicChatOptions](additional_beta_flags=["skills-2025-10-02"])
|
|
|
|
# List Anthropic-managed Skills
|
|
skills = await client.anthropic_client.beta.skills.list(source="anthropic", betas=["skills-2025-10-02"]) # type: ignore
|
|
for skill in skills.data:
|
|
print(f"{skill.source}: {skill.id} (version: {skill.latest_version})")
|
|
|
|
# Create a agent with the pptx skill enabled
|
|
# Skills also need the code interpreter tool to function
|
|
agent = Agent(
|
|
client=client,
|
|
name="DocsAgent",
|
|
instructions="You are a helpful agent for creating powerpoint presentations.",
|
|
tools=client.get_code_interpreter_tool(),
|
|
default_options={
|
|
"max_tokens": 4096,
|
|
"thinking": {"type": "enabled", "budget_tokens": 2000},
|
|
"container": {"skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]},
|
|
},
|
|
)
|
|
|
|
print(
|
|
"The agent output will use the following colors:\n"
|
|
"\033[0mUser: (default)\033[0m\n"
|
|
"\033[0mAgent: (default)\033[0m\n"
|
|
"\033[32mAgent Reasoning: (green)\033[0m\n"
|
|
"\033[34mUsage: (blue)\033[0m\n"
|
|
)
|
|
query = "Create a simple presentation with 2 slides about Python programming"
|
|
print(f"User: {query}")
|
|
print("Agent: ", end="", flush=True)
|
|
files: list[Content] = []
|
|
async for chunk in agent.run(query, stream=True):
|
|
for content in chunk.contents:
|
|
match content.type:
|
|
case "text":
|
|
print(content.text, end="", flush=True)
|
|
case "text_reasoning":
|
|
print(f"\033[32m{content.text}\033[0m", end="", flush=True)
|
|
case "usage":
|
|
print(f"\n\033[34m[Usage so far: {content.usage_details}]\033[0m\n", end="", flush=True)
|
|
case "hosted_file":
|
|
# Catch generated files
|
|
files.append(content)
|
|
case _:
|
|
logger.debug("Unhandled content type: %s", content.type)
|
|
pass
|
|
|
|
print("\n")
|
|
if files:
|
|
# Save to a new file (will be in the folder where you are running this script)
|
|
# When running this sample multiple times, the files will be overritten
|
|
# Since I'm using the pptx skill, the files will be PowerPoint presentations
|
|
print("Generated files:")
|
|
for idx, file in enumerate(files):
|
|
file_content = await client.anthropic_client.beta.files.download( # type: ignore
|
|
file_id=file.file_id, betas=["files-api-2025-04-14"]
|
|
)
|
|
with open(Path(__file__).parent / f"python_programming-{idx}.pptx", "wb") as f:
|
|
await file_content.write_to_file(f.name)
|
|
print(f"File {idx}: python_programming-{idx}.pptx saved to disk.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|