Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sdk/ai/azure-ai-projects/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "python",
"TagPrefix": "python/ai/azure-ai-projects",
"Tag": "python/ai/azure-ai-projects_2204ef492a"
"Tag": "python/ai/azure-ai-projects_d20bfd0fdc"
}
2 changes: 1 addition & 1 deletion sdk/ai/azure-ai-projects/dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ opentelemetry-sdk
azure-core-tracing-opentelemetry
azure-monitor-opentelemetry
azure-mgmt-cognitiveservices

jsonref
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@ def print_final_output(response):
final_output += getattr(part, "text", None) or getattr(part, "refusal", None) or "" + "\n"

print(f"Final status: {response.status}")
print(f"Final output: {final_output.strip()}")
print(f"==> Result: {final_output.strip()}")
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
3) AI_SEARCH_PROJECT_CONNECTION_ID - The AI Search project connection ID,
as found in the "Connections" tab in your Microsoft Foundry project.
4) AI_SEARCH_INDEX_NAME - The name of the AI Search index to use for searching.
5) AI_SEARCH_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted.
"""

import os
Expand Down Expand Up @@ -74,7 +75,10 @@
)
print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")

user_input = input("Enter your question (e.g., 'Tell me about mental health services'): \n")
# Get user input from environment variable or prompt
user_input = os.environ.get("AI_SEARCH_USER_INPUT")
if not user_input:
user_input = input("Enter your question (e.g., 'Tell me about mental health services'): \n")

stream_response = openai_client.responses.create(
stream=True,
Expand Down Expand Up @@ -104,7 +108,7 @@
)
elif event.type == "response.completed":
print(f"\nFollow-up completed!")
print(f"Full response: {event.response.output_text}")
print(f"==> Result: {event.response.output_text}")

print("\nCleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@
# Download the generated file if available
if file_id and filename:
file_content = openai_client.containers.files.content.retrieve(file_id=file_id, container_id=container_id)
print(f"File ready for download: {filename}")
with open(filename, "wb") as f:
f.write(file_content.read())
print(f"File {filename} downloaded successfully.")
print(f"File ready for download: {filename}")

# Print result (should contain "file")
print(f"==> Result: file, {filename} downloaded successfully.")
else:
print("No file generated in response")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,12 @@ async def main() -> None:
file_content = await openai_client.containers.files.content.retrieve(
file_id=file_id, container_id=container_id
)
print(f"File ready for download: {filename}")
with open(filename, "wb") as f:
f.write(file_content.read())
print(f"File {filename} downloaded successfully.")
print(f"File ready for download: {filename}")

# Print result (should contain "file")
print(f"==> Result: file, {filename} downloaded successfully.")
else:
print("No file generated in response")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Set these environment variables with your own values:
1) AZURE_AI_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview
page of your Microsoft Foundry portal.
2) AZURE_AI_MODEL_DEPLOYMENT_NAME - The deployment name of the AI model, as found under the "Name" column in
2) (Optional) COMPUTER_USE_MODEL_DEPLOYMENT_NAME - The deployment name of the computer-use-preview model, as found under the "Name" column in
the "Models + endpoints" tab in your Microsoft Foundry project.
"""

