Skip to content

Commit 0a36a6c

Browse files
authored
[Projects] add v2 sample for OpenApi with connection auth (#36689)
### Packages impacted by this PR ### Issues associated with this PR ### Describe the problem that is addressed by this PR ### What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen? ### Are there test cases added in this PR? _(If not, why?)_ ### Provide a list of related PRs _(if any)_ ### Command used to generate this PR:**_(Applicable only to SDK release request PRs)_ ### Checklists - [ ] Added impacted package name to the issue description - [ ] Does this PR needs any fixes in the SDK Generator?** _(If so, create an Issue in the [Autorest/typescript](https://github.com/Azure/autorest.typescript) repository and link it here)_ - [ ] Added a changelog (if necessary)
1 parent 4d94c8c commit 0a36a6c

File tree

6 files changed

+488
-66
lines changed

6 files changed

+488
-66
lines changed

sdk/ai/ai-projects/sample.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ FABRIC_PROJECT_CONNECTION_ID="<fabric project connection id>"
2121
IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME="<image generation model deployment name>"
2222

2323
MCP_PROJECT_CONNECTION_ID="<mcp project connection id>"
24+
TRIPADVISOR_PROJECT_CONNECTION_ID="<tripadvisor project connection id>"
25+
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
/**
5+
* This sample demonstrates how to create an AI agent that uses OpenAPI tools
6+
* authenticated via a project connection. The agent loads the TripAdvisor
7+
* OpenAPI specification from local assets and can invoke the API through the
8+
* configured project connection.
9+
*
10+
* @summary Demonstrates how to create an OpenAPI-enabled agent that uses a project connection for
11+
* authentication and stream responses that include tool invocation details.
12+
*
13+
* @azsdk-weight 100
14+
*/
15+
16+
import { DefaultAzureCredential } from "@azure/identity";
17+
import {
18+
AIProjectClient,
19+
OpenApiAgentTool,
20+
OpenApiFunctionDefinition,
21+
OpenApiProjectConnectionAuthDetails,
22+
} from "@azure/ai-projects";
23+
import * as fs from "fs";
24+
import * as path from "path";
25+
import "dotenv/config";
26+
27+
const projectEndpoint = process.env["AZURE_AI_PROJECT_ENDPOINT"] || "<project endpoint>";
28+
const deploymentName = process.env["AZURE_AI_MODEL_DEPLOYMENT_NAME"] || "<model deployment name>";
29+
const tripAdvisorProjectConnectionId =
30+
process.env["TRIPADVISOR_PROJECT_CONNECTION_ID"] || "<tripadvisor project connection id>";
31+
const tripAdvisorSpecPath = path.resolve(__dirname, "../assets", "tripadvisor_openapi.json");
32+
33+
function loadOpenApiSpec(specPath: string): unknown {
34+
if (!fs.existsSync(specPath)) {
35+
throw new Error(`OpenAPI specification not found at: ${specPath}`);
36+
}
37+
38+
try {
39+
const data = fs.readFileSync(specPath, "utf-8");
40+
return JSON.parse(data);
41+
} catch (error) {
42+
throw new Error(`Failed to read or parse OpenAPI specification at ${specPath}: ${error}`);
43+
}
44+
}
45+
46+
function createTripAdvisorTool(spec: unknown): OpenApiAgentTool {
47+
const auth: OpenApiProjectConnectionAuthDetails = {
48+
type: "project_connection",
49+
security_scheme: {
50+
project_connection_id: tripAdvisorProjectConnectionId,
51+
},
52+
};
53+
54+
const definition: OpenApiFunctionDefinition = {
55+
name: "get_tripadvisor_location_details",
56+
description:
57+
"Fetch TripAdvisor location details, reviews, or photos using the Content API via project connection auth.",
58+
spec,
59+
auth,
60+
};
61+
62+
return {
63+
type: "openapi",
64+
openapi: definition,
65+
};
66+
}
67+
68+
export async function main(): Promise<void> {
69+
console.log("Loading TripAdvisor OpenAPI specification from assets directory...");
70+
const tripAdvisorSpec = loadOpenApiSpec(tripAdvisorSpecPath);
71+
72+
const project = new AIProjectClient(projectEndpoint, new DefaultAzureCredential());
73+
const openAIClient = await project.getOpenAIClient();
74+
75+
console.log("Creating agent with OpenAPI project-connection tool...");
76+
77+
const agent = await project.agents.createVersion("MyOpenApiConnectionAgent", {
78+
kind: "prompt",
79+
model: deploymentName,
80+
instructions:
81+
"You are a travel assistant that consults the TripAdvisor Content API via project connection to answer user questions about locations.",
82+
tools: [createTripAdvisorTool(tripAdvisorSpec)],
83+
});
84+
console.log(`Agent created (id: ${agent.id}, name: ${agent.name}, version: ${agent.version})`);
85+
86+
console.log("\nSending request to TripAdvisor OpenAPI agent with streaming...");
87+
const streamResponse = await openAIClient.responses.create(
88+
{
89+
input:
90+
"Provide a quick overview of the TripAdvisor location 293919 including its name, rating, and review count.",
91+
stream: true,
92+
},
93+
{
94+
body: {
95+
agent: { name: agent.name, type: "agent_reference" },
96+
tool_choice: "required",
97+
},
98+
},
99+
);
100+
101+
// Process the streaming response
102+
for await (const event of streamResponse) {
103+
if (event.type === "response.created") {
104+
console.log(`Follow-up response created with ID: ${event.response.id}`);
105+
} else if (event.type === "response.output_text.delta") {
106+
process.stdout.write(event.delta);
107+
} else if (event.type === "response.output_text.done") {
108+
console.log("\n\nFollow-up response done!");
109+
} else if (event.type === "response.output_item.done") {
110+
const item = event.item as any;
111+
if (item.type === "message") {
112+
const content = item.content?.[item.content.length - 1];
113+
if (content?.type === "output_text" && content.annotations) {
114+
for (const annotation of content.annotations) {
115+
if (annotation.type === "url_citation") {
116+
console.log(
117+
`URL Citation: ${annotation.url}, Start index: ${annotation.start_index}, End index: ${annotation.end_index}`,
118+
);
119+
}
120+
}
121+
}
122+
} else if (item.type === "tool_call") {
123+
console.log(`Tool call completed: ${item.name ?? "unknown"}`);
124+
}
125+
} else if (event.type === "response.completed") {
126+
console.log("\nFollow-up completed!");
127+
}
128+
}
129+
130+
// Clean up resources by deleting the agent version
131+
// This prevents accumulation of unused resources in your project
132+
console.log("\nCleaning up resources...");
133+
await project.agents.deleteVersion(agent.name, agent.version);
134+
console.log("Agent deleted");
135+
136+
console.log("\nTripAdvisor OpenAPI agent sample completed!");
137+
}
138+
139+
main().catch((err) => {
140+
console.error("The sample encountered an error:", err);
141+
});

0 commit comments

Comments
 (0)