Skip to content

Commit 5f316e7

Browse files
committed
Merge branch 'main' of https://github.com/MicrosoftDocs/azure-ai-docs-pr into serverless-deploy-freshness
2 parents 1a81602 + c73743b commit 5f316e7

File tree

332 files changed

+2356
-1068
lines changed

Some content is hidden

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

332 files changed

+2356
-1068
lines changed

.openpublishing.redirection.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,16 @@
519519
"source_path": "articles/machine-learning/how-to-package-models.md",
520520
"redirect_url": "/azure/machine-learning/concept-endpoints",
521521
"redirect_document_id": false
522+
},
523+
{
524+
"source_path": "articles/ai-services/create-account-terraform.md",
525+
"redirect_url": "/azure/ai-foundry/how-to/create-resource-terraform",
526+
"redirect_document_id": false
527+
},
528+
{
529+
"source_path": "articles/ai-services/create-account-bicep.md",
530+
"redirect_url": "/azure/ai-foundry/how-to/create-resource-template",
531+
"redirect_document_id": false
522532
}
523533
]
524534
}

articles/ai-foundry/agents/concepts/capability-hosts.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ Capability hosts follow a hierarchy where more specific configurations override
5050
2. **Account-level capability host** - Provides shared defaults for all projects under the account.
5151
3. **Project-level capability host** - Overrides account-level and service defaults for that specific project.
5252

53+
## Understand capability host constraints
54+
55+
When creating capability hosts, be aware of these important constraints to avoid conflicts:
56+
57+
- **One capability host per scope**: Each account and each project can only have one active capability host. Attempting to create a second capability host with a different name at the same scope will result in a 409 conflict.
58+
59+
- **Configuration updates are not supported**: If you need to change configuration, you must delete the existing capability host and recreate it.
60+
5361

5462
## Recommended setup
5563

@@ -79,6 +87,7 @@ PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{
7987
}
8088
}
8189
```
90+
8291
**Project capability host**
8392

8493
This configuration overrides service defaults and any account-level settings. All agents in this project will use your specified resources:
@@ -134,6 +143,120 @@ DELETE https://management.azure.com/subscriptions/{subscriptionId}/resourceGroup
134143
DELETE https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/projects/{projectName}/capabilityHosts/{name}?api-version=2025-06-01
135144
```
136145

146+
## Troubleshooting
147+
148+
If you're experiencing issues when creating capability hosts, this section provides solutions to the most common problems and errors.
149+
150+
### HTTP 409 Conflict errors
151+
152+
#### Problem: Multiple capability hosts per scope
153+
154+
**Symptoms:** You receive a 409 Conflict error when trying to create a capability host, even though you believe the scope is empty.
155+
156+
**Error message:**
157+
```json
158+
{
159+
"error": {
160+
"code": "Conflict",
161+
"message": "There is an existing Capability Host with name: existing-host, provisioning state: Succeeded for workspace: /subscriptions/.../workspaces/my-workspace, cannot create a new Capability Host with name: new-host for the same ClientId."
162+
}
163+
}
164+
```
165+
166+
**Root cause:** Each account and each project can only have one active capability host. You're trying to create a capability host with a different name when one already exists at the same scope.
167+
168+
**Solution:**
169+
1. **Check existing capability hosts** - Query the scope to see what already exists
170+
2. **Use consistent naming** - Ensure you're using the same name across all requests for the same scope
171+
3. **Review your requirements** - Determine if the existing capability host meets your needs
172+
173+
**Validation steps:**
174+
```http
175+
# For account-level capability hosts
176+
GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/capabilityHosts?api-version=2025-06-01
177+
178+
# For project-level capability hosts
179+
GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/projects/{projectName}/capabilityHosts?api-version=2025-06-01
180+
```
181+
182+
#### Problem: Concurrent operations in progress
183+
184+
**Symptoms:** You receive a 409 Conflict error indicating that another operation is currently running.
185+
186+
**Error message:**
187+
```json
188+
{
189+
"error": {
190+
"code": "Conflict",
191+
"message": "Create: Capability Host my-host is currently in non creating, retry after its complete: /subscriptions/.../workspaces/my-workspace"
192+
}
193+
}
194+
```
195+
196+
**Root cause:** You're trying to create a capability host while another operation (update, delete, modify) is in progress at the same scope.
197+
198+
**Solution:**
199+
1. **Wait for current operation to complete** - Check the status of ongoing operations
200+
2. **Monitor operation progress** - Use the operations API to track completion
201+
3. **Implement retry logic** - Add exponential backoff for temporary conflicts
202+
203+
**Operation monitoring:**
204+
```http
205+
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.CognitiveServices/locations/{location}/operationResults/{operationId}?api-version=2025-06-01
206+
```
207+
208+
### Best practices for conflict prevention
209+
210+
#### 1. Pre-request validation
211+
Always verify the current state before making changes:
212+
- Query existing capability hosts in the target scope
213+
- Check for any ongoing operations
214+
- Understand the current configuration
215+
216+
#### 2. Implement retry logic with exponential backoff
217+
```csharp
218+
try
219+
{
220+
var response = await CreateCapabilityHostAsync(request);
221+
return response;
222+
}
223+
catch (HttpRequestException ex) when (ex.Message.Contains("409"))
224+
{
225+
if (ex.Message.Contains("existing Capability Host with name"))
226+
{
227+
// Handle name conflict - check if existing resource is acceptable
228+
var existing = await GetExistingCapabilityHostAsync();
229+
if (IsAcceptable(existing))
230+
{
231+
return existing; // Use existing resource
232+
}
233+
else
234+
{
235+
throw new InvalidOperationException("Scope already has a capability host with different name");
236+
}
237+
}
238+
else if (ex.Message.Contains("currently in non creating"))
239+
{
240+
// Handle concurrent operation - implement retry with backoff
241+
await Task.Delay(TimeSpan.FromSeconds(30));
242+
return await CreateCapabilityHostAsync(request); // Retry once
243+
}
244+
}
245+
```
246+
247+
#### 3. Understand idempotent behavior
248+
The system supports idempotent create requests:
249+
- **Same name + same configuration** → Returns existing resource (200 OK)
250+
- **Same name + different configuration** → Returns 400 Bad Request
251+
- **Different name** → Returns 409 Conflict
252+
253+
#### 4. Configuration change workflow
254+
Since updates aren't supported, follow this sequence for configuration changes:
255+
1. Delete the existing capability host
256+
2. Wait for deletion to complete
257+
3. Create a new capability host with the desired configuration
258+
259+
137260
## Next steps
138261
- Learn more about the [Standard Agent Setup](standard-agent-setup.md)
139262
- Get started with [Agent Service](../environment-setup.md)

