c218067646
* Bump uv from 0.11.28 to 0.11.29 in /python Bumps [uv](https://github.com/astral-sh/uv) from 0.11.28 to 0.11.29. - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/uv/compare/0.11.28...0.11.29) --- updated-dependencies: - dependency-name: uv dependency-version: 0.11.29 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump zuban from 0.8.2 to 0.9.0 in /python Bumps [zuban](https://github.com/zubanls/zubanls-python) from 0.8.2 to 0.9.0. - [Release notes](https://github.com/zubanls/zubanls-python/releases) - [Commits](https://github.com/zubanls/zubanls-python/compare/v0.8.2...v0.9.0) --- updated-dependencies: - dependency-name: zuban dependency-version: 0.9.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * PR #7146: Bump ty from 0.0.55 to 0.0.60 in /python * Bump ruff from 0.15.20 to 0.15.22 in /python Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.20 to 0.15.22. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.15.20...0.15.22) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.15.21 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump mypy from 2.2.0 to 2.3.0 in /python Bumps [mypy](https://github.com/python/mypy) from 2.2.0 to 2.3.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v2.2.0...v2.3.0) --- updated-dependencies: - dependency-name: mypy dependency-version: 2.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump prek from 0.4.8 to 0.4.10 in /python Bumps [prek](https://github.com/j178/prek) from 0.4.8 to 0.4.10. - [Release notes](https://github.com/j178/prek/releases) - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md) - [Commits](https://github.com/j178/prek/compare/v0.4.8...v0.4.10) --- updated-dependencies: - dependency-name: prek dependency-version: 0.4.10 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump azure-ai-projects from 2.2.0 to 2.3.0 in /python Bumps azure-ai-projects from 2.2.0 to 2.3.0. --- updated-dependencies: - dependency-name: azure-ai-projects dependency-version: 2.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump types-python-dateutil in /python Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.9.0.20260518 to 2.9.0.20260716. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-python-dateutil dependency-version: 2.9.0.20260716 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump mypy from 2.2.0 to 2.3.0 in /python Bumps [mypy](https://github.com/python/mypy) from 2.2.0 to 2.3.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v2.2.0...v2.3.0) --- updated-dependencies: - dependency-name: mypy dependency-version: 2.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump botocore from 1.43.45 to 1.43.49 in /python Bumps [botocore](https://github.com/boto/botocore) from 1.43.45 to 1.43.49. - [Commits](https://github.com/boto/botocore/compare/1.43.45...1.43.49) --- updated-dependencies: - dependency-name: botocore dependency-version: 1.43.49 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * PRs #7144/#7147: Align lab uv and ruff pins * Regenerate lockfile for Python Dependabot PRs #7144-#7153 * Python: Support azure-ai-projects 2.3 session operations (#7150) * Python: Apply Ruff 0.15.22 suppression updates (#7147) * Python: Update tests for ty 0.0.60 (#7146) * Python: Update Foundry samples for azure-ai-projects 2.3 (#7150) * Python: Address dependency rollup review comments --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
155 lines
5.7 KiB
Python
155 lines
5.7 KiB
Python
# Copyright (c) Microsoft. All rights reserved.
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import os
|
|
from collections.abc import Mapping
|
|
from typing import Any, cast
|
|
|
|
from agent_framework import AgentSession
|
|
from agent_framework.foundry import FoundryAgent
|
|
from azure.ai.projects.aio import AIProjectClient
|
|
from azure.ai.projects.models import VersionRefIndicator
|
|
from azure.identity.aio import AzureCliCredential
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
"""
|
|
This sample demonstrates how to connect to the deployed basic Foundry agent with
|
|
`FoundryAgent`.
|
|
|
|
The sample uses environment variables for configuration, which can be set in a .env file or in the environment directly:
|
|
Environment variables:
|
|
FOUNDRY_PROJECT_ENDPOINT: Microsoft Foundry project endpoint.
|
|
FOUNDRY_AGENT_NAME: Hosted agent name.
|
|
FOUNDRY_AGENT_VERSION: Hosted agent version. Optional, defaults to latest if not specified.
|
|
|
|
After you deploy one of the agents in this directory, you can run this sample
|
|
to connect to it and have a conversation.
|
|
|
|
Note: The `allow_preview=True` flag is required to connect to the new hosted
|
|
agents, as this is a preview feature in Foundry.
|
|
|
|
"""
|
|
|
|
|
|
def get_hosted_session_agents(project_client: AIProjectClient) -> Any:
|
|
"""Return the hosted-session operations for azure-ai-projects 2.2 or 2.3."""
|
|
session_agents = cast(Any, project_client.agents)
|
|
if hasattr(session_agents, "create_session"):
|
|
return session_agents
|
|
return cast(Any, project_client.beta.agents)
|
|
|
|
|
|
async def create_hosted_agent_session(
|
|
*,
|
|
agent: FoundryAgent,
|
|
project_client: AIProjectClient,
|
|
agent_name: str,
|
|
agent_version: str | None,
|
|
isolation_key: str,
|
|
) -> AgentSession:
|
|
"""Create a hosted-agent service session and wrap it in an AgentSession."""
|
|
create_session_kwargs: dict[str, Any] = {
|
|
"agent_name": agent_name,
|
|
"isolation_key": isolation_key,
|
|
}
|
|
resolved_agent_version = agent_version
|
|
if resolved_agent_version is None:
|
|
agent_details = await cast(Any, project_client.beta.agents).get( # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType]
|
|
agent_name=agent_name
|
|
)
|
|
versions = getattr(agent_details, "versions", None)
|
|
if not isinstance(versions, Mapping):
|
|
raise ValueError("Hosted agent details did not include a versions mapping.")
|
|
latest_version = getattr(cast(Any, versions.get("latest")), "version", None)
|
|
if not isinstance(latest_version, str) or not latest_version:
|
|
raise ValueError("Hosted agent details did not include a latest version string.")
|
|
resolved_agent_version = latest_version
|
|
|
|
create_session_kwargs["version_indicator"] = VersionRefIndicator(agent_version=resolved_agent_version)
|
|
service_session = await get_hosted_session_agents(project_client).create_session(**create_session_kwargs)
|
|
agent_session_id = getattr(service_session, "agent_session_id", None)
|
|
if not isinstance(agent_session_id, str) or not agent_session_id:
|
|
raise ValueError("Hosted agent session creation did not return a non-empty agent_session_id.")
|
|
|
|
return agent.get_session(agent_session_id)
|
|
|
|
|
|
async def main() -> None:
|
|
credential = AzureCliCredential()
|
|
project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
|
|
agent_name = os.environ["FOUNDRY_AGENT_NAME"]
|
|
agent_version = os.getenv("FOUNDRY_AGENT_VERSION")
|
|
isolation_key = "my-isolation-key"
|
|
|
|
project_client = AIProjectClient(
|
|
endpoint=project_endpoint,
|
|
credential=credential,
|
|
allow_preview=True,
|
|
)
|
|
async with (
|
|
project_client,
|
|
FoundryAgent(
|
|
project_client=project_client,
|
|
agent_name=agent_name,
|
|
agent_version=agent_version,
|
|
allow_preview=True,
|
|
) as agent,
|
|
):
|
|
session = await create_hosted_agent_session(
|
|
agent=agent,
|
|
project_client=project_client,
|
|
agent_name=agent_name,
|
|
agent_version=agent_version,
|
|
isolation_key=isolation_key,
|
|
)
|
|
|
|
try:
|
|
# 1. Send the first turn.
|
|
query = "Hi!"
|
|
print(f"User: {query}")
|
|
print("Agent: ", end="", flush=True)
|
|
async for chunk in agent.run(query, session=session, stream=True):
|
|
if chunk.text:
|
|
print(chunk.text, end="", flush=True)
|
|
|
|
# 2. Continue the conversation with the same deployed agent session.
|
|
query = "Your name is Javis. What can you do?"
|
|
print(f"\nUser: {query}")
|
|
print("Agent: ", end="", flush=True)
|
|
async for chunk in agent.run(query, session=session, stream=True):
|
|
if chunk.text:
|
|
print(chunk.text, end="", flush=True)
|
|
|
|
# 3. Ask a follow-up question in the same session.
|
|
query = "What is your name?"
|
|
print(f"\nUser: {query}")
|
|
print("Agent: ", end="", flush=True)
|
|
async for chunk in agent.run(query, session=session, stream=True):
|
|
if chunk.text:
|
|
print(chunk.text, end="", flush=True)
|
|
finally:
|
|
if isinstance(session.service_session_id, str):
|
|
await get_hosted_session_agents(project_client).delete_session(
|
|
agent_name=agent_name,
|
|
session_id=session.service_session_id,
|
|
isolation_key=isolation_key,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|
|
|
|
"""
|
|
Sample output:
|
|
User: Hi!
|
|
Agent: Hello! How can I help you today?
|
|
User: Your name is Javis. What can you do?
|
|
Agent: I can answer questions and help with tasks using the instructions configured on the deployed agent.
|
|
User: What is your name?
|
|
Agent: My name is Javis.
|
|
"""
|