Skip to content
Open
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
12 changes: 6 additions & 6 deletions sdk/ai/azure-ai-agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ AgentsAsyncClient agentsAsyncClient = new AgentsClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildAgentsAsyncClient();
```
```

The Agents client library has the following sub-clients which group the different operations that can be performed:
The Agents client library has the following sub-clients which group the different operations that can be performed:
- `AgentsClient` / `AgentsAsyncClient`: Perform operations related to agents, such as creating, retrieving, updating, and deleting agents. When `allowPreview(true)` is configured, these clients can also use preview draft versions, hosted-agent sessions, session files, and code package operations.
- `BetaAgentsClient` / `BetaAgentsAsyncClient` **(preview)**: Perform preview agent optimization operations.
- `ResponsesClient` / `ResponsesAsyncClient`: Handle responses operations. See the [OpenAI's Responses API documentation][openai_responses_api_docs] for more information.
Expand Down Expand Up @@ -226,15 +226,15 @@ Remember to adjust your base URL so that your AI Foundry project `endpoint`'s pa

### Prompt Agent

This example will show how to create the context necessary for a `PromptAgent` to work. Note that the way that context is handled in this scenario would allow you to share the context with multiple agents.
This example will show how to create the context necessary for a `PromptAgent` to work. Note that the way that context is handled in this scenario would allow you to share the context with multiple agents.

#### Create an Agent

Creating an Agent can be done like in the following code snippet:

```java com.azure.ai.agents.create_prompt_agent
PromptAgentDefinition promptAgentDefinition = new PromptAgentDefinition("gpt-4o");
AgentVersionDetails agent = agentsClient.createAgentVersion("my-agent", promptAgentDefinition);
AgentVersionDetails agent = agentsClient.createAgentVersion("my-agent", new CreateAgentVersionInput(promptAgentDefinition));
```

This will return an `AgentVersionDetails` which contains the information necessary to create an `AgentReference`. But first it's necessary to setup the `Conversation` and its messages to be able to obtain `Response`s with a centralized context.
Expand Down Expand Up @@ -847,11 +847,11 @@ structuredInputDefinitions.put("userRole",
new StructuredInputDefinition().setDescription("User's role").setRequired(true));

AgentVersionDetails agent = agentsClient.createAgentVersion("structured-input-agent",
new PromptAgentDefinition(model)
new CreateAgentVersionInput(new PromptAgentDefinition(model)
.setInstructions("You are a helpful assistant. "
+ "The user's name is {{userName}} and their role is {{userRole}}. "
+ "Greet them and confirm their details.")
.setStructuredInputs(structuredInputDefinitions));
.setStructuredInputs(structuredInputDefinitions)));
```

#### Create a response with structured input values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
import com.azure.autorest.customization.Customization;
import com.azure.autorest.customization.LibraryCustomization;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
import com.github.javaparser.ast.modules.ModuleDeclaration;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
Expand All @@ -26,12 +29,28 @@ public class AgentsCustomizations extends Customization {

@Override
public void customize(LibraryCustomization libraryCustomization, Logger logger) {
customizeModuleInfo(libraryCustomization);
renameImageGenToolSize(libraryCustomization, logger);
modifyPollingStrategies(libraryCustomization, logger);
customizeTimeZoneModels(libraryCustomization);
annotateBetaClients(libraryCustomization, logger);
annotateBetaFields(libraryCustomization, loadBetaAnnotations(logger), logger);
}

private void customizeModuleInfo(LibraryCustomization customization) {
String fileName = "src/main/java/module-info.java";
CompilationUnit moduleInfo = StaticJavaParser.parse(customization.getRawEditor().getFileContent(fileName));
ModuleDeclaration module = moduleInfo.getModule()
.orElseThrow(() -> new IllegalStateException("Generated module-info.java has no module"));
for (String requiredModule : new String[] { "openai.java.core", "openai.java.client.okhttp" }) {
String directive = "requires " + requiredModule + ";";
if (module.getDirectives().stream().noneMatch(existing -> directive.equals(existing.toString().trim()))) {
module.addDirective(directive);
}
}
customization.getRawEditor().replaceFile(fileName, moduleInfo.toString());
}

private void renameImageGenToolSize(LibraryCustomization customization, Logger logger) {
customization.getClass("com.azure.ai.agents.models", "ImageGenToolSize").customizeAst(ast -> ast.getEnumByName("ImageGenToolSize")
.ifPresent(clazz -> clazz.getEntries().stream()
Expand Down Expand Up @@ -59,6 +78,64 @@ private void modifyPollingStrategies(LibraryCustomization customization, Logger
.ifPresent(clazz -> clazz.addMember(StaticJavaParser.parseMethodDeclaration("@Override public PollResponse<T> poll(PollingContext<T> pollingContext, TypeReference<T> pollResponseType) { return AgentsServicePollUtils.remapStatus(super.poll(pollingContext, pollResponseType)); }"))));
}

private void customizeTimeZoneModels(LibraryCustomization customization) {
for (String className : new String[] { "ApproximateLocation", "WebSearchApproximateLocation" }) {
customization.getClass("com.azure.ai.agents.models", className)
.customizeAst(ast -> customizeTimeZoneModel(ast.getClassByName(className)
.orElseThrow(() -> new IllegalStateException("Generated model " + className + " was not found."))));
}
}

private static void customizeTimeZoneModel(ClassOrInterfaceDeclaration model) {
MethodDeclaration toJson = getSingleMethod(model, "toJson");
String toJsonBody = toJson.getBody()
.orElseThrow(() -> new IllegalStateException(model.getNameAsString() + ".toJson has no body."))
.toString();
String generatedWriter = "jsonWriter.writeJsonField(\"timezone\", this.timezone);";
String timeZoneWriter
= "jsonWriter.writeStringField(\"timezone\", this.timezone != null ? this.timezone.getID() : null);";
if (!toJsonBody.contains(timeZoneWriter)) {
if (!toJsonBody.contains(generatedWriter)) {
throw new IllegalStateException(
model.getNameAsString() + ".toJson no longer uses the expected generated timezone writer.");
}
toJson.setBody(StaticJavaParser.parseBlock(toJsonBody.replace(generatedWriter, timeZoneWriter)));
}

MethodDeclaration fromJson = getSingleMethod(model, "fromJson");
String fromJsonBody = fromJson.getBody()
.orElseThrow(() -> new IllegalStateException(model.getNameAsString() + ".fromJson has no body."))
.toString();
if (!fromJsonBody.contains("parseTimeZone(")) {
String generatedParser = "TimeZone.fromJson(reader)";
if (!fromJsonBody.contains(generatedParser)) {
throw new IllegalStateException(
model.getNameAsString() + ".fromJson no longer uses the expected generated timezone parser.");
}
fromJson.setBody(StaticJavaParser.parseBlock(
fromJsonBody.replace(generatedParser, "parseTimeZone(reader.getString())")));
}

if (model.getMethodsByName("parseTimeZone").isEmpty()) {
model.addMember(StaticJavaParser.parseMethodDeclaration(
"private static TimeZone parseTimeZone(String timezoneId) {"
+ " if (timezoneId == null) { return null; }"
+ " TimeZone timezone = TimeZone.getTimeZone(timezoneId);"
+ " if (\"GMT\".equals(timezone.getID()) && !\"GMT\".equalsIgnoreCase(timezoneId)) { return null; }"
+ " return timezone;"
+ " }"));
}
}

private static MethodDeclaration getSingleMethod(ClassOrInterfaceDeclaration model, String methodName) {
List<MethodDeclaration> methods = model.getMethodsByName(methodName);
if (methods.size() != 1) {
throw new IllegalStateException(
"Expected one " + model.getNameAsString() + "." + methodName + " method, found " + methods.size() + ".");
}
return methods.get(0);
}

private void annotateBetaClients(LibraryCustomization customization, Logger logger) {
customization.getPackage("com.azure.ai.agents")
.listClasses()
Expand Down
Loading