diff --git a/python/packages/foundry_hosting/agent_framework_foundry_hosting/_invocations.py b/python/packages/foundry_hosting/agent_framework_foundry_hosting/_invocations.py index 08407874df..84e04c186d 100644 --- a/python/packages/foundry_hosting/agent_framework_foundry_hosting/_invocations.py +++ b/python/packages/foundry_hosting/agent_framework_foundry_hosting/_invocations.py @@ -17,7 +17,6 @@ class InvocationsHostServer(InvocationAgentServerHost): self, agent: BaseAgent, *, - stream: bool = False, openapi_spec: Optional[dict[str, Any]] = None, **kwargs: Any, ) -> None: @@ -25,7 +24,6 @@ class InvocationsHostServer(InvocationAgentServerHost): Args: agent: The agent to handle responses for. - stream: Whether to stream the responses. Defaults to True. openapi_spec: The OpenAPI specification for the server. **kwargs: Additional keyword arguments. @@ -40,7 +38,6 @@ class InvocationsHostServer(InvocationAgentServerHost): append_to_user_agent(self.USER_AGENT_PREFIX) self._agent = agent - self._stream = stream self._sessions: dict[str, AgentSession] = {} self.invoke_handler(self._handle_invoke) # pyright: ignore[reportUnknownMemberType] @@ -49,16 +46,17 @@ class InvocationsHostServer(InvocationAgentServerHost): data = await request.json() session_id: str = request.state.session_id + stream = data.get("stream", False) user_message = data.get("message", None) if user_message is None: error = "Missing 'message' in request" - if self._stream: + if stream: return StreamingResponse(content=error, status_code=400) return Response(content=error, status_code=400) session = self._sessions.setdefault(session_id, AgentSession(session_id=session_id)) - if self._stream: + if stream: async def stream_response() -> AsyncGenerator[str]: async for update in self._agent.run(user_message, session=session, stream=True): @@ -70,7 +68,7 @@ class InvocationsHostServer(InvocationAgentServerHost): headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}, ) - response = await self._agent.run([user_message], session=session, stream=self._stream) + response = await self._agent.run([user_message], session=session, stream=stream) return JSONResponse({ "response": response.text, "session_id": session_id, diff --git a/python/packages/foundry_hosting/pyproject.toml b/python/packages/foundry_hosting/pyproject.toml index 377e4de7e3..23217fa74e 100644 --- a/python/packages/foundry_hosting/pyproject.toml +++ b/python/packages/foundry_hosting/pyproject.toml @@ -24,9 +24,9 @@ classifiers = [ ] dependencies = [ "agent-framework-core>=1.0.0,<2", - "azure-ai-agentserver-core==2.0.0a20260410006", - "azure-ai-agentserver-responses==1.0.0a20260410006", - "azure-ai-agentserver-invocations==1.0.0a20260410006", + "azure-ai-agentserver-core==2.0.0a20260414006", + "azure-ai-agentserver-responses==1.0.0a20260414006", + "azure-ai-agentserver-invocations==1.0.0a20260414006", "azure-monitor-opentelemetry-exporter>=1.0.0a1" ] diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/.env.example b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/.env.example new file mode 100644 index 0000000000..fe302a8adb --- /dev/null +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/.env.example @@ -0,0 +1,2 @@ +FOUNDRY_PROJECT_ENDPOINT="..." +MODEL_DEPLOYMENT_NAME="..." \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/README.md index e6eaa7c6c7..66341fa9a9 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/README.md +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/README.md @@ -1,12 +1,6 @@ # Basic example of hosting an agent with the `responses` API -## Running the server locally - -Run the following command to start the server: - -```bash -python main.py -``` +This agent only contains an instruction (personal). It's the most basic agent with an LLM and no tools. ## Interacting with the agent @@ -16,7 +10,11 @@ Send a POST request to the server with a JSON body containing a "message" field curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}' ``` -The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests. +### Invoke with `azd` + +```bash +azd ai agent invoke --local "Hi" +``` ## Multi-turn conversation @@ -26,10 +24,10 @@ To have a multi-turn conversation with the agent, include the previous response curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}' ``` -## Deploying to Foundry +Invoke with `azd`: -TODO +```bash +azd ai agent invoke --local "Hi!" --conversation-id "my_conv" -## Using the deployed agent in Agent Framework - -TODO +azd ai agent invoke --local "How are you?" --conversation-id "my_conv" +``` diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/agent.manifest.yaml index 27bb7630e8..4f4749af25 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/agent.manifest.yaml +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/agent.manifest.yaml @@ -3,6 +3,7 @@ description: > A basic Agent Framework agent hosted by Foundry. metadata: tags: + - Agent Framework - AI Agent Hosting - Azure AI AgentServer - Responses Protocol @@ -12,4 +13,11 @@ template: kind: hosted protocols: - protocol: responses - version: v0.1.0 \ No newline at end of file + version: 1.0.0 + environment_variables: + - name: MODEL_DEPLOYMENT_NAME + value: "{{MODEL_DEPLOYMENT_NAME}}" +resources: + - kind: model + id: gpt-4.1-mini + name: MODEL_DEPLOYMENT_NAME \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/main.py index d88b7f61d2..c044fcdd8b 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/main.py +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/01_basic/main.py @@ -16,7 +16,7 @@ load_dotenv() def main(): client = FoundryChatClient( project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], + model=os.environ["MODEL_DEPLOYMENT_NAME"], credential=AzureCliCredential(), ) diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/.env.example b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/.env.example new file mode 100644 index 0000000000..fe302a8adb --- /dev/null +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/.env.example @@ -0,0 +1,2 @@ +FOUNDRY_PROJECT_ENDPOINT="..." +MODEL_DEPLOYMENT_NAME="..." \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/README.md index b262afa7ab..979cf8420f 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/README.md +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/README.md @@ -1,13 +1,23 @@ # Basic example of hosting an agent with the `responses` API and local tools -Run the following command to start the server: +This agent is equipped with with a function tool and a local shell tool. -```bash -python main.py -``` +> We recommend deploying this sample on a local container or to Foundry Hosting because the agent has access to a local shell tool, which can run arbitrary commands on the machine. + +## Interacting with the agent Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: ```bash curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "What is the weather in Seattle?"}' + +curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "List the files in the current directory."}' +``` + +Invoke with `azd`: + +```bash +azd ai agent invoke --local "What is the weather in Seattle?" + +azd ai agent invoke --local "List the files in the current directory." ``` diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/agent.manifest.yaml index 84a6fd95f5..ea8c6010ec 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/agent.manifest.yaml +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/agent.manifest.yaml @@ -1,8 +1,9 @@ name: agent-framework-agent-with-local-tools description: > - An Agent Framework agent with local toolshosted by Foundry. + An Agent Framework agent with local tools hosted by Foundry. metadata: tags: + - Agent Framework - AI Agent Hosting - Azure AI AgentServer - Responses Protocol @@ -12,4 +13,11 @@ template: kind: hosted protocols: - protocol: responses - version: v0.1.0 \ No newline at end of file + version: 1.0.0 + environment_variables: + - name: MODEL_DEPLOYMENT_NAME + value: "{{MODEL_DEPLOYMENT_NAME}}" +resources: + - kind: model + id: gpt-4.1-mini + name: MODEL_DEPLOYMENT_NAME \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/main.py index 894b0247e0..0482e9e14c 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/main.py +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/02_local_tools/main.py @@ -1,6 +1,7 @@ # Copyright (c) Microsoft. All rights reserved. import os +import subprocess from random import randint from agent_framework import Agent, tool @@ -25,17 +26,41 @@ def get_weather( return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C." +@tool(approval_mode="always_require") +def run_bash(command: str) -> str: + """Execute a shell command locally and return stdout, stderr, and exit code.""" + try: + result = subprocess.run( + command, + shell=True, + capture_output=True, + text=True, + timeout=30, + ) + parts: list[str] = [] + if result.stdout: + parts.append(result.stdout) + if result.stderr: + parts.append(f"stderr: {result.stderr}") + parts.append(f"exit_code: {result.returncode}") + return "\n".join(parts) + except subprocess.TimeoutExpired: + return "Command timed out after 30 seconds" + except Exception as e: + return f"Error executing command: {e}" + + def main(): client = FoundryChatClient( project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], + model=os.environ["MODEL_DEPLOYMENT_NAME"], credential=AzureCliCredential(), ) agent = Agent( client=client, instructions="You are a friendly assistant. Keep your answers brief.", - tools=[get_weather], + tools=[get_weather, run_bash], # History will be managed by the hosting infrastructure, thus there # is no need to store history by the service. Learn more at: # https://developers.openai.com/api/reference/resources/responses/methods/create diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/.env.example b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/.env.example new file mode 100644 index 0000000000..3139815ec1 --- /dev/null +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/.env.example @@ -0,0 +1,4 @@ +FOUNDRY_PROJECT_ENDPOINT="..." +MODEL_DEPLOYMENT_NAME="..." +FOUNDRY_AGENT_TOOLBOX_NAME="..." +GITHUB_PAT="..." \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/README.md index 5091871aa8..56f5ec4ed4 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/README.md +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/README.md @@ -1,13 +1,19 @@ # Basic example of hosting an agent with the `responses` API and a remote MCP -Run the following command to start the server: +This agent is equipped with a GitHub MCP server and a Foundry Toolbox, which are both remote MCPs. -```bash -python main.py -``` +> Note that there are other ways to interact with Foundry toolboxes. Using it as a MCP is just one of the options. + +## Interacting with the agent Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: ```bash curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "List all the repositories I own on GitHub."}' ``` + +Invoke with `azd`: + +```bash +azd ai agent invoke --local "List all the repositories I own on GitHub." +``` diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/agent.manifest.yaml index daf7b10cd3..ef27f6ecd1 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/agent.manifest.yaml +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/agent.manifest.yaml @@ -3,6 +3,7 @@ description: > An Agent Framework agent with remote MCP tools hosted by Foundry. metadata: tags: + - Agent Framework - AI Agent Hosting - Azure AI AgentServer - Responses Protocol @@ -12,4 +13,15 @@ template: kind: hosted protocols: - protocol: responses - version: v0.1.0 \ No newline at end of file + version: 1.0.0 + environment_variables: + - name: MODEL_DEPLOYMENT_NAME + value: "{{MODEL_DEPLOYMENT_NAME}}" + - name: GITHUB_PAT + value: ${GITHUB_PAT} + - name: FOUNDRY_AGENT_TOOLBOX_NAME + value: ${FOUNDRY_AGENT_TOOLBOX_NAME} +resources: + - kind: model + id: gpt-4.1-mini + name: MODEL_DEPLOYMENT_NAME diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/main.py index cb25d2ef96..80531a0ca1 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/main.py +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/03_remote_mcp/main.py @@ -2,7 +2,8 @@ import os -from agent_framework import Agent +import httpx +from agent_framework import Agent, MCPStreamableHTTPTool from agent_framework.foundry import FoundryChatClient from agent_framework_foundry_hosting import ResponsesHostServer from azure.ai.agentserver.responses import InMemoryResponseProvider @@ -13,14 +14,37 @@ from dotenv import load_dotenv load_dotenv() +class ToolboxAuth(httpx.Auth): + """httpx Auth that injects a fresh bearer token on every request.""" + + def auth_flow(self, request: httpx.Request): + credential = AzureCliCredential() + token = credential.get_token("https://ai.azure.com/.default").token + request.headers["Authorization"] = f"Bearer {token}" + yield request + + def main(): client = FoundryChatClient( project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], + model=os.environ["MODEL_DEPLOYMENT_NAME"], credential=AzureCliCredential(), ) - github_pat = os.getenv("GITHUB_PAT") + # Foundry Toolbox as a MCP tool + project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + toolbox_name = os.environ["FOUNDRY_AGENT_TOOLBOX_NAME"] + toolbox_endpoint = f"{project_endpoint.rstrip('/')}/toolboxes/{toolbox_name}/mcp?api-version=v1" + http_client = httpx.AsyncClient(auth=ToolboxAuth(), headers={"Foundry-Features": "Toolboxes=V1Preview"}) + foundry_mcp_tool = MCPStreamableHTTPTool( + name="toolbox", + url=toolbox_endpoint, + http_client=http_client, + load_prompts=False, + ) + + # GitHub MCP server + github_pat = os.environ["GITHUB_PAT"] if not github_pat: raise ValueError( "GITHUB_PAT environment variable must be set. Create a token at https://github.com/settings/tokens" @@ -38,7 +62,7 @@ def main(): agent = Agent( client=client, instructions="You are a friendly assistant. Keep your answers brief.", - tools=[github_mcp_tool], + tools=[foundry_mcp_tool, github_mcp_tool], # History will be managed by the hosting infrastructure, thus there # is no need to store history by the service. Learn more at: # https://developers.openai.com/api/reference/resources/responses/methods/create diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/.env.example b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/.env.example new file mode 100644 index 0000000000..fe302a8adb --- /dev/null +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/.env.example @@ -0,0 +1,2 @@ +FOUNDRY_PROJECT_ENDPOINT="..." +MODEL_DEPLOYMENT_NAME="..." \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/README.md index 75d87c3fcb..3346c2d083 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/README.md +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/README.md @@ -1,13 +1,17 @@ # Basic example of hosting an agent with the `responses` API and a workflow -Run the following command to start the server: +This sample demonstrates how to host a workflow using the `responses` API. -```bash -python main.py -``` +## Interacting with the agent Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: ```bash curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Create a slogan for a new electric SUV that is affordable and fun to drive."}' ``` + +Invoke with `azd`: + +```bash +azd ai agent invoke --local "List all the repositories I own on GitHub." +``` diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/agent.manifest.yaml index 027ca3713b..d561ec043a 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/agent.manifest.yaml +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/agent.manifest.yaml @@ -3,6 +3,7 @@ description: > An Agent Framework workflow hosted by Foundry. metadata: tags: + - Agent Framework - AI Agent Hosting - Azure AI AgentServer - Responses Protocol @@ -12,4 +13,11 @@ template: kind: hosted protocols: - protocol: responses - version: v0.1.0 \ No newline at end of file + version: 1.0.0 + environment_variables: + - name: MODEL_DEPLOYMENT_NAME + value: "{{MODEL_DEPLOYMENT_NAME}}" +resources: + - kind: model + id: gpt-4.1-mini + name: MODEL_DEPLOYMENT_NAME \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/main.py index 58fad23c97..d4d4d00057 100644 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/main.py +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/04_workflows/main.py @@ -24,7 +24,7 @@ def round_robin_selector(state: GroupChatState) -> str: def main(): client = FoundryChatClient( project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], + model=os.environ["MODEL_DEPLOYMENT_NAME"], credential=AzureCliCredential(), ) diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/.dockerignore b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/.dockerignore deleted file mode 100644 index 008e6e6616..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -.venv -__pycache__ -*.pyc -*.pyo -*.pyd -.Python \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/Dockerfile b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/Dockerfile deleted file mode 100644 index 845d325e7c..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.12-slim - -WORKDIR /app/user_agent - -COPY wheels/ /tmp/wheels/ -COPY requirements.txt . -RUN pip install --no-cache-dir --find-links /tmp/wheels/ -r requirements.txt && rm -rf /tmp/wheels/ - -COPY . . - -RUN useradd -r appuser -USER appuser - -EXPOSE 8088 - -CMD ["python", "main.py"] \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/README.md deleted file mode 100644 index 73f1ad05a9..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Agent Framework Agent with Local Shell - -> Note: This agent can execute local shell commands. We recommend running it in an isolated environment for security reasons. - -## Running the server in a Docker container - -Build the Docker image: - -```bash -docker build -t agent-framework-agent-with-local-shell . -``` - -Run the Docker container: - -```bash -docker run -p 8088:8088 --env-file .env agent-framework-agent-with-local-shell -``` - -## Interacting with the agent - -Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: - -```bash -curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}' -``` - -The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests. - -## Multi-turn conversation - -To have a multi-turn conversation with the agent, include the previous response id in the request body. For example: - -```bash -curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}' -``` - -## Deploying to Foundry - -TODO - -## Using the deployed agent in Agent Framework - -TODO diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/agent.manifest.yaml deleted file mode 100644 index 32f133d12d..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/agent.manifest.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: agent-framework-agent-with-local-shell -description: > - An Agent Framework agent that can execute local shell commands hosted by Foundry. -metadata: - tags: - - AI Agent Hosting - - Azure AI AgentServer - - Responses Protocol - - Streaming -template: - name: agent-framework-agent-with-local-shell - kind: hosted - protocols: - - protocol: responses - version: v0.1.0 \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/agent.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/agent.yaml deleted file mode 100644 index 6c0a04b83b..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/agent.yaml +++ /dev/null @@ -1,8 +0,0 @@ -kind: hosted -name: agent-framework-agent-with-local-shell -protocols: - - protocol: responses - version: v0.1.0 -resources: - cpu: "0.25" - memory: 0.5Gi \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/main.py deleted file mode 100644 index bce794a911..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/main.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -import os -import subprocess - -from agent_framework import Agent, tool -from agent_framework.foundry import FoundryChatClient -from agent_framework_foundry_hosting import ResponsesHostServer -from azure.ai.agentserver.responses import InMemoryResponseProvider -from azure.identity import AzureCliCredential -from dotenv import load_dotenv - -# Load environment variables from .env file -load_dotenv() - - -@tool(approval_mode="always_require") -def run_bash(command: str) -> str: - """Execute a shell command locally and return stdout, stderr, and exit code.""" - try: - result = subprocess.run( - command, - shell=True, - capture_output=True, - text=True, - timeout=30, - ) - parts: list[str] = [] - if result.stdout: - parts.append(result.stdout) - if result.stderr: - parts.append(f"stderr: {result.stderr}") - parts.append(f"exit_code: {result.returncode}") - return "\n".join(parts) - except subprocess.TimeoutExpired: - return "Command timed out after 30 seconds" - except Exception as e: - return f"Error executing command: {e}" - - -def main(): - client = FoundryChatClient( - project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], - credential=AzureCliCredential(), - ) - - agent = Agent( - client=client, - instructions="You are a friendly assistant. Keep your answers brief.", - tools=[run_bash], - # History will be managed by the hosting infrastructure, thus there - # is no need to store history by the service. Learn more at: - # https://developers.openai.com/api/reference/resources/responses/methods/create - default_options={"store": False}, - ) - - server = ResponsesHostServer(agent, store=InMemoryResponseProvider()) - server.run() - - -if __name__ == "__main__": - main() diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/requirements.txt b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/requirements.txt deleted file mode 100644 index 61b5ba14f7..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/05_local_shell/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -agent-framework-core -agent-framework-foundry-hosting \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/.dockerignore b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/.dockerignore deleted file mode 100644 index 008e6e6616..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -.venv -__pycache__ -*.pyc -*.pyo -*.pyd -.Python \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/Dockerfile b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/Dockerfile deleted file mode 100644 index eaffb94f19..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.12-slim - -WORKDIR /app - -COPY . user_agent/ -WORKDIR /app/user_agent - -RUN if [ -f requirements.txt ]; then \ - pip install -r requirements.txt; \ - else \ - echo "No requirements.txt found"; \ - fi - -EXPOSE 8088 - -CMD ["python", "main.py"] \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/README.md deleted file mode 100644 index 195d10e966..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Agent Framework Agent with Evaluation - -## Running the server locally - -Run the following command to start the server: - -```bash -python main.py -``` - -## Interacting with the agent - -Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: - -```bash -curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}' -``` - -The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests. - -## Multi-turn conversation - -To have a multi-turn conversation with the agent, include the previous response id in the request body. For example: - -```bash -curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}' -``` - -## Deploying to Foundry - -TODO - -## Using the deployed agent in Agent Framework - -TODO diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/agent.manifest.yaml deleted file mode 100644 index a6cc8af7fd..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/agent.manifest.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: agent-framework-agent-with-eval -description: > - An Agent Framework agent is evaluated on each response hosted by Foundry. -metadata: - tags: - - AI Agent Hosting - - Azure AI AgentServer - - Responses Protocol - - Streaming -template: - name: agent-framework-agent-with-eval - kind: hosted - protocols: - - protocol: responses - version: v0.1.0 \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/agent.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/agent.yaml deleted file mode 100644 index 7fa752ca8b..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/agent.yaml +++ /dev/null @@ -1,8 +0,0 @@ -kind: hosted -name: agent-framework-agent-with-eval -protocols: - - protocol: responses - version: v0.1.0 -resources: - cpu: "0.25" - memory: 0.5Gi \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/main.py deleted file mode 100644 index 894b0247e0..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/main.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -import os -from random import randint - -from agent_framework import Agent, tool -from agent_framework.foundry import FoundryChatClient -from agent_framework_foundry_hosting import ResponsesHostServer -from azure.ai.agentserver.responses import InMemoryResponseProvider -from azure.identity import AzureCliCredential -from dotenv import load_dotenv -from pydantic import Field -from typing_extensions import Annotated - -# Load environment variables from .env file -load_dotenv() - - -@tool(approval_mode="never_require") -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 main(): - client = FoundryChatClient( - project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], - credential=AzureCliCredential(), - ) - - agent = Agent( - client=client, - instructions="You are a friendly assistant. Keep your answers brief.", - tools=[get_weather], - # History will be managed by the hosting infrastructure, thus there - # is no need to store history by the service. Learn more at: - # https://developers.openai.com/api/reference/resources/responses/methods/create - default_options={"store": False}, - ) - - server = ResponsesHostServer(agent, store=InMemoryResponseProvider()) - server.run() - - -if __name__ == "__main__": - main() diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/requirements.txt b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/requirements.txt deleted file mode 100644 index f7dc62f3e3..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/06_eval/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -agent-framework -agent-framework-foundry-hosting \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/.dockerignore b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/.dockerignore deleted file mode 100644 index 008e6e6616..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -.venv -__pycache__ -*.pyc -*.pyo -*.pyd -.Python \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/Dockerfile b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/Dockerfile deleted file mode 100644 index eaffb94f19..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.12-slim - -WORKDIR /app - -COPY . user_agent/ -WORKDIR /app/user_agent - -RUN if [ -f requirements.txt ]; then \ - pip install -r requirements.txt; \ - else \ - echo "No requirements.txt found"; \ - fi - -EXPOSE 8088 - -CMD ["python", "main.py"] \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/README.md deleted file mode 100644 index e9987de36d..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Agent Framework Agent with Foundry Memory - -## Running the server locally - -Run the following command to start the server: - -```bash -python main.py -``` - -## Interacting with the agent - -Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: - -```bash -curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}' -``` - -The server will respond with a JSON object containing the response text and a response ID. You can use this response ID to continue the conversation in subsequent requests. - -## Multi-turn conversation - -To have a multi-turn conversation with the agent, include the previous response id in the request body. For example: - -```bash -curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "How are you?", "previous_response_id": "REPLACE_WITH_PREVIOUS_RESPONSE_ID"}' -``` - -## Deploying to Foundry - -TODO - -## Using the deployed agent in Agent Framework - -TODO diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/agent.manifest.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/agent.manifest.yaml deleted file mode 100644 index b0cf8c5fab..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/agent.manifest.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: agent-framework-agent-with-foundry-memory -description: > - An Agent Framework agent with memory support hosted by Foundry. -metadata: - tags: - - AI Agent Hosting - - Azure AI AgentServer - - Responses Protocol - - Streaming -template: - name: agent-framework-agent-with-foundry-memory - kind: hosted - protocols: - - protocol: responses - version: v0.1.0 \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/agent.yaml b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/agent.yaml deleted file mode 100644 index 90c9a26406..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/agent.yaml +++ /dev/null @@ -1,8 +0,0 @@ -kind: hosted -name: agent-framework-agent-with-foundry-memory -protocols: - - protocol: responses - version: v0.1.0 -resources: - cpu: "0.25" - memory: 0.5Gi \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/main.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/main.py deleted file mode 100644 index fabbfd98ef..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/main.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -import asyncio -import logging -import os -from datetime import datetime, timezone - -from agent_framework import Agent -from agent_framework.foundry import FoundryChatClient, FoundryMemoryProvider -from agent_framework_foundry_hosting import ResponsesHostServer -from azure.ai.agentserver.responses import InMemoryResponseProvider -from azure.ai.projects.aio import AIProjectClient -from azure.ai.projects.models import ( - MemoryStoreDefaultDefinition, - MemoryStoreDefaultOptions, -) -from azure.identity import AzureCliCredential -from dotenv import load_dotenv - -# Load environment variables from .env file -load_dotenv() - -logging.basicConfig(level=logging.INFO) - - -async def _create_memory_store(project_client: AIProjectClient) -> FoundryMemoryProvider: - memory_store_name = f"hosted_agent_memory_{datetime.now(timezone.utc).strftime('%Y%m%d')}" - options = MemoryStoreDefaultOptions( - chat_summary_enabled=True, - user_profile_enabled=True, - user_profile_details=( - "Avoid irrelevant or sensitive data, such as age, financials, precise location, and credentials" - ), - ) - memory_store_definition = MemoryStoreDefaultDefinition( - chat_model=os.environ["FOUNDRY_MODEL"], - embedding_model=os.environ["AZURE_OPENAI_EMBEDDING_MODEL"], - options=options, - ) - memory_store = await project_client.beta.memory_stores.create( - name=memory_store_name, - description="Memory store for Agent Framework with FoundryMemoryProvider", - definition=memory_store_definition, - ) - - return FoundryMemoryProvider( - project_client=project_client, - memory_store_name=memory_store.name, - # Scope memories to a specific user, if not set, the session_id - # will be used as scope, which means memories are only shared within the same session - scope="demo", - # Do not wait to update memories after each interaction (for demo purposes) - # In production, consider setting a delay to batch updates and reduce costs - update_delay=0, - ) - - -async def _delete_memory_store(project_client: AIProjectClient, memory_store_name: str): - await project_client.beta.memory_stores.delete(name=memory_store_name) - - -async def main(): - client = FoundryChatClient( - project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model=os.environ["FOUNDRY_MODEL"], - credential=AzureCliCredential(), - ) - - # Create the memory store - memory_provider = await _create_memory_store(client.project_client) - - agent = Agent( - client=client, - instructions="You are a friendly assistant. Keep your answers brief.", - context_providers=[memory_provider], - # History will be managed by the hosting infrastructure, thus there - # is no need to store history by the service. Learn more at: - # https://developers.openai.com/api/reference/resources/responses/methods/create - default_options={"store": False}, - ) - - server = ResponsesHostServer(agent, store=InMemoryResponseProvider()) - - try: - await server.run_async() - finally: - await _delete_memory_store(client.project_client, memory_provider.memory_store_name) - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/requirements.txt b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/requirements.txt deleted file mode 100644 index f7dc62f3e3..0000000000 --- a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/07_foundry_memory/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -agent-framework -agent-framework-foundry-hosting \ No newline at end of file diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/README.md b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/README.md new file mode 100644 index 0000000000..83999222ad --- /dev/null +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/README.md @@ -0,0 +1,65 @@ +# Hosting agents with Foundry Hosting and the `responses` API + +This folder contains a list of samples that show how to host agents using the `responses` API and deploy them to Foundry Hosting. + +| Sample | Description | +| --- | --- | +| [01_basic](./01_basic) | A basic example of hosting an agent with the `responses` API and carrying on a multi-turn conversation. | +| [02_local_tools](./02_local_tools) | An example of hosting an agent with the `responses` API and local tools including a function tool and a local shell tool. | +| [03_remote_mcp](./03_remote_mcp) | An example of hosting an agent with the `responses` API and remote MCPs, including a GitHub MCP server and a Foundry Toolboox. | +| [04_workflows](./04_workflows) | An example of hosting a workflow with the `responses` API. | + +## Running the server locally + +Navigate to the sample directory and run the following command to start the server: + +```bash +python main.py +``` + +## Interacting with the agent + +There two ways to interact with the agent: sending HTTP requests to the server or using the `azd` CLI: + +### Invoke with `azd` + +```bash +azd ai agent invoke --local "Hi" +``` + +### Sending HTTP requests + +Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example: + +```bash +curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}' +``` + +> See the individual samples for more examples of interacting with the agent. + +## Deploying to a Docker container + +Navigate to the sample directory and build the Docker image: + +```bash +docker build -t hosted-agent-sample . +``` + +Run the container, passing in the required environment variables: + +```bash +docker run -p 8088:8088 \ + -e FOUNDRY_PROJECT_ENDPOINT= \ + -e FOUNDRY_MODEL= \ + hosted-agent-sample +``` + +The server will be available at `http://localhost:8088`. You can send requests using the same `curl` command shown above. + +## Deploying to Foundry + +TODO + +## Using the deployed agent in Agent Framework + +After deploying the agent, you can also try to use the agent in Agent Framework. Refer to the [using_deployed_agent.py](./using_deployed_agent.py) sample for an example of how to do this. diff --git a/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/using_deployed_agent.py b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/using_deployed_agent.py new file mode 100644 index 0000000000..33430caea9 --- /dev/null +++ b/python/samples/05-end-to-end/hosted_agents/foundry_hosted_responses/using_deployed_agent.py @@ -0,0 +1,50 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio + +from agent_framework import Agent, AgentResponse, AgentResponseUpdate, ResponseStream +from agent_framework.openai import OpenAIChatClient +from typing_extensions import Any + +""" +This script demonstrates how to talk to a deployed agent using the OpenAIChatClient. + +Depending on where you have deployed your agent (local or Foundry Hosting), you may +need to change the base_url when initializing the OpenAIChatClient. +""" + + +async def print_streaming_response(streaming_response: ResponseStream[AgentResponseUpdate, AgentResponse[Any]]) -> None: + async for chunk in streaming_response: + if chunk.text: + print(chunk.text, end="", flush=True) + + +async def main() -> None: + agent = Agent(client=OpenAIChatClient(base_url="http://localhost:8088")) + session = agent.create_session() + + # First turn + query = "Hi!" + print(f"User: {query}") + print("Agent: ", end="", flush=True) + streaming_response = agent.run(query, session=session, stream=True) + await print_streaming_response(streaming_response) + + # Second turn + query = "You name is Javis. What can you do?" + print(f"\nUser: {query}") + print("Agent: ", end="", flush=True) + streaming_response = agent.run(query, session=session, stream=True) + await print_streaming_response(streaming_response) + + # Third turn + query = "What is your name?" + print(f"\nUser: {query}") + print("Agent: ", end="", flush=True) + streaming_response = agent.run(query, session=session, stream=True) + await print_streaming_response(streaming_response) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/python/uv.lock b/python/uv.lock index 34f8bd75e2..6d5f6679f9 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -514,9 +514,9 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "agent-framework-core", editable = "packages/core" }, - { name = "azure-ai-agentserver-core", specifier = "==2.0.0a20260410006", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, - { name = "azure-ai-agentserver-invocations", specifier = "==1.0.0a20260410006", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, - { name = "azure-ai-agentserver-responses", specifier = "==1.0.0a20260410006", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, + { name = "azure-ai-agentserver-core", specifier = "==2.0.0a20260414006", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, + { name = "azure-ai-agentserver-invocations", specifier = "==1.0.0a20260414006", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, + { name = "azure-ai-agentserver-responses", specifier = "==1.0.0a20260414006", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, { name = "azure-monitor-opentelemetry-exporter", specifier = ">=1.0.0a1", index = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" }, ] @@ -1036,7 +1036,7 @@ wheels = [ [[package]] name = "azure-ai-agentserver-core" -version = "2.0.0a20260410006" +version = "2.0.0a20260414006" source = { registry = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" } dependencies = [ { name = "azure-monitor-opentelemetry-exporter", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -1046,26 +1046,26 @@ dependencies = [ { name = "opentelemetry-sdk", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "starlette", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-core/2a20260410006/azure_ai_agentserver_core-2.0.0a20260410006.tar.gz", hash = "sha256:834de1dca553ed964819faf5d1c7564e58e03c667c276d04d458c8bb81d2aac4" } +sdist = { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-core/2a20260414006/azure_ai_agentserver_core-2.0.0a20260414006.tar.gz", hash = "sha256:b8d6c5d753650b0eae7468f4dce58faec52baec98ad31744fd5a505c8f3f9267" } wheels = [ - { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-core/2a20260410006/azure_ai_agentserver_core-2.0.0a20260410006-py3-none-any.whl", hash = "sha256:d0fd251635f4b52fbf24dbba916f7e8e173043f0ba9537bb335ab3a1ead1432a" }, + { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-core/2a20260414006/azure_ai_agentserver_core-2.0.0a20260414006-py3-none-any.whl", hash = "sha256:1e816ee611ecdd82d49aee836d6229fae5db1d2321919691afa77de08ad65119" }, ] [[package]] name = "azure-ai-agentserver-invocations" -version = "1.0.0a20260410006" +version = "1.0.0a20260414006" source = { registry = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" } dependencies = [ { name = "azure-ai-agentserver-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-invocations/1a20260410006/azure_ai_agentserver_invocations-1.0.0a20260410006.tar.gz", hash = "sha256:6419d8524fbf5e5a3d94937108f928da70d1406bdfd83cd2e6cba9f5e54f07af" } +sdist = { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-invocations/1a20260414006/azure_ai_agentserver_invocations-1.0.0a20260414006.tar.gz", hash = "sha256:5503f95be679d4245d51d7416e4264fdab471a3bb9db633385cc2d5e950f9df2" } wheels = [ - { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-invocations/1a20260410006/azure_ai_agentserver_invocations-1.0.0a20260410006-py3-none-any.whl", hash = "sha256:5b9e3364d73bc2bb9581540cbf3172624fbc75be7739c95e4d70c83541bde008" }, + { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-invocations/1a20260414006/azure_ai_agentserver_invocations-1.0.0a20260414006-py3-none-any.whl", hash = "sha256:ccae5703c38e25a177075fdfca45fe7cac55c39776ecb0f84c12d7438cfda0cf" }, ] [[package]] name = "azure-ai-agentserver-responses" -version = "1.0.0a20260410006" +version = "1.0.0a20260414006" source = { registry = "https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/" } dependencies = [ { name = "aiohttp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -1073,9 +1073,9 @@ dependencies = [ { name = "azure-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "isodate", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-responses/1a20260410006/azure_ai_agentserver_responses-1.0.0a20260410006.tar.gz", hash = "sha256:795862c6abdd2794be04f685d3995b174364f1280fe7be507bcfa64b6359ec53" } +sdist = { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-responses/1a20260414006/azure_ai_agentserver_responses-1.0.0a20260414006.tar.gz", hash = "sha256:671a93454cae3a0efdc37fc481e4eb45b1356e5339c8d3a8a0a171632ec8cae5" } wheels = [ - { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-responses/1a20260410006/azure_ai_agentserver_responses-1.0.0a20260410006-py3-none-any.whl", hash = "sha256:e877eea7b2bb31c9766c69159e799aff112741eefb178bc3a3c7a07ce0b09dbb" }, + { url = "https://pkgs.dev.azure.com/azure-sdk/29ec6040-b234-4e31-b139-33dc4287b756/_packaging/3572dbf9-b5ef-433b-9137-fc4d7768e7cc/pypi/download/azure-ai-agentserver-responses/1a20260414006/azure_ai_agentserver_responses-1.0.0a20260414006-py3-none-any.whl", hash = "sha256:70a497fd78a1c139568b15ef1035e0ff8cf5eaa2d512772398c866fa19e9d2ef" }, ] [[package]]