articles/ai-foundry/agents/how-to/tools/azure-ai-search-samples.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,144 @@ curl --request GET \
535535
```
536536

537537
:::zone-end
538+
539+
:::zone pivot="java"
540+
541+
## Code example
542+
543+
```java
544+
package com.example.agents;
545+
546+
import com.azure.ai.agents.persistent.MessagesClient;
547+
import com.azure.ai.agents.persistent.PersistentAgentsAdministrationClient;
548+
import com.azure.ai.agents.persistent.PersistentAgentsClient;
549+
import com.azure.ai.agents.persistent.PersistentAgentsClientBuilder;
550+
import com.azure.ai.agents.persistent.RunsClient;
551+
import com.azure.ai.agents.persistent.ThreadsClient;
552+
import com.azure.ai.agents.persistent.models.AISearchIndexResource;
553+
import com.azure.ai.agents.persistent.models.AzureAISearchToolDefinition;
554+
import com.azure.ai.agents.persistent.models.AzureAISearchToolResource;
555+
import com.azure.ai.agents.persistent.models.CreateAgentOptions;
556+
import com.azure.ai.agents.persistent.models.CreateRunOptions;
557+
import com.azure.ai.agents.persistent.models.MessageImageFileContent;
558+
import com.azure.ai.agents.persistent.models.MessageRole;
559+
import com.azure.ai.agents.persistent.models.MessageTextContent;
560+
import com.azure.ai.agents.persistent.models.PersistentAgent;
561+
import com.azure.ai.agents.persistent.models.PersistentAgentThread;
562+
import com.azure.ai.agents.persistent.models.RunStatus;
563+
import com.azure.ai.agents.persistent.models.ThreadMessage;
564+
import com.azure.ai.agents.persistent.models.ThreadRun;
565+
import com.azure.ai.agents.persistent.models.ToolResources;
566+
import com.azure.ai.agents.persistent.models.MessageContent;
567+
import com.azure.core.http.rest.PagedIterable;
568+
import com.azure.identity.DefaultAzureCredentialBuilder;
569+
570+
import java.net.URL;
571+
import java.io.File;
572+
import java.io.FileNotFoundException;
573+
import java.net.URISyntaxException;
574+
import java.nio.file.Path;
575+
import java.util.Arrays;
576+
577+
public class AgentExample {
578+
579+
public static void main(String[] args) throws FileNotFoundException, URISyntaxException {
580+
581+
// variables for authenticating requests to the agent service
582+
String projectEndpoint = System.getenv("PROJECT_ENDPOINT");
583+
String modelName = System.getenv("MODEL_DEPLOYMENT_NAME");
584+
String aiSearchConnectionId = System.getenv("AZURE_AI_CONNECTION_ID");
585+
String indexName = "my-index";
586+
587+
PersistentAgentsClientBuilder clientBuilder = new PersistentAgentsClientBuilder().endpoint(projectEndpoint)
588+
.credential(new DefaultAzureCredentialBuilder().build());
589+
PersistentAgentsClient agentsClient = clientBuilder.buildClient();
590+
PersistentAgentsAdministrationClient administrationClient = agentsClient.getPersistentAgentsAdministrationClient();
591+
ThreadsClient threadsClient = agentsClient.getThreadsClient();
592+
MessagesClient messagesClient = agentsClient.getMessagesClient();
593+
RunsClient runsClient = agentsClient.getRunsClient();
594+
595+
AISearchIndexResource indexResource = new AISearchIndexResource()
596+
.setIndexConnectionId(aiSearchConnectionId)
597+
.setIndexName(indexName);
598+
ToolResources toolResources = new ToolResources()
599+
.setAzureAISearch(new AzureAISearchToolResource()
600+
.setIndexList(Arrays.asList(indexResource)));
601+
602+
String agentName = "ai_search_example";
603+
CreateAgentOptions createAgentOptions = new CreateAgentOptions(modelName)
604+
.setName(agentName)
605+
.setInstructions("You are a helpful agent")
606+
.setTools(Arrays.asList(new AzureAISearchToolDefinition()))
607+
.setToolResources(toolResources);
608+
PersistentAgent agent = administrationClient.createAgent(createAgentOptions);
609+
610+
PersistentAgentThread thread = threadsClient.createThread();
611+
ThreadMessage createdMessage = messagesClient.createMessage(
612+
thread.getId(),
613+
MessageRole.USER,
614+
"<question about information in search index>");
615+
616+
try {
617+
//run agent
618+
CreateRunOptions createRunOptions = new CreateRunOptions(thread.getId(), agent.getId())
619+
.setAdditionalInstructions("");
620+
ThreadRun threadRun = runsClient.createRun(createRunOptions);
621+
622+
waitForRunCompletion(thread.getId(), threadRun, runsClient);
623+
printRunMessages(messagesClient, thread.getId());
624+
625+
} catch (InterruptedException e) {
626+
throw new RuntimeException(e);
627+
} finally {
628+
//cleanup
629+
threadsClient.deleteThread(thread.getId());
630+
administrationClient.deleteAgent(agent.getId());
631+
}
632+
}
633+
// A helper function to print messages from the agent
634+
public static void printRunMessages(MessagesClient messagesClient, String threadId) {
635+
636+
PagedIterable<ThreadMessage> runMessages = messagesClient.listMessages(threadId);
637+
for (ThreadMessage message : runMessages) {
638+
System.out.print(String.format("%1$s - %2$s : ", message.getCreatedAt(), message.getRole()));
639+
for (MessageContent contentItem : message.getContent()) {
640+
if (contentItem instanceof MessageTextContent) {
641+
System.out.print((((MessageTextContent) contentItem).getText().getValue()));
642+
} else if (contentItem instanceof MessageImageFileContent) {
643+
String imageFileId = (((MessageImageFileContent) contentItem).getImageFile().getFileId());
644+
System.out.print("Image from ID: " + imageFileId);
645+
}
646+
System.out.println();
647+
}
648+
}
649+
}
650+
651+
// a helper function to wait until a run has completed running
652+
public static void waitForRunCompletion(String threadId, ThreadRun threadRun, RunsClient runsClient)
653+
throws InterruptedException {
654+
655+
do {
656+
Thread.sleep(500);
657+
threadRun = runsClient.getRun(threadId, threadRun.getId());
658+
}
659+
while (
660+
threadRun.getStatus() == RunStatus.QUEUED
661+
|| threadRun.getStatus() == RunStatus.IN_PROGRESS
662+
|| threadRun.getStatus() == RunStatus.REQUIRES_ACTION);
663+
664+
if (threadRun.getStatus() == RunStatus.FAILED) {
665+
System.out.println(threadRun.getLastError().getMessage());
666+
}
667+
}
668+
private static Path getFile(String fileName) throws FileNotFoundException, URISyntaxException {
669+
URL resource = AgentExample.class.getClassLoader().getResource(fileName);
670+
if (resource == null) {
671+
throw new FileNotFoundException("File not found");
672+
}
673+
File file = new File(resource.toURI());
674+
return file.toPath();
675+
}
676+
}
677+
```
678+
:::zone-end

articles/ai-foundry/agents/how-to/tools/azure-ai-search.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ services: azure-ai-agent-service
66
manager: nitinme
77
ms.service: azure-ai-agent-service
88
ms.topic: how-to
9-
ms.date: 7/28/2025
9+
ms.date: 08/07/2025
1010
author: aahill
1111
ms.author: aahi
1212
ms.custom: azure-ai-agents
@@ -36,9 +36,9 @@ You can have indexes without a specified search type. By default, the Azure AI S
3636

3737
## Usage support
3838

39-
|Azure AI foundry support | Python SDK | C# SDK | JavaScript SDK | REST API | Basic agent setup | Standard agent setup |
40-
|---------|---------|---------|---------|---------|---------|---------|
41-
| ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
39+
|Azure AI foundry support | Python SDK | C# SDK | JavaScript SDK | Java SDK | REST API | Basic agent setup | Standard agent setup |
40+
|---------|---------|---------|---------|---------|---------|---------|---------|
41+
| ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
4242

4343
## Setup
4444

0 commit comments

Comments
 (0)