@azure/ai-agents 1.0.0-alpha.20250507.2 → 1.0.0-alpha.20250514.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +233 -303
  2. package/dist/browser/api/agentsContext.d.ts.map +1 -1
  3. package/dist/browser/api/agentsContext.js +7 -19
  4. package/dist/browser/api/agentsContext.js.map +1 -1
  5. package/dist/browser/models/models.d.ts +1 -1
  6. package/dist/browser/models/models.d.ts.map +1 -1
  7. package/dist/browser/models/models.js +2 -0
  8. package/dist/browser/models/models.js.map +1 -1
  9. package/dist/browser/static-helpers/urlTemplate.d.ts.map +1 -1
  10. package/dist/browser/static-helpers/urlTemplate.js +2 -2
  11. package/dist/browser/static-helpers/urlTemplate.js.map +1 -1
  12. package/dist/commonjs/api/agentsContext.d.ts.map +1 -1
  13. package/dist/commonjs/api/agentsContext.js +7 -19
  14. package/dist/commonjs/api/agentsContext.js.map +1 -1
  15. package/dist/commonjs/models/models.d.ts +1 -1
  16. package/dist/commonjs/models/models.d.ts.map +1 -1
  17. package/dist/commonjs/models/models.js +2 -0
  18. package/dist/commonjs/models/models.js.map +1 -1
  19. package/dist/commonjs/static-helpers/urlTemplate.d.ts.map +1 -1
  20. package/dist/commonjs/static-helpers/urlTemplate.js +2 -2
  21. package/dist/commonjs/static-helpers/urlTemplate.js.map +1 -1
  22. package/dist/esm/api/agentsContext.d.ts.map +1 -1
  23. package/dist/esm/api/agentsContext.js +7 -19
  24. package/dist/esm/api/agentsContext.js.map +1 -1
  25. package/dist/esm/models/models.d.ts +1 -1
  26. package/dist/esm/models/models.d.ts.map +1 -1
  27. package/dist/esm/models/models.js +2 -0
  28. package/dist/esm/models/models.js.map +1 -1
  29. package/dist/esm/static-helpers/urlTemplate.d.ts.map +1 -1
  30. package/dist/esm/static-helpers/urlTemplate.js +2 -2
  31. package/dist/esm/static-helpers/urlTemplate.js.map +1 -1
  32. package/dist/react-native/api/agentsContext.d.ts.map +1 -1
  33. package/dist/react-native/api/agentsContext.js +7 -19
  34. package/dist/react-native/api/agentsContext.js.map +1 -1
  35. package/dist/react-native/models/models.d.ts +1 -1
  36. package/dist/react-native/models/models.d.ts.map +1 -1
  37. package/dist/react-native/models/models.js +2 -0
  38. package/dist/react-native/models/models.js.map +1 -1
  39. package/dist/react-native/static-helpers/urlTemplate.d.ts.map +1 -1
  40. package/dist/react-native/static-helpers/urlTemplate.js +2 -2
  41. package/dist/react-native/static-helpers/urlTemplate.js.map +1 -1
  42. package/package.json +3 -3
package/README.md CHANGED
@@ -1,32 +1,24 @@
1
- # Azure AI Projects client library for JavaScript
1
+ # Azure AI Agents client library for JavaScript
2
2
 
3
- Use the AI Projects client library (in preview) to:
3
+ Use the AI Agents client library to:
4
4
 
5
- - **Enumerate connections** in your Azure AI Foundry project and get connection properties.
6
- For example, get the inference endpoint URL and credentials associated with your Azure OpenAI connection.
7
- - **Develop Agents using the Azure AI Agent Service**, leveraging an extensive ecosystem of models, tools, and capabilities from OpenAI, Microsoft, and other LLM providers. The Azure AI Agent Service enables the building of Agents for a wide range of generative AI use cases. The package is currently in private preview.
8
- - **Enable OpenTelemetry tracing**.
5
+ - **Develop Agents using the Azure AI Agent Service**, leveraging an extensive ecosystem of models, tools, and capabilities from OpenAI, Microsoft, and other LLM providers. The Azure AI Agent Service enables the building of Agents for a wide range of generative AI use cases.
9
6
 
