Skip to content

Commit 2b5cb05

Browse files
authored
Beta 9 release of Python Azure AI Projects SDK (#40280)
1 parent 26d6821 commit 2b5cb05

File tree

59 files changed

+3398
-888
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+3398
-888
lines changed

.vscode/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@
377377
"prebuilts",
378378
"premf",
379379
"prevsnapshot",
380+
"prompty",
380381
"pschema",
381382
"PSECRET",
382383
"pydantic",

sdk/ai/azure-ai-projects/CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Release History
22

3+
## 1.0.0b9 (2025-04-16)
4+
5+
### Features added
6+
7+
* Utilities to load prompt template strings and Prompty file content
8+
* Added BingCustomSearchTool class with sample
9+
* Added list_threads API to agents namespace
10+
* Added image input support for agents create_message
11+
12+
### Sample updates
13+
14+
* Added `project_client.agents.enable_auto_function_calls(toolset=toolset)` to all samples that has `toolcalls` executed by `azure-ai-project` SDK
15+
* New BingCustomSearchTool sample
16+
* New samples added for image input from url, file and base64
17+
18+
### Breaking Changes
19+
20+
Redesigned automatic function calls because agents retrieved by `update_agent` and `get_agent` do not support them. With the new design, the toolset parameter in `create_agent` no longer executes toolcalls automatically during `create_and_process_run` or `create_stream`. To retain this behavior, call `enable_auto_function_calls` without additional changes.
21+
322
## 1.0.0b8 (2025-03-28)
423

524
### Features added

sdk/ai/azure-ai-projects/MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ include azure/ai/projects/py.typed
44
recursive-include tests *.py
55
recursive-include samples *.py *.md
66
include azure/__init__.py
7-
include azure/ai/__init__.py
7+
include azure/ai/__init__.py

sdk/ai/azure-ai-projects/README.md

Lines changed: 117 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ To report an issue with the client library, or request additional features, plea
5252
- [Create message](#create-message) with:
5353
- [File search attachment](#create-message-with-file-search-attachment)
5454
- [Code interpreter attachment](#create-message-with-code-interpreter-attachment)
55+
- [Create Message with Image Inputs](#create-message-with-image-inputs)
5556
- [Execute Run, Run_and_Process, or Stream](#create-run-run_and_process-or-stream)
5657
- [Retrieve message](#retrieve-message)
5758
- [Retrieve file](#retrieve-file)
@@ -280,6 +281,9 @@ toolset = ToolSet()
280281
toolset.add(functions)
281282
toolset.add(code_interpreter)
282283

284+
# To enable tool calls executed automatically
285+
project_client.agents.enable_auto_function_calls(toolset=toolset)
286+
283287
agent = project_client.agents.create_agent(
284288
model=os.environ["MODEL_DEPLOYMENT_NAME"],
285289
name="my-assistant",
@@ -290,7 +294,7 @@ agent = project_client.agents.create_agent(
290294

291295
<!-- END SNIPPET -->
292296

293-
Also notices that if you use asynchronous client, you use `AsyncToolSet` instead. Additional information related to `AsyncFunctionTool` be discussed in the later sections.
297+
Also notice that if you use the asynchronous client, use `AsyncToolSet` instead. Additional information related to `AsyncFunctionTool` be discussed in the later sections.
294298

295299
Here is an example to use `tools` and `tool_resources`:
296300
<!-- SNIPPET:sample_agents_vector_store_batch_file_search.create_agent_with_tools_and_tool_resources -->
@@ -463,11 +467,7 @@ print(conn_id)
463467

464468
# Initialize agent AI search tool and add the search index connection id
465469
ai_search = AzureAISearchTool(
466-
index_connection_id=conn_id,
467-
index_name="sample_index",
468-
query_type=AzureAISearchQueryType.SIMPLE,
469-
top_k=3,
470-
filter=""
470+
index_connection_id=conn_id, index_name="sample_index", query_type=AzureAISearchQueryType.SIMPLE, top_k=3, filter=""
471471
)
472472

473473
# Create agent with AI search tool and process assistant run
@@ -513,12 +513,7 @@ for message in messages.data:
513513

514514
#### Create Agent with Function Call
515515

516-
You can enhance your Agents by defining callback functions as function tools. These can be provided to `create_agent` via either the `toolset` parameter or the combination of `tools` and `tool_resources`. Here are the distinctions:
517-
518-
- `toolset`: When using the `toolset` parameter, you provide not only the function definitions and descriptions but also their implementations. The SDK will execute these functions within `create_and_run_process` or `streaming` . These functions will be invoked based on their definitions.
519-
- `tools` and `tool_resources`: When using the `tools` and `tool_resources` parameters, only the function definitions and descriptions are provided to `create_agent`, without the implementations. The `Run` or `event handler of stream` will raise a `requires_action` status based on the function definitions. Your code must handle this status and call the appropriate functions.
520-
521-
For more details about calling functions by code, refer to [`sample_agents_stream_eventhandler_with_functions.py`](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/samples/agents/sample_agents_stream_eventhandler_with_functions.py) and [`sample_agents_functions.py`](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/samples/agents/sample_agents_functions.py).
516+
You can enhance your Agents by defining callback functions as function tools. These can be provided to `create_agent` via either the `toolset` parameter or the combination of `tools` and `tool_resources`.
522517

523518
For more details about requirements and specification of functions, refer to [Function Tool Specifications](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/FunctionTool.md)
524519

@@ -529,6 +524,7 @@ Here is an example to use [user functions](https://github.com/Azure/azure-sdk-fo
529524
functions = FunctionTool(user_functions)
530525
toolset = ToolSet()
531526
toolset.add(functions)
527+
project_client.agents.enable_auto_function_calls(toolset=toolset)
532528

533529
agent = project_client.agents.create_agent(
534530
model=os.environ["MODEL_DEPLOYMENT_NAME"],
@@ -553,6 +549,7 @@ functions = AsyncFunctionTool(user_async_functions)
553549

554550
toolset = AsyncToolSet()
555551
toolset.add(functions)
552+
project_client.agents.enable_auto_function_calls(toolset=toolset)
556553

557554
agent = await project_client.agents.create_agent(
558555
model=os.environ["MODEL_DEPLOYMENT_NAME"],
@@ -564,6 +561,9 @@ agent = await project_client.agents.create_agent(
564561

565562
<!-- END SNIPPET -->
566563

564+
Notice that if `enable_auto_function_calls` is called, the SDK will invoke the functions automatically during `create_and_process_run` or streaming. If you prefer to execute them manually, refer to [`sample_agents_stream_eventhandler_with_functions.py`](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/samples/agents/sample_agents_stream_eventhandler_with_functions.py) or
565+
[`sample_agents_functions.py`](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/samples/agents/sample_agents_functions.py)
566+
567567
#### Create Agent With Azure Function Call
568568

569569
The AI agent leverages Azure Functions triggered asynchronously via Azure Storage Queues. To enable the agent to perform Azure Function calls, you must set up the corresponding `AzureFunctionTool`, specifying input and output queues as well as parameter definitions.
@@ -610,7 +610,6 @@ agent = project_client.agents.create_agent(
610610

611611
Currently, the Azure Function integration for the AI Agent has the following limitations:
612612

613-
- Azure Functions integration is available **only for non-streaming scenarios**.
614613
- Supported trigger for Azure Function is currently limited to **Queue triggers** only.
615614
HTTP or other trigger types and streaming responses are not supported at this time.
616615

@@ -793,10 +792,17 @@ auth = OpenApiAnonymousAuthDetails()
793792

794793
# Initialize agent OpenApi tool using the read in OpenAPI spec
795794
openapi_tool = OpenApiTool(
796-
name="get_weather", spec=openapi_weather, description="Retrieve weather information for a location", auth=auth
795+
name="get_weather",
796+
spec=openapi_weather,
797+
description="Retrieve weather information for a location",
798+
auth=auth,
799+
default_parameters=["format"],
797800
)
798801
openapi_tool.add_definition(
799-
name="get_countries", spec=openapi_countries, description="Retrieve a list of countries", auth=auth
802+
name="get_countries",
803+
spec=openapi_countries,
804+
description="Retrieve a list of countries",
805+
auth=auth,
800806
)
801807

802808
# Create agent with OpenApi tool and process assistant run
@@ -885,6 +891,19 @@ thread = project_client.agents.create_thread(tool_resources=file_search.resource
885891
```
886892

887893
<!-- END SNIPPET -->
894+
895+
#### List Threads
896+
897+
To list all threads attached to a given agent, use the list_threads API:
898+
899+
<!-- SNIPPET:sample_agents_basics.list_threads -->
900+
901+
```python
902+
threads = project_client.agents.list_threads()
903+
```
904+
905+
<!-- END SNIPPET -->
906+
888907
#### Create Message
889908

890909
To create a message for assistant to process, you pass `user` as `role` and a question as `content`:
@@ -966,6 +985,88 @@ message = project_client.agents.create_message(
966985

967986
<!-- END SNIPPET -->
968987

988+
#### Create Message with Image Inputs
989+
990+
You can send messages to Azure agents with image inputs in following ways:
991+
992+
- **Using an image stored as a uploaded file**
993+
- **Using a public image accessible via URL**
994+
- **Using a base64 encoded image string**
995+
996+
The following examples demonstrate each method:
997+
998+
##### Create message using uploaded image file
999+
1000+
```python
1001+
# Upload the local image file
1002+
image_file = project_client.agents.upload_file_and_poll(file_path="image_file.png", purpose="assistants")
1003+
1004+
# Construct content using uploaded image
1005+
file_param = MessageImageFileParam(file_id=image_file.id, detail="high")
1006+
content_blocks = [
1007+
MessageInputTextBlock(text="Hello, what is in the image?"),
1008+
MessageInputImageFileBlock(image_file=file_param),
1009+
]
1010+
1011+
# Create the message
1012+
message = project_client.agents.create_message(
1013+
thread_id=thread.id,
1014+
role="user",
1015+
content=content_blocks
1016+
)
1017+
```
1018+
1019+
##### Create message with an image URL input
1020+
1021+
```python
1022+
# Specify the public image URL
1023+
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
1024+
1025+
# Create content directly referencing image URL
1026+
url_param = MessageImageUrlParam(url=image_url, detail="high")
1027+
content_blocks = [
1028+
MessageInputTextBlock(text="Hello, what is in the image?"),
1029+
MessageInputImageUrlBlock(image_url=url_param),
1030+
]
1031+
1032+
# Create the message
1033+
message = project_client.agents.create_message(
1034+
thread_id=thread.id,
1035+
role="user",
1036+
content=content_blocks
1037+
)
1038+
```
1039+
1040+
##### Create message with base64-encoded image input
1041+
1042+
```python
1043+
import base64
1044+
1045+
def image_file_to_base64(path: str) -> str:
1046+
with open(path, "rb") as f:
1047+
return base64.b64encode(f.read()).decode("utf-8")
1048+
1049+
# Convert your image file to base64 format
1050+
image_base64 = image_file_to_base64("image_file.png")
1051+
1052+
# Prepare the data URL
1053+
img_data_url = f"data:image/png;base64,{image_base64}"
1054+
1055+
# Use base64 encoded string as image URL parameter
1056+
url_param = MessageImageUrlParam(url=img_data_url, detail="high")
1057+
content_blocks = [
1058+
MessageInputTextBlock(text="Hello, what is in the image?"),
1059+
MessageInputImageUrlBlock(image_url=url_param),
1060+
]
1061+
1062+
# Create the message
1063+
message = project_client.agents.create_message(
1064+
thread_id=thread.id,
1065+
role="user",
1066+
content=content_blocks
1067+
)
1068+
```
1069+
9691070
#### Create Run, Run_and_Process, or Stream
9701071

9711072
To process your message, you can use `create_run`, `create_and_process_run`, or `create_stream`.
@@ -988,7 +1089,7 @@ while run.status in ["queued", "in_progress", "requires_action"]:
9881089

9891090
<!-- END SNIPPET -->
9901091

991-
To have the SDK poll on your behalf and call `function tools`, use the `create_and_process_run` method. Note that `function tools` will only be invoked if they are provided as `toolset` during the `create_agent` call.
1092+
To have the SDK poll on your behalf and call `function tools`, use the `create_and_process_run` method.
9921093

9931094
Here is an example:
9941095

0 commit comments

Comments
 (0)