Expand Down Expand Up @@ -70,7 +70,7 @@
agent = project_client.agents.create_version(
agent_name="ComputerUseAgent",
definition=PromptAgentDefinition(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
model=os.environ.get("COMPUTER_USE_MODEL_DEPLOYMENT_NAME", "computer-use-preview"),
instructions="""
You are a computer automation assistant.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Set these environment variables with your own values:
1) AZURE_AI_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview
page of your Microsoft Foundry portal.
2) AZURE_AI_MODEL_DEPLOYMENT_NAME - The deployment name of the AI model, as found under the "Name" column in
2) (Optional) COMPUTER_USE_MODEL_DEPLOYMENT_NAME - The deployment name of the computer-use-preview model, as found under the "Name" column in
the "Models + endpoints" tab in your Microsoft Foundry project.
"""

Expand Down Expand Up @@ -72,7 +72,7 @@ async def main():
agent = await project_client.agents.create_version(
agent_name="ComputerUseAgent",
definition=PromptAgentDefinition(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
model=os.environ.get("COMPUTER_USE_MODEL_DEPLOYMENT_NAME", "computer-use-preview"),
instructions="""
You are a computer automation assistant.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@
input="Tell me about Contoso products",
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)
print(f"Response: {response.output_text}")

print(f"==> Result: {response.output_text}")
print("\nCleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
print("Agent deleted")
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
print(f"File Citation - Filename: {annotation.filename}, File ID: {annotation.file_id}")
elif event.type == "response.completed":
print(f"\nFollow-up completed!")
print(f"Full response: {event.response.output_text}")
print(f"==> Result: {event.response.output_text}")

# Clean up resources
print("\n" + "=" * 60)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ async def main() -> None:
print(f"File Citation - Filename: {annotation.filename}, File ID: {annotation.file_id}")
elif event.type == "response.completed":
print(f"\nFollow-up completed!")
print(f"Full response: {event.response.output_text}")
print(f"==> Result: {event.response.output_text}")

# Clean up resources
print("\n" + "=" * 60)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ def get_horoscope(sign: str) -> str:
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)

# The model should be able to give a response!
print("Final output:")
print("\n" + response.output_text)
# Print result (should contain "Tuesday")
print(f"==> Result: {response.output_text}")

print("\nCleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
print("Agent deleted")
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,8 @@ async def main():
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)

# The model should be able to give a response!
print("Final output:")
print("\n" + response.output_text)
# Print result (should contain "Tuesday")
print(f"==> Result: {response.output_text}")


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@
with open(file_path, "wb") as f:
f.write(base64.b64decode(image_data[0]))
# [END download_image]
print(f"Image downloaded and saved to: {file_path}")

# Print result (should contain "file")
print(f"==> Result: Image downloaded and saved to file: {file_path}")

print("\nCleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ async def main():
with open(file_path, "wb") as f:
f.write(base64.b64decode(image_data[0]))

print(f"Image downloaded and saved to: {file_path}")
# Print result (should contain "file")
print(f"==> Result: Image downloaded and saved to file: {file_path}")

print("\nCleaning up...")
await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)

print(f"Response: {response.output_text}")
# Print result (should contain "Azure")
print(f"==> Result: {response.output_text}")

# Clean up resources by deleting the agent version
# This prevents accumulation of unused agent versions in your project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ async def main():
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)

print(f"Response: {response.output_text}")
# Print result (should contain "Azure")
print(f"==> Result: {response.output_text}")

# Clean up resources by deleting the agent version
# This prevents accumulation of unused agent versions in your project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@
input="Use the OpenAPI tool to print out, what is the weather in Seattle, WA today.",
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)
# The response to the question may contain non ASCII letters. To avoid error, encode and re decode them.
print(f"Response created: {response.output_text.encode().decode('ascii', errors='ignore')}")
# Print result (should contain "\u00b0F")
print(f"==> Result: {response.output_text}")

print("\nCleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
the "Models + endpoints" tab in your Microsoft Foundry project.
3) SHAREPOINT_PROJECT_CONNECTION_ID - The SharePoint project connection ID,
as found in the "Connections" tab in your Microsoft Foundry project.
4) SHAREPOINT_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted.
"""

import os
Expand Down Expand Up @@ -67,7 +68,10 @@
)
print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")

user_input = input("Enter your question corresponded to the documents in SharePoint:\n")
# Get user input from environment variable or prompt
user_input = os.environ.get("SHAREPOINT_USER_INPUT")
if not user_input:
user_input = input("Enter your question corresponded to the documents in SharePoint:\n")

# Send initial request that will trigger the SharePoint tool
stream_response = openai_client.responses.create(
Expand Down Expand Up @@ -97,7 +101,7 @@
)
elif event.type == "response.completed":
print(f"\nFollow-up completed!")
print(f"Full response: {event.response.output_text}")
print(f"==> Result: {event.response.output_text}")

print("Cleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
input="Show me the latest London Underground service updates",
extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
)
print(f"Response: {response.output_text}")
print(f"==> Result: {response.output_text}")

print("\nCleaning up...")
project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
Expand Down
9 changes: 9 additions & 0 deletions sdk/ai/azure-ai-projects/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
add_general_regex_sanitizer,
add_body_key_sanitizer,
add_remove_header_sanitizer,
add_general_string_sanitizer,
)

if not load_dotenv(find_dotenv(), override=True):
Expand Down Expand Up @@ -99,13 +100,21 @@ def sanitize_url_paths():

sanitize_url_paths()

# Normalize Content-Type for CSV files in multipart form-data (varies by OS/Python version)
add_general_string_sanitizer(target="Content-Type: text/csv", value="Content-Type: application/vnd.ms-excel")

# Sanitize API key from service response (this includes Application Insights connection string)
add_body_key_sanitizer(json_path="credentials.key", value="sanitized-api-key")

# Sanitize SAS URI from Datasets get credential response
add_body_key_sanitizer(json_path="blobReference.credential.sasUri", value="sanitized-sas-uri")
add_body_key_sanitizer(json_path="blobReferenceForConsumption.credential.sasUri", value="sanitized-sas-uri")

add_body_key_sanitizer(
json_path="$..project_connection_id",
value="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/connections/connector-name",
)

# Remove Stainless headers from OpenAI client requests, since they include platform and OS specific info, which we can't have in recorded requests.
# Here is an example of all the `x-stainless` headers from a Responses call:
# x-stainless-arch: other:amd64
Expand Down
Loading