10
7
  [Product documentation](https://aka.ms/azsdk/azure-ai-projects/product-doc)
11
-
12
- | [Samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-projects/samples)
13
- | [Package (npm)](https://www.npmjs.com/package/@azure/ai-projects)
8
+ | [Samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-agents/samples/)
9
+ | [Package (npm)](https://www.npmjs.com/package/@azure/ai-agents)
14
10
  | [API reference documentation](https://learn.microsoft.com/javascript/api/overview/azure/ai-projects-readme?view=azure-node-preview)
15
11
 
16
12
  ## Table of contents
17
13
 
18
14
  - [Getting started](#getting-started)
19
15
  - [Prerequisite](#prerequisite)
16
+ - [Authorization](#authorization)
20
17
  - [Install the package](#install-the-package)
21
18
  - [Key concepts](#key-concepts)
22
19
  - [Create and authenticate the client](#create-and-authenticate-the-client)
23
20
  - [Examples](#examples)
24
- - [Enumerate connections](#enumerate-connections)
25
- - [Get properties of all connections](#get-properties-of-all-connections)
26
- - [Get properties of all connections of a particular type](#get-properties-of-all-connections-of-a-particular-type)
27
- - [Get properties of a default connection](#get-properties-of-a-default-connection)
28
- - [Get properties of a connection by its connection name](#get-properties-of-a-connection-by-its-connection-name)
29
- - [Agents (Preview)](#agents-private-preview)
21
+ - [Agents](#agents)
30
22
  - [Create an Agent](#create-agent) with:
31
23
  - [File Search](#create-agent-with-file-search)
32
24
  - [Code interpreter](#create-agent-with-code-interpreter)
@@ -39,14 +31,11 @@ Use the AI Projects client library (in preview) to:
39
31
  - [Create message](#create-message) with:
40
32
  - [File search attachment](#create-message-with-file-search-attachment)
41
33
  - [Code interpreter attachment](#create-message-with-code-interpreter-attachment)
34
+ - [Image input](#create-message-with-image-inputs)
42
35
  - [Execute Run, Create Thread and Run, or Stream](#create-run-run_and_process-or-stream)
43
36
  - [Retrieve message](#retrieve-message)
44
37
  - [Retrieve file](#retrieve-file)
45
38
  - [Tear down by deleting resource](#teardown)
46
- - [Tracing](#tracing)
47
- - [Tracing](#tracing)
48
- - [Installation](#installation)
49
- - [Tracing example](#tracing-example)
50
39
  - [Troubleshooting](#troubleshooting)
51
40
  - [Exceptions](#exceptions)
52
41
  - [Reporting issues](#reporting-issues)
@@ -60,9 +49,11 @@ Use the AI Projects client library (in preview) to:
60
49
  - [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule)
61
50
  - An [Azure subscription][azure_sub].
62
51
  - A [project in Azure AI Foundry](https://learn.microsoft.com/azure/ai-studio/how-to/create-projects?tabs=ai-studio).
63
- - The project connection string. It can be found in your Azure AI Foundry project overview page, under "Project details". Below we will assume the environment variable `PROJECT_ENDPOINT` was defined to hold this value.
64
- - Entra ID is needed to authenticate the client. Your application needs an object that implements the [TokenCredential](https://learn.microsoft.com/javascript/api/@azure/core-auth/tokencredential) interface. Code samples here use [DefaultAzureCredential](https://learn.microsoft.com/javascript/api/@azure/identity/defaultazurecredential?view=azure-node-latest). To get that working, you will need:
65
- - The `Contributor` role. Role assigned can be done via the "Access Control (IAM)" tab of your Azure AI Project resource in the Azure portal.
52
+
53
+ ### Authorization
54
+
55
+ - [Entra ID][entra_id] is needed to authenticate the client. Your application needs an object that implements the [TokenCredential](https://learn.microsoft.com/javascript/api/@azure/core-auth/tokencredential) interface. Code samples here use [DefaultAzureCredential](https://learn.microsoft.com/javascript/api/@azure/identity/defaultazurecredential?view=azure-node-latest). To get that working, you will need:
56
+ - The `Contributor` role. Role assigned can be done via the "Access Control (IAM)" tab of your Azure AI Project resource in the Azure portal. Learn more about role assignments [here](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-portal).
66
57
  - [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed.
67
58
  - You are logged into your Azure account by running `az login`.
68
59
  - Note that if you have multiple Azure subscriptions, the subscription that contains your Azure AI Project resource must be your default subscription. Run `az account list --output table` to list all your subscription and see which one is the default. Run `az account set --subscription "Your Subscription ID or Name"` to change your default subscription.
@@ -77,33 +68,31 @@ npm install @azure/ai-agents @azure/identity
77
68
 
78
69
  ### Create and authenticate the client
79
70
 
80
- The class factory method `fromConnectionString` is used to construct the client. To construct a client:
71
+ The `AgentsClient` is used to construct the client. Currently, we recommend that you use the AgentsClient through the [Azure AI Projects Client Library](https://www.npmjs.com/package/@azure/ai-projects) using `client.agents`.
72
+
73
+ To construct a client:
81
74
 
82
75
  ```ts snippet:setup
83
- import { AIProjectsClient } from "@azure/ai-projects";
76
+ import { AgentsClient } from "@azure/ai-agents";
84
77
  import { DefaultAzureCredential } from "@azure/identity";
85
78
 
86
- const connectionString = process.env.PROJECT_ENDPOINT ?? "<connectionString>";
87
- const client = AIProjectsClient.fromConnectionString(
88
- connectionString,
89
- new DefaultAzureCredential(),
90
- );
79
+ const projectEndpoint = process.env["PROJECT_ENDPOINT"] || "<project endpoint>";
80
+ const modelDeploymentName = process.env["MODEL_DEPLOYMENT_NAME"] || "gpt-4o";
81
+ const client = new AgentsClient(projectEndpoint, new DefaultAzureCredential());
91
82
  ```
92
83
 
93
84
  ## Examples
94
85
 
95
- ### Agents (Preview)
86
+ ### Agents
96
87
 
97
- Agents in the Azure AI Projects client library are designed to facilitate various interactions and operations within your AI projects. They serve as the core components that manage and execute tasks, leveraging different tools and resources to achieve specific goals. The following steps outline the typical sequence for interacting with Agents. See the "agents" folder in the [package samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-projects/samples) for additional Agent samples.
98
-
99
- Agents are actively being developed. A sign-up form for private preview is coming soon.
88
+ Agents in the Azure AI Projects client library are designed to facilitate various interactions and operations within your AI projects. They serve as the core components that manage and execute tasks, leveraging different tools and resources to achieve specific goals. The following steps outline the typical sequence for interacting with Agents. See the [package samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-agents/samples/) for additional Agent samples.
100
89
 
101
90
  #### Create Agent
102
91
 
103
92
  Here is an example of how to create an Agent:
104
93
 
105
94
  ```ts snippet:createAgent
106
- const agent = await client.agents.createAgent("gpt-4o", {
95
+ const agent = await client.createAgent("gpt-4o", {
107
96
  name: "my-agent",
108
97
  instructions: "You are a helpful assistant",
109
98
  });
@@ -114,18 +103,32 @@ To allow Agents to access your resources or custom functions, you need tools. Yo
114
103
  You can use `ToolSet` to do this:
115
104
 
116
105
  ```ts snippet:toolSet
117
- import { ToolSet } from "@azure/ai-projects";
106
+ import { ToolSet } from "@azure/ai-agents";
118
107
 
108
+ // Upload file for code interpreter tool
109
+ const filePath1 = "./data/nifty500QuarterlyResults.csv";
110
+ const fileStream1 = fs.createReadStream(filePath1);
111
+ const codeInterpreterFile = await client.files.upload(fileStream1, "assistants", {
112
+ fileName: "myLocalFile",
113
+ });
114
+ console.log(`Uploaded local file, file ID : ${codeInterpreterFile.id}`);
115
+ // Upload file for file search tool
116
+ const filePath2 = "./data/sampleFileForUpload.txt";
117
+ const fileStream2 = fs.createReadStream(filePath2);
118
+ const fileSearchFile = await client.files.upload(fileStream2, "assistants", {
119
+ fileName: "sampleFileForUpload.txt",
120
+ });
121
+ console.log(`Uploaded file, file ID: ${fileSearchFile.id}`);
122
+ // Create vector store for file search tool
123
+ const vectorStore = await client.vectorStores
124
+ .createAndPoll({
125
+ fileIds: [fileSearchFile.id],
126
+ })
127
+ .pollUntilDone();
128
+ // Create tool set
119
129
  const toolSet = new ToolSet();
120
130
  toolSet.addFileSearchTool([vectorStore.id]);
121
131
  toolSet.addCodeInterpreterTool([codeInterpreterFile.id]);
122
- const agent = await client.agents.createAgent("gpt-4o", {
123
- name: "my-agent",
124
- instructions: "You are a helpful agent",
125
- tools: toolSet.toolDefinitions,
126
- toolResources: toolSet.toolResources,
127
- });
128
- console.log(`Created agent, agent ID: ${agent.id}`);
129
132
  ```
130
133
 
131
134
  #### Create Agent with File Search
@@ -133,21 +136,25 @@ console.log(`Created agent, agent ID: ${agent.id}`);
133
136
  To perform file search by an Agent, we first need to upload a file, create a vector store, and associate the file to the vector store. Here is an example:
134
137
 
135
138
  ```ts snippet:fileSearch
136
- import { ToolUtility } from "@azure/ai-projects";
139
+ import { ToolUtility } from "@azure/ai-agents";
137
140
 
141
+ const filePath = "./data/sampleFileForUpload.txt";
138
142
  const localFileStream = fs.createReadStream(filePath);
139
- const file = await client.agents.uploadFile(localFileStream, "assistants", {
140
- fileName: "sample_file_for_upload.txt",
143
+ const file = await client.files.upload(localFileStream, "assistants", {
144
+ fileName: "sampleFileForUpload.txt",
141
145
  });
142
- console.log(`Uploaded file, ID: ${file.id}`);
143
- const vectorStore = await client.agents.createVectorStore({
146
+ console.log(`Uploaded file, file ID: ${file.id}`);
147
+
148
+ const vectorStore = await client.vectorStores.create({
144
149
  fileIds: [file.id],
145
- name: "my_vector_store",
150
+ name: "myVectorStore",
146
151
  });
147
- console.log(`Created vector store, ID: ${vectorStore.id}`);
152
+ console.log(`Created vector store, vector store ID: ${vectorStore.id}`);
153
+
148
154
  const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
149
- const agent = await client.agents.createAgent("gpt-4o", {
150
- name: "SDK Test Agent - Retrieval",
155
+
156
+ const agent = await client.createAgent("gpt-4o", {
157
+ name: "File Search Agent",
151
158
  instructions: "You are helpful agent that can help fetch data from files you know about.",
152
159
  tools: [fileSearchTool.definition],
153
160
  toolResources: fileSearchTool.resources,
@@ -160,16 +167,20 @@ console.log(`Created agent, agent ID : ${agent.id}`);
160
167
  Here is an example to upload a file and use it for code interpreter by an Agent:
161
168
 
162
169
  ```ts snippet:codeInterpreter
163
- import { ToolUtility } from "@azure/ai-projects";
170
+ import { ToolUtility } from "@azure/ai-agents";
164
171
 
172
+ const filePath = "./data/nifty500QuarterlyResults.csv";
165
173
  const localFileStream = fs.createReadStream(filePath);
166
- const localFile = await client.agents.uploadFile(localFileStream, "assistants", {
174
+ const localFile = await client.files.upload(localFileStream, "assistants", {
167
175
  fileName: "localFile",
168
176
  });
177
+
169
178
  console.log(`Uploaded local file, file ID : ${localFile.id}`);
179
+
170
180
  const codeInterpreterTool = ToolUtility.createCodeInterpreterTool([localFile.id]);
181
+
171
182
  // Notice that CodeInterpreter must be enabled in the agent creation, otherwise the agent will not be able to see the file attachment
172
- const agent = await client.agents.createAgent("gpt-4o-mini", {
183
+ const agent = await client.createAgent("gpt-4o", {
173
184
  name: "my-agent",
174
185
  instructions: "You are a helpful agent",
175
186
  tools: [codeInterpreterTool.definition],
@@ -180,19 +191,20 @@ console.log(`Created agent, agent ID: ${agent.id}`);
180
191
 
181
192
  #### Create Agent with Bing Grounding
182
193
 
183
- To enable your Agent to perform search through Bing search API, you use `ToolUtility.createConnectionTool()` along with a connection.
194
+ To enable your Agent to perform search through Bing search API, you use `ToolUtility.createBingGroundingTool()` along with a connection. See [here](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/bing-grounding?tabs=python&pivots=overview) to learn more about Grounding with Bing Search.
184
195
 
185
196
  Here is an example:
186
197
 
187
198
  ```ts snippet:bingGrounding
188
- import { ToolUtility, connectionToolType } from "@azure/ai-projects";
199
+ import { ToolUtility } from "@azure/ai-agents";
189
200
 
190
- const bingConnection = await client.connections.getConnection(
191
- process.env.BING_CONNECTION_NAME ?? "<connection-name>",
192
- );
193
- const connectionId = bingConnection.id;
194
- const bingTool = ToolUtility.createConnectionTool(connectionToolType.BingGrounding, [connectionId]);
195
- const agent = await client.agents.createAgent("gpt-4o", {
201
+ const connectionId = process.env["AZURE_BING_CONNECTION_ID"] || "<connection-name>";
202
+
203
+ // Initialize agent bing tool with the connection id
204
+ const bingTool = ToolUtility.createBingGroundingTool([{ connectionId: connectionId }]);
205
+
206
+ // Create agent with the bing tool and process assistant run
207
+ const agent = await client.createAgent("gpt-4o", {
196
208
  name: "my-agent",
197
209
  instructions: "You are a helpful agent",
198
210
  tools: [bingTool.definition],
@@ -207,13 +219,21 @@ Azure AI Search is an enterprise search system for high-performance applications
207
219
  Here is an example to integrate Azure AI Search:
208
220
 
209
221
  ```ts snippet:AISearch
210
- import { ToolUtility } from "@azure/ai-projects";
222
+ import { ToolUtility } from "@azure/ai-agents";
211
223
 
212
- const connectionName =
213
- process.env.AZURE_AI_SEARCH_CONNECTION_NAME ?? "<AzureAISearchConnectionName>";
214
- const connection = await client.connections.getConnection(connectionName);
215
- const azureAISearchTool = ToolUtility.createAzureAISearchTool(connection.id, connection.name);
216
- const agent = await client.agents.createAgent("gpt-4-0125-preview", {
224
+ const connectionName = process.env["AZURE_AI_SEARCH_CONNECTION_NAME"] || "<connection-name>";
225
+
226
+ // Initialize Azure AI Search tool
227
+ const azureAISearchTool = ToolUtility.createAzureAISearchTool(connectionName, "search-index", {
228
+ queryType: "simple",
229
+ topK: 3,
230
+ filter: "", // Add string here to filter results
231
+ indexConnectionId: connectionName,
232
+ indexName: "search-index",
233
+ });
234
+
235
+ // Create agent with the Azure AI search tool
236
+ const agent = await client.createAgent("gpt-4o", {
217
237
  name: "my-agent",
218
238
  instructions: "You are a helpful agent",
219
239
  tools: [azureAISearchTool.definition],
@@ -232,16 +252,16 @@ Here is an example:
232
252
  import {
233
253
  FunctionToolDefinition,
234
254
  ToolUtility,
235
- RequiredToolCallOutput,
236
- FunctionToolDefinitionOutput,
255
+ RequiredToolCall,
237
256
  ToolOutput,
238
- } from "@azure/ai-projects";
257
+ } from "@azure/ai-agents";
239
258
 
240
259
  class FunctionToolExecutor {
241
260
  private functionTools: {
242
261
  func: Function;
243
262
  definition: FunctionToolDefinition;
244
263
  }[];
264
+
245
265
  constructor() {
246
266
  this.functionTools = [
247
267
  {
@@ -281,20 +301,22 @@ class FunctionToolExecutor {
281
301
  },
282
302
  ];
283
303
  }
304
+
284
305
  private getUserFavoriteCity(): {} {
285
306
  return { location: "Seattle, WA" };
286
307
  }
287
- private getCityNickname(location: string): {} {
308
+
309
+ private getCityNickname(_location: string): {} {
288
310
  return { nickname: "The Emerald City" };
289
311
  }
290
- private getWeather(location: string, unit: string): {} {
312
+
313
+ private getWeather(_location: string, unit: string): {} {
291
314
  return { weather: unit === "f" ? "72f" : "22c" };
292
315
  }
293
- public invokeTool(
294
- toolCall: RequiredToolCallOutput & FunctionToolDefinitionOutput,
295
- ): ToolOutput | undefined {
316
+
317
+ public invokeTool(toolCall: RequiredToolCall & FunctionToolDefinition): ToolOutput | undefined {
296
318
  console.log(`Function tool call - ${toolCall.function.name}`);
297
- const args = [];
319
+ const args: any[] = [];
298
320
  if (toolCall.function.parameters) {
299
321
  try {
300
322
  const params = JSON.parse(toolCall.function.parameters);
@@ -309,15 +331,23 @@ class FunctionToolExecutor {
309
331
  }
310
332
  }
311
333
  const result = this.functionTools
312
- .find((tool) => tool.definition.function.name === toolCall.function.name)
313
- ?.func(...args);
334
+ .map((tool) =>
335
+ tool.definition.function.name === toolCall.function.name ? tool.func(...args) : undefined,
336
+ )
337
+ .find((r) => r !== undefined);
314
338
  return result
315
339
  ? {
316
340
  toolCallId: toolCall.id,
317
341
  output: JSON.stringify(result),
318
342
  }
319
- : undefined;
343
+ : {
344
+ toolCallId: toolCall.id,
345
+ output: JSON.stringify({
346
+ error: `No matching tool found for function: ${toolCall.function.name}`,
347
+ }),
348
+ };
320
349
  }
350
+
321
351
  public getFunctionDefinitions(): FunctionToolDefinition[] {
322
352
  return this.functionTools.map((tool) => {
323
353
  return tool.definition;
@@ -326,7 +356,7 @@ class FunctionToolExecutor {
326
356
  }
327
357
  const functionToolExecutor = new FunctionToolExecutor();
328
358
  const functionTools = functionToolExecutor.getFunctionDefinitions();
329
- const agent = await client.agents.createAgent("gpt-4o", {
359
+ const agent = await client.createAgent("gpt-4o", {
330
360
  name: "my-agent",
331
361
  instructions:
332
362
  "You are a weather bot. Use the provided functions to help answer questions. Customize your responses to the user's preferences as much as possible and use friendly nicknames for cities whenever possible.",
@@ -341,11 +371,12 @@ OpenAPI specifications describe REST operations against a specific endpoint. Age
341
371
  Here is an example creating an OpenAPI tool (using anonymous authentication):
342
372
 
343
373
  ```ts snippet:createAgentWithOpenApi
344
- import { ToolUtility } from "@azure/ai-projects";
374
+ import { ToolUtility } from "@azure/ai-agents";
345
375
 
346
376
  // Read in OpenApi spec
347
377
  const filePath = "./data/weatherOpenApi.json";
348
378
  const openApiSpec = JSON.parse(fs.readFileSync(filePath, "utf-8"));
379
+
349
380
  // Define OpenApi function
350
381
  const openApiFunction = {
351
382
  name: "getWeather",
@@ -356,10 +387,12 @@ const openApiFunction = {
356
387
  },
357
388
  default_params: ["format"], // optional
358
389
  };
390
+
359
391
  // Create OpenApi tool
360
392
  const openApiTool = ToolUtility.createOpenApiTool(openApiFunction);
393
+
361
394
  // Create agent with OpenApi tool
362
- const agent = await client.agents.createAgent("gpt-4o-mini", {
395
+ const agent = await client.createAgent("gpt-4o", {
363
396
  name: "myAgent",
364
397
  instructions: "You are a helpful agent",
365
398
  tools: [openApiTool.definition],
@@ -374,16 +407,15 @@ To enable your Agent to answer queries using Fabric data, use `FabricTool` along
374
407
  Here is an example:
375
408
 
376
409
  ```ts snippet:createAgentWithFabric
377
- import { ToolUtility } from "@azure/ai-projects";
410
+ import { ToolUtility } from "@azure/ai-agents";
411
+
412
+ const connectionId = process.env["FABRIC_CONNECTION_ID"] || "<connection-name>";
378
413
 
379
- const fabricConnection = await client.connections.getConnection(
380
- process.env["FABRIC_CONNECTION_NAME"] || "<connection-name>",
381
- );
382
- const connectionId = fabricConnection.id;
383
414
  // Initialize agent Microsoft Fabric tool with the connection id
384
415
  const fabricTool = ToolUtility.createFabricTool(connectionId);
416
+
385
417
  // Create agent with the Microsoft Fabric tool and process assistant run
386
- const agent = await client.agents.createAgent("gpt-4o", {
418
+ const agent = await client.createAgent("gpt-4o", {
387
419
  name: "my-agent",
388
420
  instructions: "You are a helpful agent",
389
421
  tools: [fabricTool.definition],
@@ -396,45 +428,51 @@ console.log(`Created agent, agent ID : ${agent.id}`);
396
428
  For each session or conversation, a thread is required. Here is an example:
397
429
 
398
430
  ```ts snippet:createThread
399
- const thread = await client.agents.createThread();
431
+ const thread = await client.threads.create();
432
+ console.log(`Created thread, thread ID: ${thread.id}`);
400
433
  ```
401
434
 
402
435
  #### Create Thread with Tool Resource
403
436
 
404
- In some scenarios, you might need to assign specific resources to individual threads. To achieve this, you provide the `toolResources` argument to `createThread`. In the following example, you create a vector store and upload a file, enable an Agent for file search using the `tools` argument, and then associate the file with the thread using the `toolResources` argument.
437
+ In some scenarios, you might need to assign specific resources to individual threads. To achieve this, you provide the `toolResources` argument to `threads.create`. In the following example, you create a vector store and upload a file, enable an Agent for file search using the `tools` argument, and then associate the file with the thread using the `toolResources` argument.
405
438
 
406
439
  ```ts snippet:threadWithTool
407
- import { ToolUtility } from "@azure/ai-projects";
440
+ import { ToolUtility } from "@azure/ai-agents";
408
441
 
442
+ const filePath = "./data/nifty500QuarterlyResults.csv";
409
443
  const localFileStream = fs.createReadStream(filePath);
410
- const file = await client.agents.uploadFile(localFileStream, "assistants", {
444
+ const file = await client.files.upload(localFileStream, "assistants", {
411
445
  fileName: "sample_file_for_upload.csv",
412
446
  });
413
447
  console.log(`Uploaded file, ID: ${file.id}`);
414
- const vectorStore = await client.agents.createVectorStore({
448
+
449
+ const vectorStore = await client.agents.vectorStores.create()({
415
450
  fileIds: [file.id],
416
451
  });
417
452
  console.log(`Created vector store, ID: ${vectorStore.id}`);
453
+
418
454
  const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
455
+
419
456
  const agent = await client.agents.createAgent("gpt-4o", {
420
457
  name: "myAgent",
421
458
  instructions: "You are helpful agent that can help fetch data from files you know about.",
422
459
  tools: [fileSearchTool.definition],
423
460
  });
424
461
  console.log(`Created agent, agent ID : ${agent.id}`);
462
+
425
463
  // Create thread with file resources.
426
464
  // If the agent has multiple threads, only this thread can search this file.
427
- const thread = await client.agents.createThread({ toolResources: fileSearchTool.resources });
465
+ const thread = await client.threads.create({ toolResources: fileSearchTool.resources });
428
466
  ```
429
467
 
430
468
  #### List Threads
431
469
 
432
- To list all threads attached to a given agent, use the list_threads API:
470
+ To list all threads attached to a given agent, use `threads.list`:
433
471
 
434
472
  ```ts snippet:listThreads
435
- const threads = await client.agents.listThreads();
473
+ const threads = client.threads.list();
436
474
  console.log(`Threads for agent ${agent.id}:`);
437
- for await (const t of (await threads).data) {
475
+ for await (const t of threads) {
438
476
  console.log(`Thread ID: ${t.id}`);
439
477
  console.log(`Created at: ${t.createdAt}`);
440
478
  console.log(`Metadata: ${t.metadata}`);
@@ -447,10 +485,7 @@ for await (const t of (await threads).data) {
447
485
  To create a message for assistant to process, you pass `user` as `role` and a question as `content`:
448
486
 
449
487
  ```ts snippet:createMessage
450
- const message = await client.agents.createMessage(thread.id, {
451
- role: "user",
452
- content: "hello, world!",
453
- });
488
+ const message = await client.messages.create(thread.id, "user", "hello, world!");
454
489
  console.log(`Created message, message ID: ${message.id}`);
455
490
  ```
456
491
 
@@ -459,17 +494,22 @@ console.log(`Created message, message ID: ${message.id}`);
459
494
  To attach a file to a message for content searching, you use `ToolUtility.createFileSearchTool()` and the `attachments` argument:
460
495
 
461
496
  ```ts snippet:messageWithFileSearch
462
- import { ToolUtility } from "@azure/ai-projects";
497
+ import { ToolUtility } from "@azure/ai-agents";
463
498
 
464
499
  const fileSearchTool = ToolUtility.createFileSearchTool();
465
- const message = await client.agents.createMessage(thread.id, {
466
- role: "user",
467
- content: "What feature does Smart Eyewear offer?",
468
- attachments: {
469
- fileId: file.id,
470
- tools: [fileSearchTool.definition],
500
+ const message = await client.messages.create(
501
+ thread.id,
502
+ "user",
503
+ "What feature does Smart Eyewear offer?",
504
+ {
505
+ attachments: [
506
+ {
507
+ fileId: file.id,
508
+ tools: [fileSearchTool.definition],
509
+ },
510
+ ],
471
511
  },
472
- });
512
+ );
473
513
  ```
474
514
 
475
515
  #### Create Message with Code Interpreter Attachment
@@ -479,28 +519,34 @@ To attach a file to a message for data analysis, you use `ToolUtility.createCode
479
519
  Here is an example:
480
520
 
481
521
  ```ts snippet:messageWithCodeInterpreter
482
- import { ToolUtility } from "@azure/ai-projects";
522
+ import { ToolUtility } from "@azure/ai-agents";
483
523
 
484
524
  // notice that CodeInterpreter must be enabled in the agent creation,
485
525
  // otherwise the agent will not be able to see the file attachment for code interpretation
486
526
  const codeInterpreterTool = ToolUtility.createCodeInterpreterTool();
487
- const agent = await client.agents.createAgent("gpt-4-1106-preview", {
527
+ const agent = await client.agents.createAgent("gpt-4o", {
488
528
  name: "my-assistant",
489
529
  instructions: "You are helpful assistant",
490
530
  tools: [codeInterpreterTool.definition],
491
531
  });
492
532
  console.log(`Created agent, agent ID: ${agent.id}`);
493
- const thread = await client.agents.createThread();
533
+
534
+ const thread = await client.threads.create();
494
535
  console.log(`Created thread, thread ID: ${thread.id}`);
495
- const message = await client.agents.createMessage(thread.id, {
496
- role: "user",
497
- content:
498
- "Could you please create bar chart in TRANSPORTATION sector for the operating profit from the uploaded csv file and provide file to me?",
499
- attachments: {
500
- fileId: file.id,
501
- tools: [codeInterpreterTool.definition],
536
+
537
+ const message = await client.messages.create(
538
+ thread.id,
539
+ "user",
540
+ "Could you please create a bar chart in the TRANSPORTATION sector for the operating profit from the uploaded CSV file and provide the file to me?",
541
+ {
542
+ attachments: [
543
+ {
544
+ fileId: file.id,
545
+ tools: [codeInterpreterTool.definition],
546
+ },
547
+ ],
502
548
  },
503
- });
549
+ );
504
550
  console.log(`Created message, message ID: ${message.id}`);
505
551
  ```
506
552
 
@@ -512,67 +558,7 @@ You can send messages to Azure agents with image inputs in following ways:
512
558
  - **Using a public image accessible via URL**
513
559
  - **Using a base64 encoded image string**
514
560
 
515
- The following examples demonstrate each method:
516
-
517
- ##### Create message using uploaded image file
518
-
519
- ```ts snippet:imageInputWithFile
520
- // Upload the local image file
521
- const fileStream = fs.createReadStream(imagePath);
522
- const imageFile = await client.agents.uploadFile(fileStream, "assistants", {
523
- fileName: "image_file.png",
524
- });
525
- console.log(`Uploaded file, file ID: ${imageFile.id}`);
526
- // Create a message with both text and image content
527
- console.log("Creating message with image content...");
528
- const inputMessage = "Hello, what is in the image?";
529
- const content = [
530
- {
531
- type: "text",
532
- text: inputMessage,
533
- },
534
- {
535
- type: "image_file",
536
- image_file: {
537
- file_id: imageFile.id,
538
- detail: "high",
539
- },
540
- },
541
- ];
542
- const message = await client.agents.createMessage(thread.id, {
543
- role: "user",
544
- content: content,
545
- });
546
- console.log(`Created message, message ID: ${message.id}`);
547
- ```
548
-
549
- ##### Create message with an image URL input
550
-
551
- ```ts snippet:imageInputWithUrl
552
- // Specify the public image URL
553
- const imageUrl =
554
- "https://github.com/Azure/azure-sdk-for-js/blob/0aa88ceb18d865726d423f73b8393134e783aea6/sdk/ai/ai-projects/data/image_file.png?raw=true";
555
- // Create content directly referencing image URL
556
- const inputMessage = "Hello, what is in the image?";
557
- const content = [
558
- {
559
- type: "text",
560
- text: inputMessage,
561
- },
562
- {
563
- type: "image_url",
564
- image_url: {
565
- url: imageUrl,
566
- detail: "high",
567
- },
568
- },
569
- ];
570
- const message = await client.agents.createMessage(thread.id, {
571
- role: "user",
572
- content: content,
573
- });
574
- console.log(`Created message, message ID: ${message.id}`);
575
- ```
561
+ The following example demonstrates base64 method:
576
562
 
577
563
  ##### Create message with base64-encoded image input
578
564
 
@@ -590,9 +576,13 @@ function imageToBase64DataUrl(imagePath: string, mimeType: string): string {
590
576
  throw error;
591
577
  }
592
578
  }
579
+
593
580
  // Convert your image file to base64 format
581
+ const filePath = "./data/image_file.png";
594
582
  const imageDataUrl = imageToBase64DataUrl(filePath, "image/png");
583
+
595
584
  // Create a message with both text and image content
585
+ console.log("Creating message with image content...");
596
586
  const inputMessage = "Hello, what is in the image?";
597
587
  const content = [
598
588
  {
@@ -607,28 +597,26 @@ const content = [
607
597
  },
608
598
  },
609
599
  ];
610
- const message = await client.agents.createMessage(thread.id, {
611
- role: "user",
612
- content: content,
613
- });
600
+
601
+ const message = await client.messages.create(thread.id, "user", content);
614
602
  console.log(`Created message, message ID: ${message.id}`);
615
603
  ```
616
604
 
617
605
  #### Create Run, Run_and_Process, or Stream
618
606
 
619
- Here is an example of `createRun` and poll until the run is completed:
607
+ Here is an example of `runs.create` and poll until the run is completed:
620
608
 
621
609
  ```ts snippet:createRun
622
- let run = await client.agents.createRun(thread.id, agent.id);
623
- // Poll the run as long as run status is queued or in progress
624
- while (
625
- run.status === "queued" ||
626
- run.status === "in_progress" ||
627
- run.status === "requires_action"
628
- ) {
629
- // Wait for a second
630
- await new Promise((resolve) => setTimeout(resolve, 1000));
631
- run = await client.agents.getRun(thread.id, run.id);
610
+ import { delay } from "@azure/core-util";
611
+
612
+ let run = await client.runs.create(thread.id, agent.id);
613
+ console.log(`Created run, run ID: ${run.id}`);
614
+
615
+ // Wait for run to complete
616
+ while (["queued", "in_progress", "requires_action"].includes(run.status)) {
617
+ await delay(1000);
618
+ run = await client.runs.get(thread.id, run.id);
619
+ console.log(`Run status: ${run.status}`);
632
620
  }
633
621
  ```
634
622
 
@@ -637,7 +625,7 @@ To have the SDK poll on your behalf, use the `createThreadAndRun` method.
637
625
  Here is an example:
638
626
 
639
627
  ```ts snippet:createThreadAndRun
640
- const run = await client.agents.createThreadAndRun(agent.id, {
628
+ const run = await client.runs.createThreadAndRun(agent.id, {
641
629
  thread: {
642
630
  messages: [
643
631
  {
@@ -654,7 +642,7 @@ With streaming, polling also need not be considered.
654
642
  Here is an example:
655
643
 
656
644
  ```ts snippet:createRunStream
657
- const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();
645
+ const streamEventMessages = await client.runs.create(thread.id, agent.id).stream();
658
646
  ```
659
647
 
660
648
  Event handling can be done as follows:
@@ -662,18 +650,20 @@ Event handling can be done as follows:
662
650
  ```ts snippet:eventHandling
663
651
  import {
664
652
  RunStreamEvent,
665
- ThreadRunOutput,
653
+ ThreadRun,
666
654
  MessageStreamEvent,
667
655
  MessageDeltaChunk,
668
656
  MessageDeltaTextContent,
657
+ ErrorEvent,
669
658
  DoneEvent,
670
- } from "@azure/ai-projects";
659
+ } from "@azure/ai-agents";
660
+
661
+ const streamEventMessages = await client.runs.create(thread.id, agent.id).stream();
671
662
 
672
- const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();
673
663
  for await (const eventMessage of streamEventMessages) {
674
664
  switch (eventMessage.event) {
675
665
  case RunStreamEvent.ThreadRunCreated:
676
- console.log(`ThreadRun status: ${(eventMessage.data as ThreadRunOutput).status}`);
666
+ console.log(`ThreadRun status: ${(eventMessage.data as ThreadRun).status}`);
677
667
  break;
678
668
  case MessageStreamEvent.ThreadMessageDelta:
679
669
  {
@@ -687,6 +677,7 @@ for await (const eventMessage of streamEventMessages) {
687
677
  });
688
678
  }
689
679
  break;
680
+
690
681
  case RunStreamEvent.ThreadRunCompleted:
691
682
  console.log("Thread Run Completed");
692
683
  break;
@@ -705,63 +696,62 @@ for await (const eventMessage of streamEventMessages) {
705
696
  To retrieve messages from agents, use the following example:
706
697
 
707
698
  ```ts snippet:listMessages
708
- import { MessageContentOutput, isOutputOfType, MessageTextContentOutput } from "@azure/ai-projects";
709
-
710
- const messages = await client.agents.listMessages(thread.id);
711
- while (messages.hasMore) {
712
- const nextMessages = await client.agents.listMessages(currentRun.threadId, {
713
- after: messages.lastId,
714
- });
715
- messages.data = messages.data.concat(nextMessages.data);
716
- messages.hasMore = nextMessages.hasMore;
717
- messages.lastId = nextMessages.lastId;
699
+ const messagesIterator = client.messages.list(thread.id);
700
+ const allMessages = [];
701
+ for await (const m of messagesIterator) {
702
+ allMessages.push(m);
718
703
  }
704
+ console.log("Messages:", allMessages);
705
+
719
706
  // The messages are following in the reverse order,
720
707
  // we will iterate them and output only text contents.
721
- for (const dataPoint of messages.data.reverse()) {
722
- const lastMessageContent: MessageContentOutput = dataPoint.content[dataPoint.content.length - 1];
723
- console.log(lastMessageContent);
724
- if (isOutputOfType<MessageTextContentOutput>(lastMessageContent, "text")) {
725
- console.log(
726
- `${dataPoint.role}: ${(lastMessageContent as MessageTextContentOutput).text.value}`,
727
- );
708
+ const messages = await client.messages.list(thread.id, {
709
+ order: "asc",
710
+ });
711
+
712
+ for await (const dataPoint of messages) {
713
+ const textContent = dataPoint.content.find((item) => item.type === "text");
714
+ if (textContent && "text" in textContent) {
715
+ console.log(`${dataPoint.role}: ${textContent.text.value}`);
728
716
  }
729
717
  }
730
718
  ```
731
719
 
732
720
  ### Retrieve File
733
721
 
734
- Files uploaded by Agents cannot be retrieved back. If your use case needs to access the file content uploaded by the Agents, you are advised to keep an additional copy accessible by your application. However, files generated by Agents are retrievable by `getFileContent`.
722
+ Files uploaded by Agents cannot be retrieved back. If your use case needs to access the file content uploaded by the Agents, you are advised to keep an additional copy accessible by your application. However, files generated by Agents are retrievable by `files.getContent`.
735
723
 
736
724
  Here is an example retrieving file ids from messages:
737
725
 
738
726
  ```ts snippet:retrieveFile
739
- import {
740
- isOutputOfType,
741
- MessageTextContentOutput,
742
- MessageImageFileContentOutput,
743
- } from "@azure/ai-projects";
727
+ import { isOutputOfType, MessageTextContent, MessageImageFileContent } from "@azure/ai-agents";
728
+
729
+ const messagesIterator = client.messages.list(thread.id);
730
+ const allMessages = [];
731
+ for await (const m of messagesIterator) {
732
+ allMessages.push(m);
733
+ }
734
+ console.log("Messages:", allMessages);
744
735
 
745
- const messages = await client.agents.listMessages(thread.id);
746
736
  // Get most recent message from the assistant
747
- const assistantMessage = messages.data.find((msg) => msg.role === "assistant");
737
+ const assistantMessage = allMessages.find((msg) => msg.role === "assistant");
748
738
  if (assistantMessage) {
749
739
  const textContent = assistantMessage.content.find((content) =>
750
- isOutputOfType<MessageTextContentOutput>(content, "text"),
751
- ) as MessageTextContentOutput;
740
+ isOutputOfType<MessageTextContent>(content, "text"),
741
+ ) as MessageTextContent;
752
742
  if (textContent) {
753
743
  console.log(`Last message: ${textContent.text.value}`);
754
744
  }
755
745
  }
756
- const imageFile = (messages.data[0].content[0] as MessageImageFileContentOutput).imageFile;
757
- const imageFileName = (await client.agents.getFile(imageFile.fileId)).filename;
758
- const fileContent = await (
759
- await client.agents.getFileContent(imageFile.fileId).asNodeStream()
760
- ).body;
746
+
747
+ const imageFile = (allMessages[0].content[0] as MessageImageFileContent).imageFile;
748
+ const imageFileName = (await client.agents.files.get(imageFile.fileId)).filename;
749
+
750
+ const fileContent = await (await client.files.getContent(imageFile.fileId).asNodeStream()).body;
761
751
  if (fileContent) {
762
752
  const chunks: Buffer[] = [];
763
753
  for await (const chunk of fileContent) {
764
- chunks.push(Buffer.from(chunk));
754
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
765
755
  }
766
756
  const buffer = Buffer.concat(chunks);
767
757
  fs.writeFileSync(imageFileName, buffer);
@@ -776,71 +766,14 @@ console.log(`Saved image file to: ${imageFileName}`);
776
766
  To remove resources after completing tasks, use the following functions:
777
767
 
778
768
  ```ts snippet:teardown
779
- await client.agents.deleteVectorStore(vectorStore.id);
769
+ await client.vectorStores.delete(vectorStore.id);
780
770
  console.log(`Deleted vector store, vector store ID: ${vectorStore.id}`);
781
- await client.agents.deleteFile(file.id);
782
- console.log(`Deleted file, file ID: ${file.id}`);
783
- client.agents.deleteAgent(agent.id);
784
- console.log(`Deleted agent, agent ID: ${agent.id}`);
785
- ```
786
-
787
- ### Tracing
788
771
 
789
- You can add an Application Insights Azure resource to your Azure AI Foundry project. See the Tracing tab in your studio. If one was enabled, you can get the Application Insights connection string, configure your Agents, and observe the full execution path through Azure Monitor. Typically, you might want to start tracing before you create an Agent.
772
+ await client.files.delete(file.id);
773
+ console.log(`Deleted file, file ID : ${file.id}`);
790
774
 
791
- #### Installation
792
-
793
- Make sure to install OpenTelemetry and the Azure SDK tracing plugin via
794
-
795
- ```bash
796
- npm install @opentelemetry/api \
797
- @opentelemetry/instrumentation \
798
- @opentelemetry/sdk-trace-node \
799
- @azure/opentelemetry-instrumentation-azure-sdk \
800
- @azure/monitor-opentelemetry-exporter
801
- ```
802
-
803
- You will also need an exporter to send telemetry to your observability backend. You can print traces to the console or use a local viewer such as [Aspire Dashboard](https://learn.microsoft.com/dotnet/aspire/fundamentals/dashboard/standalone?tabs=bash).
804
-
805
- To connect to Aspire Dashboard or another OpenTelemetry compatible backend, install OTLP exporter:
806
-
807
- ```bash
808
- npm install @opentelemetry/exporter-trace-otlp-proto \
809
- @opentelemetry/exporter-metrics-otlp-proto
810
- ```
811
-
812
- #### Tracing example
813
-
814
- Here is a code sample to be included above `createAgent`:
815
-
816
- ```ts snippet:tracing
817
- import {
818
- NodeTracerProvider,
819
- SimpleSpanProcessor,
820
- ConsoleSpanExporter,
821
- } from "@opentelemetry/sdk-trace-node";
822
- import { trace } from "@opentelemetry/api";
823
- import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter";
824
-
825
- const provider = new NodeTracerProvider();
826
- provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
827
- provider.register();
828
- const tracer = trace.getTracer("Agents Sample", "1.0.0");
829
- let appInsightsConnectionString =
830
- process.env.APP_INSIGHTS_CONNECTION_STRING ?? "<appInsightsConnectionString>";
831
- if (appInsightsConnectionString == "<appInsightsConnectionString>") {
832
- appInsightsConnectionString = await client.telemetry.getConnectionString();
833
- }
834
- if (appInsightsConnectionString) {
835
- const exporter = new AzureMonitorTraceExporter({
836
- connectionString: appInsightsConnectionString,
837
- });
838
- provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
839
- }
840
- await tracer.startActiveSpan("main", async (span) => {
841
- client.telemetry.updateSettings({ enableContentRecording: true });
842
- // ...
843
- });
775
+ await client.deleteAgent(agent.id);
776
+ console.log(`Deleted agent, agent ID: ${agent.id}`);
844
777
  ```
845
778
 
846
779
  ## Troubleshooting
@@ -853,7 +786,7 @@ Client methods that make service calls raise an [RestError](https://learn.micros
853
786
  import { RestError } from "@azure/core-rest-pipeline";
854
787
 
855
788
  try {
856
- const result = await client.connections.listConnections();
789
+ const thread = await client.threads.create();
857
790
  } catch (e) {
858
791
  if (e instanceof RestError) {
859
792
  console.log(`Status code: ${e.code}`);
@@ -877,7 +810,7 @@ To report issues with the client library, or request additional features, please
877
810
 
878
811
  ## Next steps
879
812
 
880
- Have a look at the [package samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-projects/samples) folder, containing fully runnable code.
813
+ Have a look at the [package samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/ai/ai-agents/samples) folder, containing fully runnable code.
881
814
 
882
815
  ## Contributing
883
816
 
@@ -901,7 +834,4 @@ additional questions or comments.
901
834
  [code_of_conduct]: https://opensource.microsoft.com/codeofconduct/
902
835
  [entra_id]: https://learn.microsoft.com/azure/ai-services/authentication?tabs=powershell#authenticate-with-microsoft-entra-id
903
836
  [azure_identity_npm]: https://www.npmjs.com/package/@azure/identity
904
- [default_azure_credential]: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#defaultazurecredential
905
837
  [azure_sub]: https://azure.microsoft.com/free/
906
- [evaluators]: https://learn.microsoft.com/azure/ai-studio/how-to/develop/evaluate-sdk
907
- [evaluator_library]: https://learn.microsoft.com/azure/ai-studio/how-to/evaluate-generative-ai-app#view-and-manage-the-evaluators-in-the-evaluator-library