Skip to content

Commit 904565b

Browse files
author
Jarno Hakulinen
authored
Jhakulin/image input assistants (Azure#49395)
* Image input support for agents
1 parent c8a0871 commit 904565b

File tree

53 files changed

+3651
-104
lines changed

Some content is hidden

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

53 files changed

+3651
-104
lines changed

sdk/ai/Azure.AI.Projects/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
## 1.0.0-beta.7 (Unreleased)
44

55
### Features Added
6+
* Added image input support for agents create message
7+
* Added list threads support for agents
68

79
### Breaking Changes
810

911
### Bugs Fixed
1012

11-
### Other Changes
13+
### Sample Updates
14+
* New samples added for image input from url and file.
1215

1316
## 1.0.0-beta.6 (2025-03-28)
1417

sdk/ai/Azure.AI.Projects/api/Azure.AI.Projects.net8.0.cs

Lines changed: 126 additions & 2 deletions
Large diffs are not rendered by default.

sdk/ai/Azure.AI.Projects/api/Azure.AI.Projects.netstandard2.0.cs

Lines changed: 126 additions & 2 deletions
Large diffs are not rendered by default.
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Sample using agents with Image URL as an input.
2+
3+
This sample demonstrates examples of sending an image URL (along with optional text) as a structured content block in a single message. The examples shows how to create an agent, open a thread, post content blocks combining text and image inputs, and then run the agent to see how it interprets the multimedia input.
4+
5+
1. Create an agent.
6+
7+
Synchronous sample:
8+
```C# Snippet:ImageUrlInMessageCreateAgent_Sync
9+
Agent agent = client.CreateAgent(
10+
model: modelDeploymentName,
11+
name: "Image Understanding Agent",
12+
instructions: "You are an image-understanding assistant. Analyze images and provide textual descriptions."
13+
);
14+
```
15+
16+
Asynchronous sample:
17+
```C# Snippet:ImageUrlInMessageCreateAgent
18+
Agent agent = await client.CreateAgentAsync(
19+
model: modelDeploymentName,
20+
name: "Image Understanding Agent",
21+
instructions: "You are an image-understanding assistant. Analyze images and provide textual descriptions."
22+
);
23+
```
24+
25+
2. Create a thread
26+
27+
Synchronous sample:
28+
```C# Snippet:ImageUrlInMessageCreateThread_Sync
29+
AgentThread thread = client.CreateThread();
30+
```
31+
32+
Asynchronous sample:
33+
```C# Snippet:ImageUrlInMessageCreateThread
34+
AgentThread thread = await client.CreateThreadAsync();
35+
```
36+
37+
3. Create a message using multiple content blocks. Here we combine a short text and an image URL in a single user message.
38+
39+
Synchronous sample:
40+
```C# Snippet:ImageUrlInMessageCreateMessage_Sync
41+
MessageImageUrlParam imageUrlParam = new MessageImageUrlParam(
42+
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"
43+
);
44+
imageUrlParam.Detail = ImageDetailLevel.High;
45+
46+
var contentBlocks = new List<MessageInputContentBlock>
47+
{
48+
new MessageInputTextBlock("Could you describe this image?"),
49+
new MessageInputImageUrlBlock(imageUrlParam)
50+
};
51+
52+
ThreadMessage imageMessage = client.CreateMessage(
53+
threadId: thread.Id,
54+
role: MessageRole.User,
55+
contentBlocks: contentBlocks
56+
);
57+
```
58+
59+
Asynchronous sample:
60+
```C# Snippet:ImageUrlInMessageCreateMessage
61+
MessageImageUrlParam imageUrlParam = new MessageImageUrlParam(
62+
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"
63+
);
64+
imageUrlParam.Detail = ImageDetailLevel.High;
65+
var contentBlocks = new List<MessageInputContentBlock>
66+
{
67+
new MessageInputTextBlock("Could you describe this image?"),
68+
new MessageInputImageUrlBlock(imageUrlParam)
69+
};
70+
71+
ThreadMessage imageMessage = await client.CreateMessageAsync(
72+
threadId: thread.Id,
73+
role: MessageRole.User,
74+
contentBlocks: contentBlocks
75+
);
76+
```
77+
78+
4. Run the agent against the thread that now has an image to analyze.
79+
80+
Synchronous sample:
81+
```C# Snippet:ImageUrlInMessageCreateRun_Sync
82+
ThreadRun run = client.CreateRun(
83+
threadId: thread.Id,
84+
assistantId: agent.Id
85+
);
86+
```
87+
88+
Asynchronous sample:
89+
```C# Snippet:ImageUrlInMessageCreateRun
90+
ThreadRun run = await client.CreateRunAsync(
91+
threadId: thread.Id,
92+
assistantId: agent.Id
93+
);
94+
```
95+
96+
5. Wait for the run to complete.
97+
98+
99+
Synchronous sample:
100+
```C# Snippet:ImageUrlInMessageWaitForRun_Sync
101+
do
102+
{
103+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
104+
run = client.GetRun(thread.Id, run.Id);
105+
}
106+
while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);
107+
108+
if (run.Status != RunStatus.Completed)
109+
{
110+
throw new InvalidOperationException($"Run failed or was canceled: {run.LastError?.Message}");
111+
}
112+
```
113+
114+
Asynchronous sample:
115+
```C# Snippet:ImageUrlInMessageWaitForRun
116+
do
117+
{
118+
await Task.Delay(TimeSpan.FromMilliseconds(500));
119+
run = await client.GetRunAsync(thread.Id, run.Id);
120+
}
121+
while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);
122+
123+
if (run.Status != RunStatus.Completed)
124+
{
125+
throw new InvalidOperationException($"Run failed or was canceled: {run.LastError?.Message}");
126+
}
127+
```
128+
129+
6. Retrieve messages (including how the agent responds) and print their contents.
130+
131+
Synchronous sample:
132+
```C# Snippet:ImageUrlInMessageReview_Sync
133+
PageableList<ThreadMessage> messages = client.GetMessages(thread.Id);
134+
135+
foreach (ThreadMessage msg in messages)
136+
{
137+
Console.WriteLine($"{msg.CreatedAt:yyyy-MM-dd HH:mm:ss} - {msg.Role,10}:");
138+
139+
foreach (MessageContent content in msg.ContentItems)
140+
{
141+
switch (content)
142+
{
143+
case MessageTextContent textItem:
144+
Console.WriteLine($" Text: {textItem.Text}");
145+
break;
146+
147+
case MessageImageFileContent fileItem:
148+
Console.WriteLine($" Image File (internal ID): {fileItem.FileId}");
149+
break;
150+
}
151+
}
152+
}
153+
```
154+
155+
Asynchronous sample:
156+
```C# Snippet:ImageUrlInMessageReview
157+
PageableList<ThreadMessage> messages = await client.GetMessagesAsync(thread.Id);
158+
159+
foreach (ThreadMessage msg in messages)
160+
{
161+
Console.WriteLine($"{msg.CreatedAt:yyyy-MM-dd HH:mm:ss} - {msg.Role,10}:");
162+
163+
foreach (MessageContent content in msg.ContentItems)
164+
{
165+
switch (content)
166+
{
167+
case MessageTextContent textItem:
168+
Console.WriteLine($" Text: {textItem.Text}");
169+
break;
170+
171+
case MessageImageFileContent fileItem:
172+
Console.WriteLine($" Image File (internal ID): {fileItem.FileId}");
173+
break;
174+
}
175+
}
176+
}
177+
```
178+
179+
7. Finally, we delete all the resources, we have created in this sample.
180+
181+
Synchronous sample:
182+
```C# Snippet:ImageUrlInMessageCleanup_Sync
183+
client.DeleteThread(thread.Id);
184+
client.DeleteAgent(agent.Id);
185+
```
186+
187+
Asynchronous sample:
188+
```C# Snippet:ImageUrlInMessageCleanup
189+
await client.DeleteThreadAsync(thread.Id);
190+
await client.DeleteAgentAsync(agent.Id);
191+
```

0 commit comments

Comments
 (0)