diff --git a/README.md b/README.md index 665f4610df..b2d8aca8d2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ Highlights - Multimodal: Text, vision, and function calling - Cross-Platform: .NET and Python implementations -## Quick Install +Below are the basics for each language implementation. For more details on python see [here](./python/README.md) and for .NET see [here](./dotnet/README.md). + +## Python - Quick Install ```bash pip install agent-framework @@ -25,13 +27,14 @@ Supported Platforms: - Python: 3.10+ - OS: Windows, macOS, Linux -## 1. Setup API Keys +## Python - 1. Setup API Keys Set as environment variables, or create a .env file at your project root: ```bash OPENAI_API_KEY=sk-... OPENAI_CHAT_MODEL_ID=... +OPENAI_RESPONSES_MODEL_ID=... ... AZURE_OPENAI_API_KEY=... AZURE_OPENAI_ENDPOINT=... @@ -56,66 +59,38 @@ chat_client = AzureChatClient( See the following [setup guide](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started) for more information. -## 2. Create a Simple Agent +## Python - 2. Create a Simple Agent Create agents and invoke them directly: ```python import asyncio from agent_framework import ChatClientAgent -from agent_framework.openai import OpenAIChatClient +from agent_framework.foundry import FoundryChatClient async def main(): - agent = ChatClientAgent( - chat_client=OpenAIChatClient(), - instructions=""" + async with ChatClientAgent( + chat_client=FoundryChatClient(), + instructions="""These are the Three Laws of Robotics: 1) A robot may not injure a human being... 2) A robot must obey orders given it by human beings... 3) A robot must protect its own existence... - Give me the TLDR in exactly 5 words. + Respond concisely to the user's request. + """ + ): + result = await agent.run("Summarize the Three Laws of Robotics") + print(result.text) + """ + Output: + Protect humans, obey, self-preserve, prioritized. """ - ) - result = await agent.run("Summarize the Three Laws of Robotics") - print(result) - -asyncio.run(main()) -# Output: Protect humans, obey, self-preserve, prioritized. +if __name__ == "__main__": + asyncio.run(main()) ``` -## 3. Directly Use Chat Clients (No Agent Required) - -You can use the chat client classes directly for advanced workflows: - -```python -import asyncio -from agent_framework.openai import OpenAIChatClient -from agent_framework import ChatMessage, ChatRole - -async def main(): - client = OpenAIChatClient() - - messages = [ - ChatMessage(role=ChatRole.SYSTEM, text="You are a helpful assistant."), - ChatMessage(role=ChatRole.USER, text="Write a haiku about Agent Framework.") - ] - - response = await client.get_response(messages) - print(response.messages[0].text) - - """ - Output: - - Agents work in sync, - Framework threads through each task— - Code sparks collaboration. - """ - -asyncio.run(main()) -``` - -## 4. Build an Agent with Tools and Functions +## Python - 3. Build an Agent with Tools Enhance your agent with custom tools and function calling: @@ -125,7 +100,7 @@ from typing import Annotated from random import randint from pydantic import Field from agent_framework import ChatClientAgent -from agent_framework.openai import OpenAIChatClient +from agent_framework.openai import OpenAIResponsesClient def get_weather( @@ -147,13 +122,13 @@ def get_menu_specials() -> str: async def main(): agent = ChatClientAgent( - chat_client=OpenAIChatClient(), + chat_client=OpenAIResponsesClient(), instructions="You are a helpful assistant that can provide weather and restaurant information.", tools=[get_weather, get_menu_specials] ) response = await agent.run("What's the weather in Amsterdam and what are today's specials?") - print(response) + print(response.text) """ Output: @@ -167,56 +142,6 @@ if __name__ == "__main__": You can explore additional agent samples [here](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started/agents). -## 5. Multi-Agent Orchestration - -Coordinate multiple agents to collaborate on complex tasks using orchestration patterns: - -```python -import asyncio -from agent_framework import ChatClientAgent -from agent_framework.openai import OpenAIChatClient - - -async def main(): - # Create specialized agents - writer = ChatClientAgent( - chat_client=OpenAIChatClient(), - name="Writer", - instructions="You are a creative content writer. Generate and refine slogans based on feedback." - ) - - reviewer = ChatClientAgent( - chat_client=OpenAIChatClient(), - name="Reviewer", - instructions="You are a critical reviewer. Provide detailed feedback on proposed slogans." - ) - - # Sequential workflow: Writer creates, Reviewer provides feedback - task = "Create a slogan for a new electric SUV that is affordable and fun to drive." - - # Step 1: Writer creates initial slogan - initial_result = await writer.run(task) - print(f"Writer: {initial_result}") - - # Step 2: Reviewer provides feedback - feedback_request = f"Please review this slogan: {initial_result}" - feedback = await reviewer.run(feedback_request) - print(f"Reviewer: {feedback}") - - # Step 3: Writer refines based on feedback - refinement_request = f"Please refine this slogan based on the feedback: {initial_result}\nFeedback: {feedback}" - final_result = await writer.run(refinement_request) - print(f"Final Slogan: {final_result}") - - # Example Output: - # Writer: "Charge Forward: Affordable Adventure Awaits!" - # Reviewer: "Good energy, but 'Charge Forward' is overused in EV marketing..." - # Final Slogan: "Power Up Your Adventure: Premium Feel, Smart Price!" - -if __name__ == "__main__": - asyncio.run(main()) -``` - **Note**: Advanced orchestration patterns like GroupChat, Sequential, and Concurrent orchestrations are coming soon. ## More Examples & Samples diff --git a/python/DEV_SETUP.md b/python/DEV_SETUP.md index 418d45d126..d815d76637 100644 --- a/python/DEV_SETUP.md +++ b/python/DEV_SETUP.md @@ -6,6 +6,8 @@ want to run the tests included. ## System setup +We are using a tool called [poethepoet](https://github.com/nat-n/poethepoet) for task management and [uv](https://github.com/astral-sh/uv) for dependency management. At the [end of this document](#available-poe-tasks), you will find the available Poe tasks. + ## If you're on WSL Check that you've cloned the repository to `~/workspace` or a similar folder. @@ -461,3 +463,163 @@ or: This is assuming the upstream branch refers to the main repository. If you have a different name for the upstream branch, you can replace `upstream` with the name of your upstream branch. After running the rebase command, you may need to resolve any conflicts that arise. If you are unsure how to resolve a conflict, please refer to the [GitHub's documentation on resolving conflicts](https://docs.github.com/en/get-started/using-git/resolving-merge-conflicts-after-a-git-rebase), or for [VSCode](https://code.visualstudio.com/docs/sourcecontrol/overview#_merge-conflicts). + +# Task automation + +## Available Poe Tasks +This project uses [poethepoet](https://github.com/nat-n/poethepoet) for task management and [uv](https://github.com/astral-sh/uv) for dependency management. + +### Setup and Installation + +Once uv is installed, and you do not yet have a virtual environment setup: + +```bash +uv venv +``` + +and then you can run the following tasks: +```bash +uv sync --all-extras --dev +``` + +After this initial setup, you can use the following tasks to manage your development environment, it is adviced to use the following setup command since that also installs the pre-commit hooks. + +#### `setup` +Set up the development environment with a virtual environment, install dependencies and pre-commit hooks: +```bash +uv run poe setup +# or with specific Python version +uv run poe setup --python 3.12 +``` + +#### `install` +Install all dependencies including extras and dev dependencies, including updates: +```bash +uv run poe install +``` + +#### `venv` +Create a virtual environment with specified Python version or switch python version: +```bash +uv run poe venv +# or with specific Python version +uv run poe venv --python 3.12 +``` + +#### `pre-commit-install` +Install pre-commit hooks: +```bash +uv run poe pre-commit-install +``` + +### Code Quality and Formatting + +Each of the following tasks are designed to run against both the main `agent-framework` package and the extension packages, ensuring consistent code quality across the project. + +#### `fmt` (format) +Format code using ruff: +```bash +uv run poe fmt +``` + +#### `lint` +Run linting checks and fix issues: +```bash +uv run poe lint +``` + +#### `pyright` +Run Pyright type checking: +```bash +uv run poe pyright +``` + +#### `mypy` +Run MyPy type checking: +```bash +uv run poe mypy +``` + +### Testing + +#### `test` +Run unit tests with coverage: +```bash +uv run poe test +``` + +### Documentation + +#### `docs-clean` +Remove the docs build directory: +```bash +uv run poe docs-clean +``` + +#### `docs-build` +Build the documentation: +```bash +uv run poe docs-build +``` + +#### `docs-serve` +Serve documentation locally with auto-reload: +```bash +uv run poe docs-serve +``` + +#### `docs-check` +Build documentation and fail on warnings: +```bash +uv run poe docs-check +``` + +#### `docs-check-examples` +Check documentation examples for code correctness: +```bash +uv run poe docs-check-examples +``` + +### Code Validation + +#### `markdown-code-lint` +Lint markdown code blocks: +```bash +uv run poe markdown-code-lint +``` + +#### `samples-code-check` +Run type checking on samples: +```bash +uv run poe samples-code-check +``` + +### Comprehensive Checks + +#### `check` +Run all quality checks (format, lint, pyright, mypy, test, markdown lint, samples check): +```bash +uv run poe check +``` + +#### `pre-commit-check` +Run pre-commit specific checks (all of the above, excluding `mypy`): +```bash +uv run poe pre-commit-check +``` + +### Building + +#### `build` +Build the package: +```bash +uv run poe build +``` + +## Pre-commit Hooks + +You can also run all checks using pre-commit directly: + +```bash +uv run pre-commit run -a +``` diff --git a/python/README.md b/python/README.md index 93329a0634..26b4bbd5cc 100644 --- a/python/README.md +++ b/python/README.md @@ -1,160 +1,235 @@ -# Python +# Get Started with Microsoft Agent Framework -This project uses [poethepoet](https://github.com/nat-n/poethepoet) for task management and [uv](https://github.com/astral-sh/uv) for dependency management. +Highlights +- Flexible Agent Framework: build, orchestrate, and deploy AI agents and multi-agent systems +- Multi-Agent Orchestration: Group chat, sequential, concurrent, and handoff patterns +- Plugin Ecosystem: Extend with native functions, OpenAPI, Model Context Protocol (MCP), and more +- LLM Support: OpenAI, Azure OpenAI, Azure AI Foundry, and more +- Runtime Support: In-process and distributed agent execution +- Multimodal: Text, vision, and function calling +- Cross-Platform: .NET and Python implementations -## Available Poe Tasks - -### Setup and Installation - -Once uv is installed, and you do not yet have a virtual environment setup: +## Quick Install ```bash -uv venv +pip install agent-framework +# Optional: Add Azure integration +pip install agent-framework[azure] +# Optional: Add Foundry integration +pip install agent-framework[foundry] +# Optional: Both +pip install agent-framework[azure,foundry] ``` -and then you can run the following tasks: -```bash -uv sync --all-extras --dev -``` +Supported Platforms: +- Python: 3.10+ +- OS: Windows, macOS, Linux -After this initial setup, you can use the following tasks to manage your development environment, it is adviced to use the following setup command since that also installs the pre-commit hooks. +## 1. Setup API Keys -#### `setup` -Set up the development environment with a virtual environment, install dependencies and pre-commit hooks: -```bash -uv run poe setup -# or with specific Python version -uv run poe setup --python 3.12 -``` - -#### `install` -Install all dependencies including extras and dev dependencies, including updates: -```bash -uv run poe install -``` - -#### `venv` -Create a virtual environment with specified Python version or switch python version: -```bash -uv run poe venv -# or with specific Python version -uv run poe venv --python 3.12 -``` - -#### `pre-commit-install` -Install pre-commit hooks: -```bash -uv run poe pre-commit-install -``` - -### Code Quality and Formatting - -Each of the following tasks are designed to run against both the main `agent-framework` package and the extension packages, ensuring consistent code quality across the project. - -#### `fmt` (format) -Format code using ruff: -```bash -uv run poe fmt -``` - -#### `lint` -Run linting checks and fix issues: -```bash -uv run poe lint -``` - -#### `pyright` -Run Pyright type checking: -```bash -uv run poe pyright -``` - -#### `mypy` -Run MyPy type checking: -```bash -uv run poe mypy -``` - -### Testing - -#### `test` -Run unit tests with coverage: -```bash -uv run poe test -``` - -### Documentation - -#### `docs-clean` -Remove the docs build directory: -```bash -uv run poe docs-clean -``` - -#### `docs-build` -Build the documentation: -```bash -uv run poe docs-build -``` - -#### `docs-serve` -Serve documentation locally with auto-reload: -```bash -uv run poe docs-serve -``` - -#### `docs-check` -Build documentation and fail on warnings: -```bash -uv run poe docs-check -``` - -#### `docs-check-examples` -Check documentation examples for code correctness: -```bash -uv run poe docs-check-examples -``` - -### Code Validation - -#### `markdown-code-lint` -Lint markdown code blocks: -```bash -uv run poe markdown-code-lint -``` - -#### `samples-code-check` -Run type checking on samples: -```bash -uv run poe samples-code-check -``` - -### Comprehensive Checks - -#### `check` -Run all quality checks (format, lint, pyright, mypy, test, markdown lint, samples check): -```bash -uv run poe check -``` - -#### `pre-commit-check` -Run pre-commit specific checks (all of the above, excluding `mypy`): -```bash -uv run poe pre-commit-check -``` - -### Building - -#### `build` -Build the package: -```bash -uv run poe build -``` - -## Pre-commit Hooks - -You can also run all checks using pre-commit directly: +Set as environment variables, or create a .env file at your project root: ```bash -uv run pre-commit run -a +OPENAI_API_KEY=sk-... +OPENAI_CHAT_MODEL_ID=... +... +AZURE_OPENAI_API_KEY=... +AZURE_OPENAI_ENDPOINT=... +AZURE_OPENAI_CHAT_DEPLOYMENT_NAME=... +... +FOUNDRY_PROJECT_ENDPOINT=... +FOUNDRY_MODEL_DEPLOYMENT_NAME=... ``` + +You can also override environment variables by explicitly passing configuration parameters to the chat client constructor: + +```python +from agent_framework.azure import AzureChatClient + +chat_client = AzureChatClient( + api_key='', + endpoint='', + deployment_name='', + api_version='', +) +``` + +See the following [setup guide](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started) for more information. + +## 2. Create a Simple Agent + +Create agents and invoke them directly: + +```python +import asyncio +from agent_framework import ChatClientAgent +from agent_framework.openai import OpenAIChatClient + +async def main(): + agent = ChatClientAgent( + chat_client=OpenAIChatClient(), + instructions=""" + 1) A robot may not injure a human being... + 2) A robot must obey orders given it by human beings... + 3) A robot must protect its own existence... + + Give me the TLDR in exactly 5 words. + """ + ) + + result = await agent.run("Summarize the Three Laws of Robotics") + print(result) + +asyncio.run(main()) +# Output: Protect humans, obey, self-preserve, prioritized. +``` + +## 3. Directly Use Chat Clients (No Agent Required) + +You can use the chat client classes directly for advanced workflows: + +```python +import asyncio +from agent_framework.openai import OpenAIChatClient +from agent_framework import ChatMessage, ChatRole + +async def main(): + client = OpenAIChatClient() + + messages = [ + ChatMessage(role=ChatRole.SYSTEM, text="You are a helpful assistant."), + ChatMessage(role=ChatRole.USER, text="Write a haiku about Agent Framework.") + ] + + response = await client.get_response(messages) + print(response.messages[0].text) + + """ + Output: + + Agents work in sync, + Framework threads through each task— + Code sparks collaboration. + """ + +asyncio.run(main()) +``` + +## 4. Build an Agent with Tools and Functions + +Enhance your agent with custom tools and function calling: + +```python +import asyncio +from typing import Annotated +from random import randint +from pydantic import Field +from agent_framework import ChatClientAgent +from agent_framework.openai import OpenAIChatClient + + +def get_weather( + location: Annotated[str, Field(description="The location to get the weather for.")], +) -> str: + """Get the weather for a given location.""" + conditions = ["sunny", "cloudy", "rainy", "stormy"] + return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C." + + +def get_menu_specials() -> str: + """Get today's menu specials.""" + return """ + Special Soup: Clam Chowder + Special Salad: Cobb Salad + Special Drink: Chai Tea + """ + + +async def main(): + agent = ChatClientAgent( + chat_client=OpenAIChatClient(), + instructions="You are a helpful assistant that can provide weather and restaurant information.", + tools=[get_weather, get_menu_specials] + ) + + response = await agent.run("What's the weather in Amsterdam and what are today's specials?") + print(response) + + """ + Output: + The weather in Amsterdam is sunny with a high of 22°C. Today's specials include + Clam Chowder soup, Cobb Salad, and Chai Tea as the special drink. + """ + +if __name__ == "__main__": + asyncio.run(main()) +``` + +You can explore additional agent samples [here](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started/agents). + +## 5. Multi-Agent Orchestration + +Coordinate multiple agents to collaborate on complex tasks using orchestration patterns: + +```python +import asyncio +from agent_framework import ChatClientAgent +from agent_framework.openai import OpenAIChatClient + + +async def main(): + # Create specialized agents + writer = ChatClientAgent( + chat_client=OpenAIChatClient(), + name="Writer", + instructions="You are a creative content writer. Generate and refine slogans based on feedback." + ) + + reviewer = ChatClientAgent( + chat_client=OpenAIChatClient(), + name="Reviewer", + instructions="You are a critical reviewer. Provide detailed feedback on proposed slogans." + ) + + # Sequential workflow: Writer creates, Reviewer provides feedback + task = "Create a slogan for a new electric SUV that is affordable and fun to drive." + + # Step 1: Writer creates initial slogan + initial_result = await writer.run(task) + print(f"Writer: {initial_result}") + + # Step 2: Reviewer provides feedback + feedback_request = f"Please review this slogan: {initial_result}" + feedback = await reviewer.run(feedback_request) + print(f"Reviewer: {feedback}") + + # Step 3: Writer refines based on feedback + refinement_request = f"Please refine this slogan based on the feedback: {initial_result}\nFeedback: {feedback}" + final_result = await writer.run(refinement_request) + print(f"Final Slogan: {final_result}") + + # Example Output: + # Writer: "Charge Forward: Affordable Adventure Awaits!" + # Reviewer: "Good energy, but 'Charge Forward' is overused in EV marketing..." + # Final Slogan: "Power Up Your Adventure: Premium Feel, Smart Price!" + +if __name__ == "__main__": + asyncio.run(main()) +``` + +**Note**: Advanced orchestration patterns like GroupChat, Sequential, and Concurrent orchestrations are coming soon. + +## More Examples & Samples + +- [Getting Started with Agents](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started/agents): Basic agent creation and tool usage +- [Chat Client Examples](https://github.com/microsoft/agent-framework/tree/main/python/samples/getting_started/chat_client): Direct chat client usage patterns +- [Azure Integration](https://github.com/microsoft/agent-framework/tree/main/python/packages/azure): Azure OpenAI and AI Foundry integration +- [.NET Orchestration Samples](https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/GettingStarted/Orchestration): Advanced multi-agent patterns (.NET) + +## Agent Framework Documentation + +- [Agent Framework Repository](https://github.com/microsoft/agent-framework) +- [Python Package Documentation](https://github.com/microsoft/agent-framework/tree/main/python) +- [.NET Package Documentation](https://github.com/microsoft/agent-framework/tree/main/dotnet) +- [Design Documents](https://github.com/microsoft/agent-framework/tree/main/docs/design) +- Learn docs are coming soon. diff --git a/python/packages/foundry/agent_framework_foundry/_chat_client.py b/python/packages/foundry/agent_framework_foundry/_chat_client.py index 7cf56022b3..d01c030b67 100644 --- a/python/packages/foundry/agent_framework_foundry/_chat_client.py +++ b/python/packages/foundry/agent_framework_foundry/_chat_client.py @@ -245,7 +245,7 @@ class FoundryChatClient(ChatClientBase): raise ValueError("No thread ID was provided, but chat messages includes tool results.") # Determine which agent to use and create if needed - agent_id = await self._get_agent_id_or_create() + agent_id = await self._get_agent_id_or_create(run_options) # Create the streaming response stream, thread_id = await self._create_agent_stream(thread_id, agent_id, run_options, tool_results) @@ -254,7 +254,7 @@ class FoundryChatClient(ChatClientBase): async for update in self._process_stream_events(stream, thread_id): yield update - async def _get_agent_id_or_create(self) -> str: + async def _get_agent_id_or_create(self, run_options: dict[str, Any] | None = None) -> str: """Determine which agent to use and create if needed. Returns: @@ -266,9 +266,15 @@ class FoundryChatClient(ChatClientBase): raise ServiceInitializationError("Model deployment name is required for agent creation.") agent_name = self._foundry_settings.agent_name - created_agent = await self.client.agents.create_agent( - model=self._foundry_settings.model_deployment_name, name=agent_name - ) + args = {"model": self._foundry_settings.model_deployment_name, "name": agent_name} + if run_options: + if "tools" in run_options: + args["tools"] = run_options["tools"] + if "instructions" in run_options: + args["instructions"] = run_options["instructions"] + if "response_format" in run_options: + args["response_format"] = run_options["response_format"] + created_agent = await self.client.agents.create_agent(**args) # type: ignore[arg-type] self.agent_id = created_agent.id self._should_delete_agent = True diff --git a/python/packages/main/agent_framework/_agents.py b/python/packages/main/agent_framework/_agents.py index abe98e48ad..66f1c8f2df 100644 --- a/python/packages/main/agent_framework/_agents.py +++ b/python/packages/main/agent_framework/_agents.py @@ -2,6 +2,7 @@ import sys from collections.abc import AsyncIterable, Callable, MutableMapping, Sequence +from contextlib import AbstractAsyncContextManager from enum import Enum from typing import Any, ClassVar, Literal, Protocol, TypeVar, runtime_checkable from uuid import uuid4 @@ -417,7 +418,7 @@ class ChatClientAgent(AgentBase): If the chat_client supports async context management, enter its context. """ - if hasattr(self.chat_client, "__aenter__") and hasattr(self.chat_client, "__aexit__"): + if isinstance(self.chat_client, AbstractAsyncContextManager): await self.chat_client.__aenter__() # type: ignore[reportUnknownMemberType] return self @@ -426,7 +427,7 @@ class ChatClientAgent(AgentBase): If the chat_client supports async context management, exit its context. """ - if hasattr(self.chat_client, "__aenter__") and hasattr(self.chat_client, "__aexit__"): + if isinstance(self.chat_client, AbstractAsyncContextManager): await self.chat_client.__aexit__(exc_type, exc_val, exc_tb) # type: ignore[reportUnknownMemberType] async def run( diff --git a/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py b/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py index 9f321a6470..fd8e2e0a96 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py @@ -2,7 +2,7 @@ import asyncio -from agent_framework import AgentRunResponseUpdate, ChatClientAgent, HostedCodeInterpreterTool +from agent_framework import AgentRunResponseUpdate, ChatClientAgent, ChatResponseUpdate, HostedCodeInterpreterTool from agent_framework.foundry import FoundryChatClient from azure.ai.agents.models import ( RunStepDelta, @@ -16,12 +16,13 @@ from azure.ai.agents.models import ( def get_code_interpreter_chunk(chunk: AgentRunResponseUpdate) -> str | None: """Helper method to access code interpreter data.""" if ( - isinstance(chunk.raw_representation, RunStepDeltaChunk) - and isinstance(chunk.raw_representation.delta, RunStepDelta) - and isinstance(chunk.raw_representation.delta.step_details, RunStepDeltaToolCallObject) - and chunk.raw_representation.delta.step_details.tool_calls + isinstance(chunk.raw_representation, ChatResponseUpdate) + and isinstance(chunk.raw_representation.raw_representation, RunStepDeltaChunk) + and isinstance(chunk.raw_representation.raw_representation.delta, RunStepDelta) + and isinstance(chunk.raw_representation.raw_representation.delta.step_details, RunStepDeltaToolCallObject) + and chunk.raw_representation.raw_representation.delta.step_details.tool_calls ): - for tool_call in chunk.raw_representation.delta.step_details.tool_calls: + for tool_call in chunk.raw_representation.raw_representation.delta.step_details.tool_calls: if ( isinstance(tool_call, RunStepDeltaCodeInterpreterToolCall) and isinstance(tool_call.code_interpreter, RunStepDeltaCodeInterpreterDetailItemObject) @@ -40,7 +41,7 @@ async def main() -> None: instructions="You are a helpful assistant that can write and execute Python code to solve problems.", tools=HostedCodeInterpreterTool(), ) as agent: - query = "What is current datetime?" + query = "Generate the factorial of 100 using python code." print(f"User: {query}") print("Agent: ", end="", flush=True) generated_code = "" diff --git a/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py b/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py index bda2fde90a..1b525bdd26 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py @@ -33,6 +33,8 @@ async def main() -> None: try: async with ChatClientAgent( + # passing in the client is optional here, so if you take the agent_id from the portal + # you can use it directly without the two lines above. chat_client=FoundryChatClient(client=client, agent_id=created_agent.id), instructions="You are a helpful weather agent.", tools=get_weather, diff --git a/python/samples/getting_started/agents/openai_assistants_client/openai_assistants_with_code_interpreter.py b/python/samples/getting_started/agents/openai_assistants_client/openai_assistants_with_code_interpreter.py index 406ea9ce0a..57d2cca223 100644 --- a/python/samples/getting_started/agents/openai_assistants_client/openai_assistants_with_code_interpreter.py +++ b/python/samples/getting_started/agents/openai_assistants_client/openai_assistants_with_code_interpreter.py @@ -16,12 +16,13 @@ from openai.types.beta.threads.runs.code_interpreter_tool_call_delta import Code def get_code_interpreter_chunk(chunk: AgentRunResponseUpdate) -> str | None: """Helper method to access code interpreter data.""" if ( - isinstance(chunk.raw_representation, RunStepDeltaEvent) - and isinstance(chunk.raw_representation.delta, RunStepDelta) - and isinstance(chunk.raw_representation.delta.step_details, ToolCallDeltaObject) - and chunk.raw_representation.delta.step_details.tool_calls + isinstance(chunk.raw_representation, AgentRunResponseUpdate) + and isinstance(chunk.raw_representation.raw_representation, RunStepDeltaEvent) + and isinstance(chunk.raw_representation.raw_representation.delta, RunStepDelta) + and isinstance(chunk.raw_representation.raw_representation.delta.step_details, ToolCallDeltaObject) + and chunk.raw_representation.raw_representation.delta.step_details.tool_calls ): - for tool_call in chunk.raw_representation.delta.step_details.tool_calls: + for tool_call in chunk.raw_representation.raw_representation.delta.step_details.tool_calls: if ( isinstance(tool_call, CodeInterpreterToolCallDelta) and isinstance(tool_call.code_interpreter, CodeInterpreter) @@ -40,7 +41,7 @@ async def main() -> None: instructions="You are a helpful assistant that can write and execute Python code to solve problems.", tools=HostedCodeInterpreterTool(), ) as agent: - query = "What is current datetime?" + query = "Use code to get the factorial of 100?" print(f"User: {query}") print("Agent: ", end="", flush=True) generated_code = "" diff --git a/python/samples/getting_started/agents/openai_responses_client/openai_responses_client_with_code_interpreter.py b/python/samples/getting_started/agents/openai_responses_client/openai_responses_client_with_code_interpreter.py index 9810ae8eca..8e144e87b0 100644 --- a/python/samples/getting_started/agents/openai_responses_client/openai_responses_client_with_code_interpreter.py +++ b/python/samples/getting_started/agents/openai_responses_client/openai_responses_client_with_code_interpreter.py @@ -2,7 +2,7 @@ import asyncio -from agent_framework import ChatClientAgent, HostedCodeInterpreterTool +from agent_framework import ChatClientAgent, ChatResponse, HostedCodeInterpreterTool from agent_framework.openai import OpenAIResponsesClient from openai.types.responses.response import Response as OpenAIResponse from openai.types.responses.response_code_interpreter_tool_call import ResponseCodeInterpreterToolCall @@ -18,17 +18,18 @@ async def main() -> None: tools=HostedCodeInterpreterTool(), ) - query = "What is current datetime?" + query = "Use code to get the factorial of 100?" print(f"User: {query}") result = await agent.run(query) print(f"Result: {result}\n") if ( - isinstance(result.raw_representation, OpenAIResponse) - and len(result.raw_representation.output) > 0 - and isinstance(result.raw_representation.output[0], ResponseCodeInterpreterToolCall) + isinstance(result.raw_representation, ChatResponse) + and isinstance(result.raw_representation.raw_representation, OpenAIResponse) + and len(result.raw_representation.raw_representation.output) > 0 + and isinstance(result.raw_representation.raw_representation.output[0], ResponseCodeInterpreterToolCall) ): - generated_code = result.raw_representation.output[0].code + generated_code = result.raw_representation.raw_representation.output[0].code print(f"Generated code:\n{generated_code}")