@azure/ai-agents 1.0.0-alpha.20250507.2 → 1.0.0-alpha.20250509.4
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.
- package/README.md +196 -214
- package/dist/browser/api/agentsContext.d.ts.map +1 -1
- package/dist/browser/api/agentsContext.js +7 -19
- package/dist/browser/api/agentsContext.js.map +1 -1
- package/dist/browser/models/models.d.ts +1 -1
- package/dist/browser/models/models.d.ts.map +1 -1
- package/dist/browser/models/models.js +2 -0
- package/dist/browser/models/models.js.map +1 -1
- package/dist/browser/static-helpers/urlTemplate.d.ts.map +1 -1
- package/dist/browser/static-helpers/urlTemplate.js +2 -2
- package/dist/browser/static-helpers/urlTemplate.js.map +1 -1
- package/dist/commonjs/api/agentsContext.d.ts.map +1 -1
- package/dist/commonjs/api/agentsContext.js +7 -19
- package/dist/commonjs/api/agentsContext.js.map +1 -1
- package/dist/commonjs/models/models.d.ts +1 -1
- package/dist/commonjs/models/models.d.ts.map +1 -1
- package/dist/commonjs/models/models.js +2 -0
- package/dist/commonjs/models/models.js.map +1 -1
- package/dist/commonjs/static-helpers/urlTemplate.d.ts.map +1 -1
- package/dist/commonjs/static-helpers/urlTemplate.js +2 -2
- package/dist/commonjs/static-helpers/urlTemplate.js.map +1 -1
- package/dist/esm/api/agentsContext.d.ts.map +1 -1
- package/dist/esm/api/agentsContext.js +7 -19
- package/dist/esm/api/agentsContext.js.map +1 -1
- package/dist/esm/models/models.d.ts +1 -1
- package/dist/esm/models/models.d.ts.map +1 -1
- package/dist/esm/models/models.js +2 -0
- package/dist/esm/models/models.js.map +1 -1
- package/dist/esm/static-helpers/urlTemplate.d.ts.map +1 -1
- package/dist/esm/static-helpers/urlTemplate.js +2 -2
- package/dist/esm/static-helpers/urlTemplate.js.map +1 -1
- package/dist/react-native/api/agentsContext.d.ts.map +1 -1
- package/dist/react-native/api/agentsContext.js +7 -19
- package/dist/react-native/api/agentsContext.js.map +1 -1
- package/dist/react-native/models/models.d.ts +1 -1
- package/dist/react-native/models/models.d.ts.map +1 -1
- package/dist/react-native/models/models.js +2 -0
- package/dist/react-native/models/models.js.map +1 -1
- package/dist/react-native/static-helpers/urlTemplate.d.ts.map +1 -1
- package/dist/react-native/static-helpers/urlTemplate.js +2 -2
- package/dist/react-native/static-helpers/urlTemplate.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Azure AI
|
|
1
|
+
# Azure AI Agents client library for JavaScript
|
|
2
2
|
|
|
3
|
-
Use the AI
|
|
3
|
+
Use the AI Agents client library (in preview) to:
|
|
4
4
|
|
|
5
5
|
- **Enumerate connections** in your Azure AI Foundry project and get connection properties.
|
|
6
6
|
For example, get the inference endpoint URL and credentials associated with your Azure OpenAI connection.
|
|
@@ -9,8 +9,8 @@ Use the AI Projects client library (in preview) to:
|
|
|
9
9
|
|
|
10
10
|
[Product documentation](https://aka.ms/azsdk/azure-ai-projects/product-doc)
|
|
11
11
|
|
|
12
|
-
| [Samples](https://github.com/Azure/azure-sdk-for-js/tree/
|
|
13
|
-
| [Package (npm)](https://www.npmjs.com/package/@azure/ai-
|
|
12
|
+
| [Samples](https://github.com/Azure/azure-sdk-for-js/tree/feature/azure-ai-agents/sdk/ai/ai-agents/samples)
|
|
13
|
+
| [Package (npm)](https://www.npmjs.com/package/@azure/ai-agents)
|
|
14
14
|
| [API reference documentation](https://learn.microsoft.com/javascript/api/overview/azure/ai-projects-readme?view=azure-node-preview)
|
|
15
15
|
|
|
16
16
|
## Table of contents
|
|
@@ -60,7 +60,7 @@ Use the AI Projects client library (in preview) to:
|
|
|
60
60
|
- [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule)
|
|
61
61
|
- An [Azure subscription][azure_sub].
|
|
62
62
|
- A [project in Azure AI Foundry](https://learn.microsoft.com/azure/ai-studio/how-to/create-projects?tabs=ai-studio).
|
|
63
|
-
- The project
|
|
63
|
+
- The project endpoint. 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
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
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.
|
|
66
66
|
- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed.
|
|
@@ -80,21 +80,19 @@ npm install @azure/ai-agents @azure/identity
|
|
|
80
80
|
The class factory method `fromConnectionString` is used to construct the client. To construct a client:
|
|
81
81
|
|
|
82
82
|
```ts snippet:setup
|
|
83
|
-
import {
|
|
83
|
+
import { AgentsClient } from "@azure/ai-agents";
|
|
84
84
|
import { DefaultAzureCredential } from "@azure/identity";
|
|
85
85
|
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
new DefaultAzureCredential(),
|
|
90
|
-
);
|
|
86
|
+
const projectEndpoint = process.env["PROJECT_ENDPOINT"] || "<project endpoint>";
|
|
87
|
+
const modelDeploymentName = process.env["MODEL_DEPLOYMENT_NAME"] || "gpt-4o";
|
|
88
|
+
const client = new AgentsClient(projectEndpoint, new DefaultAzureCredential());
|
|
91
89
|
```
|
|
92
90
|
|
|
93
91
|
## Examples
|
|
94
92
|
|
|
95
93
|
### Agents (Preview)
|
|
96
94
|
|
|
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/
|
|
95
|
+
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/feature/azure-ai-agents/sdk/ai/ai-agents/samples) for additional Agent samples.
|
|
98
96
|
|
|
99
97
|
Agents are actively being developed. A sign-up form for private preview is coming soon.
|
|
100
98
|
|
|
@@ -103,7 +101,7 @@ Agents are actively being developed. A sign-up form for private preview is comin
|
|
|
103
101
|
Here is an example of how to create an Agent:
|
|
104
102
|
|
|
105
103
|
```ts snippet:createAgent
|
|
106
|
-
const agent = await client.
|
|
104
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
107
105
|
name: "my-agent",
|
|
108
106
|
instructions: "You are a helpful assistant",
|
|
109
107
|
});
|
|
@@ -114,12 +112,15 @@ To allow Agents to access your resources or custom functions, you need tools. Yo
|
|
|
114
112
|
You can use `ToolSet` to do this:
|
|
115
113
|
|
|
116
114
|
```ts snippet:toolSet
|
|
117
|
-
import { ToolSet } from "@azure/ai-
|
|
115
|
+
import { ToolSet } from "@azure/ai-agents";
|
|
118
116
|
|
|
117
|
+
// Create tool set
|
|
119
118
|
const toolSet = new ToolSet();
|
|
120
|
-
toolSet.addFileSearchTool([vectorStore.id]);
|
|
121
|
-
toolSet.addCodeInterpreterTool([codeInterpreterFile.id]);
|
|
122
|
-
|
|
119
|
+
await toolSet.addFileSearchTool([vectorStore.id]);
|
|
120
|
+
await toolSet.addCodeInterpreterTool([codeInterpreterFile.id]);
|
|
121
|
+
|
|
122
|
+
// Create agent with tool set
|
|
123
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
123
124
|
name: "my-agent",
|
|
124
125
|
instructions: "You are a helpful agent",
|
|
125
126
|
tools: toolSet.toolDefinitions,
|
|
@@ -133,20 +134,24 @@ console.log(`Created agent, agent ID: ${agent.id}`);
|
|
|
133
134
|
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
135
|
|
|
135
136
|
```ts snippet:fileSearch
|
|
136
|
-
import { ToolUtility } from "@azure/ai-
|
|
137
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
137
138
|
|
|
139
|
+
const filePath = "./data/sampleFileForUpload.txt";
|
|
138
140
|
const localFileStream = fs.createReadStream(filePath);
|
|
139
|
-
const file = await client.
|
|
140
|
-
fileName: "
|
|
141
|
+
const file = await client.files.upload(localFileStream, "assistants", {
|
|
142
|
+
fileName: "sampleFileForUpload.txt",
|
|
141
143
|
});
|
|
142
|
-
console.log(`Uploaded file, ID: ${file.id}`);
|
|
143
|
-
|
|
144
|
+
console.log(`Uploaded file, file ID: ${file.id}`);
|
|
145
|
+
|
|
146
|
+
const vectorStore = await client.vectorStores.create({
|
|
144
147
|
fileIds: [file.id],
|
|
145
|
-
name: "
|
|
148
|
+
name: "myVectorStore",
|
|
146
149
|
});
|
|
147
|
-
console.log(`Created vector store, ID: ${vectorStore.id}`);
|
|
150
|
+
console.log(`Created vector store, vector store ID: ${vectorStore.id}`);
|
|
151
|
+
|
|
148
152
|
const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
|
|
149
|
-
|
|
153
|
+
|
|
154
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
150
155
|
name: "SDK Test Agent - Retrieval",
|
|
151
156
|
instructions: "You are helpful agent that can help fetch data from files you know about.",
|
|
152
157
|
tools: [fileSearchTool.definition],
|
|
@@ -160,16 +165,20 @@ console.log(`Created agent, agent ID : ${agent.id}`);
|
|
|
160
165
|
Here is an example to upload a file and use it for code interpreter by an Agent:
|
|
161
166
|
|
|
162
167
|
```ts snippet:codeInterpreter
|
|
163
|
-
import { ToolUtility } from "@azure/ai-
|
|
168
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
164
169
|
|
|
170
|
+
const filePath = "./data/nifty500QuarterlyResults.csv";
|
|
165
171
|
const localFileStream = fs.createReadStream(filePath);
|
|
166
|
-
const localFile = await client.
|
|
172
|
+
const localFile = await client.files.upload(localFileStream, "assistants", {
|
|
167
173
|
fileName: "localFile",
|
|
168
174
|
});
|
|
175
|
+
|
|
169
176
|
console.log(`Uploaded local file, file ID : ${localFile.id}`);
|
|
177
|
+
|
|
170
178
|
const codeInterpreterTool = ToolUtility.createCodeInterpreterTool([localFile.id]);
|
|
179
|
+
|
|
171
180
|
// 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.
|
|
181
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
173
182
|
name: "my-agent",
|
|
174
183
|
instructions: "You are a helpful agent",
|
|
175
184
|
tools: [codeInterpreterTool.definition],
|
|
@@ -185,14 +194,15 @@ To enable your Agent to perform search through Bing search API, you use `ToolUti
|
|
|
185
194
|
Here is an example:
|
|
186
195
|
|
|
187
196
|
```ts snippet:bingGrounding
|
|
188
|
-
import { ToolUtility
|
|
197
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
189
198
|
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
199
|
+
const connectionId = process.env["AZURE_BING_CONNECTION_ID"] || "<connection-name>";
|
|
200
|
+
|
|
201
|
+
// Initialize agent bing tool with the connection id
|
|
202
|
+
const bingTool = ToolUtility.createBingGroundingTool([{ connectionId: connectionId }]);
|
|
203
|
+
|
|
204
|
+
// Create agent with the bing tool and process assistant run
|
|
205
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
196
206
|
name: "my-agent",
|
|
197
207
|
instructions: "You are a helpful agent",
|
|
198
208
|
tools: [bingTool.definition],
|
|
@@ -207,13 +217,21 @@ Azure AI Search is an enterprise search system for high-performance applications
|
|
|
207
217
|
Here is an example to integrate Azure AI Search:
|
|
208
218
|
|
|
209
219
|
```ts snippet:AISearch
|
|
210
|
-
import { ToolUtility } from "@azure/ai-
|
|
220
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
221
|
+
|
|
222
|
+
const connectionId = process.env["AZURE_AI_CONNECTION_ID"] || "<connection-name>";
|
|
223
|
+
|
|
224
|
+
// Initialize Azure AI Search tool
|
|
225
|
+
const azureAISearchTool = ToolUtility.createAzureAISearchTool(connectionId, "ai-search-sample", {
|
|
226
|
+
queryType: "simple",
|
|
227
|
+
topK: 3,
|
|
228
|
+
filter: "",
|
|
229
|
+
indexConnectionId: "",
|
|
230
|
+
indexName: "",
|
|
231
|
+
});
|
|
211
232
|
|
|
212
|
-
|
|
213
|
-
|
|
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", {
|
|
233
|
+
// Create agent with the Azure AI search tool
|
|
234
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
217
235
|
name: "my-agent",
|
|
218
236
|
instructions: "You are a helpful agent",
|
|
219
237
|
tools: [azureAISearchTool.definition],
|
|
@@ -232,16 +250,16 @@ Here is an example:
|
|
|
232
250
|
import {
|
|
233
251
|
FunctionToolDefinition,
|
|
234
252
|
ToolUtility,
|
|
235
|
-
|
|
236
|
-
FunctionToolDefinitionOutput,
|
|
253
|
+
RequiredToolCall,
|
|
237
254
|
ToolOutput,
|
|
238
|
-
} from "@azure/ai-
|
|
255
|
+
} from "@azure/ai-agents";
|
|
239
256
|
|
|
240
257
|
class FunctionToolExecutor {
|
|
241
258
|
private functionTools: {
|
|
242
259
|
func: Function;
|
|
243
260
|
definition: FunctionToolDefinition;
|
|
244
261
|
}[];
|
|
262
|
+
|
|
245
263
|
constructor() {
|
|
246
264
|
this.functionTools = [
|
|
247
265
|
{
|
|
@@ -281,18 +299,20 @@ class FunctionToolExecutor {
|
|
|
281
299
|
},
|
|
282
300
|
];
|
|
283
301
|
}
|
|
302
|
+
|
|
284
303
|
private getUserFavoriteCity(): {} {
|
|
285
304
|
return { location: "Seattle, WA" };
|
|
286
305
|
}
|
|
287
|
-
|
|
306
|
+
|
|
307
|
+
private getCityNickname(_location: string): {} {
|
|
288
308
|
return { nickname: "The Emerald City" };
|
|
289
309
|
}
|
|
290
|
-
|
|
310
|
+
|
|
311
|
+
private getWeather(_location: string, unit: string): {} {
|
|
291
312
|
return { weather: unit === "f" ? "72f" : "22c" };
|
|
292
313
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
): ToolOutput | undefined {
|
|
314
|
+
|
|
315
|
+
public invokeTool(toolCall: RequiredToolCall & FunctionToolDefinition): ToolOutput | undefined {
|
|
296
316
|
console.log(`Function tool call - ${toolCall.function.name}`);
|
|
297
317
|
const args = [];
|
|
298
318
|
if (toolCall.function.parameters) {
|
|
@@ -318,6 +338,7 @@ class FunctionToolExecutor {
|
|
|
318
338
|
}
|
|
319
339
|
: undefined;
|
|
320
340
|
}
|
|
341
|
+
|
|
321
342
|
public getFunctionDefinitions(): FunctionToolDefinition[] {
|
|
322
343
|
return this.functionTools.map((tool) => {
|
|
323
344
|
return tool.definition;
|
|
@@ -326,7 +347,7 @@ class FunctionToolExecutor {
|
|
|
326
347
|
}
|
|
327
348
|
const functionToolExecutor = new FunctionToolExecutor();
|
|
328
349
|
const functionTools = functionToolExecutor.getFunctionDefinitions();
|
|
329
|
-
const agent = await client.
|
|
350
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
330
351
|
name: "my-agent",
|
|
331
352
|
instructions:
|
|
332
353
|
"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 +362,12 @@ OpenAPI specifications describe REST operations against a specific endpoint. Age
|
|
|
341
362
|
Here is an example creating an OpenAPI tool (using anonymous authentication):
|
|
342
363
|
|
|
343
364
|
```ts snippet:createAgentWithOpenApi
|
|
344
|
-
import { ToolUtility } from "@azure/ai-
|
|
365
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
345
366
|
|
|
346
367
|
// Read in OpenApi spec
|
|
347
368
|
const filePath = "./data/weatherOpenApi.json";
|
|
348
369
|
const openApiSpec = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
370
|
+
|
|
349
371
|
// Define OpenApi function
|
|
350
372
|
const openApiFunction = {
|
|
351
373
|
name: "getWeather",
|
|
@@ -356,10 +378,12 @@ const openApiFunction = {
|
|
|
356
378
|
},
|
|
357
379
|
default_params: ["format"], // optional
|
|
358
380
|
};
|
|
381
|
+
|
|
359
382
|
// Create OpenApi tool
|
|
360
383
|
const openApiTool = ToolUtility.createOpenApiTool(openApiFunction);
|
|
384
|
+
|
|
361
385
|
// Create agent with OpenApi tool
|
|
362
|
-
const agent = await client.
|
|
386
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
363
387
|
name: "myAgent",
|
|
364
388
|
instructions: "You are a helpful agent",
|
|
365
389
|
tools: [openApiTool.definition],
|
|
@@ -374,16 +398,15 @@ To enable your Agent to answer queries using Fabric data, use `FabricTool` along
|
|
|
374
398
|
Here is an example:
|
|
375
399
|
|
|
376
400
|
```ts snippet:createAgentWithFabric
|
|
377
|
-
import { ToolUtility } from "@azure/ai-
|
|
401
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
402
|
+
|
|
403
|
+
const connectionId = process.env["FABRIC_CONNECTION_ID"] || "<connection-name>";
|
|
378
404
|
|
|
379
|
-
const fabricConnection = await client.connections.getConnection(
|
|
380
|
-
process.env["FABRIC_CONNECTION_NAME"] || "<connection-name>",
|
|
381
|
-
);
|
|
382
|
-
const connectionId = fabricConnection.id;
|
|
383
405
|
// Initialize agent Microsoft Fabric tool with the connection id
|
|
384
406
|
const fabricTool = ToolUtility.createFabricTool(connectionId);
|
|
407
|
+
|
|
385
408
|
// Create agent with the Microsoft Fabric tool and process assistant run
|
|
386
|
-
const agent = await client.
|
|
409
|
+
const agent = await client.createAgent("gpt-4o", {
|
|
387
410
|
name: "my-agent",
|
|
388
411
|
instructions: "You are a helpful agent",
|
|
389
412
|
tools: [fabricTool.definition],
|
|
@@ -396,7 +419,8 @@ console.log(`Created agent, agent ID : ${agent.id}`);
|
|
|
396
419
|
For each session or conversation, a thread is required. Here is an example:
|
|
397
420
|
|
|
398
421
|
```ts snippet:createThread
|
|
399
|
-
const thread = await client.
|
|
422
|
+
const thread = await client.threads.create();
|
|
423
|
+
console.log(`Created thread, thread ID: ${thread.id}`);
|
|
400
424
|
```
|
|
401
425
|
|
|
402
426
|
#### Create Thread with Tool Resource
|
|
@@ -404,27 +428,32 @@ const thread = await client.agents.createThread();
|
|
|
404
428
|
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.
|
|
405
429
|
|
|
406
430
|
```ts snippet:threadWithTool
|
|
407
|
-
import { ToolUtility } from "@azure/ai-
|
|
431
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
408
432
|
|
|
433
|
+
const filePath = "./data/nifty500QuarterlyResults.csv";
|
|
409
434
|
const localFileStream = fs.createReadStream(filePath);
|
|
410
|
-
const file = await client.
|
|
435
|
+
const file = await client.files.upload(localFileStream, "assistants", {
|
|
411
436
|
fileName: "sample_file_for_upload.csv",
|
|
412
437
|
});
|
|
413
438
|
console.log(`Uploaded file, ID: ${file.id}`);
|
|
414
|
-
|
|
439
|
+
|
|
440
|
+
const vectorStore = await client.agents.vectorStores.create()({
|
|
415
441
|
fileIds: [file.id],
|
|
416
442
|
});
|
|
417
443
|
console.log(`Created vector store, ID: ${vectorStore.id}`);
|
|
444
|
+
|
|
418
445
|
const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
|
|
446
|
+
|
|
419
447
|
const agent = await client.agents.createAgent("gpt-4o", {
|
|
420
448
|
name: "myAgent",
|
|
421
449
|
instructions: "You are helpful agent that can help fetch data from files you know about.",
|
|
422
450
|
tools: [fileSearchTool.definition],
|
|
423
451
|
});
|
|
424
452
|
console.log(`Created agent, agent ID : ${agent.id}`);
|
|
453
|
+
|
|
425
454
|
// Create thread with file resources.
|
|
426
455
|
// If the agent has multiple threads, only this thread can search this file.
|
|
427
|
-
const thread = await client.
|
|
456
|
+
const thread = await client.threads.create({ toolResources: fileSearchTool.resources });
|
|
428
457
|
```
|
|
429
458
|
|
|
430
459
|
#### List Threads
|
|
@@ -432,9 +461,9 @@ const thread = await client.agents.createThread({ toolResources: fileSearchTool.
|
|
|
432
461
|
To list all threads attached to a given agent, use the list_threads API:
|
|
433
462
|
|
|
434
463
|
```ts snippet:listThreads
|
|
435
|
-
const threads =
|
|
464
|
+
const threads = client.threads.list();
|
|
436
465
|
console.log(`Threads for agent ${agent.id}:`);
|
|
437
|
-
for await (const t of
|
|
466
|
+
for await (const t of threads) {
|
|
438
467
|
console.log(`Thread ID: ${t.id}`);
|
|
439
468
|
console.log(`Created at: ${t.createdAt}`);
|
|
440
469
|
console.log(`Metadata: ${t.metadata}`);
|
|
@@ -447,10 +476,7 @@ for await (const t of (await threads).data) {
|
|
|
447
476
|
To create a message for assistant to process, you pass `user` as `role` and a question as `content`:
|
|
448
477
|
|
|
449
478
|
```ts snippet:createMessage
|
|
450
|
-
const message = await client.
|
|
451
|
-
role: "user",
|
|
452
|
-
content: "hello, world!",
|
|
453
|
-
});
|
|
479
|
+
const message = await client.messages.create(thread.id, "user", "hello, world!");
|
|
454
480
|
console.log(`Created message, message ID: ${message.id}`);
|
|
455
481
|
```
|
|
456
482
|
|
|
@@ -459,17 +485,22 @@ console.log(`Created message, message ID: ${message.id}`);
|
|
|
459
485
|
To attach a file to a message for content searching, you use `ToolUtility.createFileSearchTool()` and the `attachments` argument:
|
|
460
486
|
|
|
461
487
|
```ts snippet:messageWithFileSearch
|
|
462
|
-
import { ToolUtility } from "@azure/ai-
|
|
488
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
463
489
|
|
|
464
490
|
const fileSearchTool = ToolUtility.createFileSearchTool();
|
|
465
|
-
const message = await client.
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
491
|
+
const message = await client.messages.create(
|
|
492
|
+
thread.id,
|
|
493
|
+
"user",
|
|
494
|
+
"What feature does Smart Eyewear offer?",
|
|
495
|
+
{
|
|
496
|
+
attachments: [
|
|
497
|
+
{
|
|
498
|
+
fileId: file.id,
|
|
499
|
+
tools: [fileSearchTool.definition],
|
|
500
|
+
},
|
|
501
|
+
],
|
|
471
502
|
},
|
|
472
|
-
|
|
503
|
+
);
|
|
473
504
|
```
|
|
474
505
|
|
|
475
506
|
#### Create Message with Code Interpreter Attachment
|
|
@@ -479,28 +510,34 @@ To attach a file to a message for data analysis, you use `ToolUtility.createCode
|
|
|
479
510
|
Here is an example:
|
|
480
511
|
|
|
481
512
|
```ts snippet:messageWithCodeInterpreter
|
|
482
|
-
import { ToolUtility } from "@azure/ai-
|
|
513
|
+
import { ToolUtility } from "@azure/ai-agents";
|
|
483
514
|
|
|
484
515
|
// notice that CodeInterpreter must be enabled in the agent creation,
|
|
485
516
|
// otherwise the agent will not be able to see the file attachment for code interpretation
|
|
486
517
|
const codeInterpreterTool = ToolUtility.createCodeInterpreterTool();
|
|
487
|
-
const agent = await client.agents.createAgent("gpt-
|
|
518
|
+
const agent = await client.agents.createAgent("gpt-4o", {
|
|
488
519
|
name: "my-assistant",
|
|
489
520
|
instructions: "You are helpful assistant",
|
|
490
521
|
tools: [codeInterpreterTool.definition],
|
|
491
522
|
});
|
|
492
523
|
console.log(`Created agent, agent ID: ${agent.id}`);
|
|
493
|
-
|
|
524
|
+
|
|
525
|
+
const thread = await client.threads.create();
|
|
494
526
|
console.log(`Created thread, thread ID: ${thread.id}`);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
527
|
+
|
|
528
|
+
const message = await client.messages.create(
|
|
529
|
+
thread.id,
|
|
530
|
+
"user",
|
|
531
|
+
"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?",
|
|
532
|
+
{
|
|
533
|
+
attachments: [
|
|
534
|
+
{
|
|
535
|
+
fileId: file.id,
|
|
536
|
+
tools: [codeInterpreterTool.definition],
|
|
537
|
+
},
|
|
538
|
+
],
|
|
502
539
|
},
|
|
503
|
-
|
|
540
|
+
);
|
|
504
541
|
console.log(`Created message, message ID: ${message.id}`);
|
|
505
542
|
```
|
|
506
543
|
|
|
@@ -517,12 +554,14 @@ The following examples demonstrate each method:
|
|
|
517
554
|
##### Create message using uploaded image file
|
|
518
555
|
|
|
519
556
|
```ts snippet:imageInputWithFile
|
|
557
|
+
const imagePath = "./data/image_file.png";
|
|
520
558
|
// Upload the local image file
|
|
521
559
|
const fileStream = fs.createReadStream(imagePath);
|
|
522
|
-
const imageFile = await client.
|
|
560
|
+
const imageFile = await client.files.upload(fileStream, "assistants", {
|
|
523
561
|
fileName: "image_file.png",
|
|
524
562
|
});
|
|
525
563
|
console.log(`Uploaded file, file ID: ${imageFile.id}`);
|
|
564
|
+
|
|
526
565
|
// Create a message with both text and image content
|
|
527
566
|
console.log("Creating message with image content...");
|
|
528
567
|
const inputMessage = "Hello, what is in the image?";
|
|
@@ -539,20 +578,18 @@ const content = [
|
|
|
539
578
|
},
|
|
540
579
|
},
|
|
541
580
|
];
|
|
542
|
-
const message = await client.
|
|
543
|
-
role: "user",
|
|
544
|
-
content: content,
|
|
545
|
-
});
|
|
581
|
+
const message = await client.messages.create(thread.id, "user", content);
|
|
546
582
|
console.log(`Created message, message ID: ${message.id}`);
|
|
547
583
|
```
|
|
548
584
|
|
|
549
585
|
##### Create message with an image URL input
|
|
550
586
|
|
|
551
587
|
```ts snippet:imageInputWithUrl
|
|
552
|
-
// Specify the public image URL
|
|
553
588
|
const imageUrl =
|
|
554
589
|
"https://github.com/Azure/azure-sdk-for-js/blob/0aa88ceb18d865726d423f73b8393134e783aea6/sdk/ai/ai-projects/data/image_file.png?raw=true";
|
|
555
|
-
|
|
590
|
+
|
|
591
|
+
// Create a message with both text and image content
|
|
592
|
+
console.log("Creating message with image content...");
|
|
556
593
|
const inputMessage = "Hello, what is in the image?";
|
|
557
594
|
const content = [
|
|
558
595
|
{
|
|
@@ -567,10 +604,8 @@ const content = [
|
|
|
567
604
|
},
|
|
568
605
|
},
|
|
569
606
|
];
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
content: content,
|
|
573
|
-
});
|
|
607
|
+
|
|
608
|
+
const message = await client.messages.create(thread.id, "user", content);
|
|
574
609
|
console.log(`Created message, message ID: ${message.id}`);
|
|
575
610
|
```
|
|
576
611
|
|
|
@@ -590,9 +625,13 @@ function imageToBase64DataUrl(imagePath: string, mimeType: string): string {
|
|
|
590
625
|
throw error;
|
|
591
626
|
}
|
|
592
627
|
}
|
|
628
|
+
|
|
593
629
|
// Convert your image file to base64 format
|
|
630
|
+
const filePath = "./data/image_file.png";
|
|
594
631
|
const imageDataUrl = imageToBase64DataUrl(filePath, "image/png");
|
|
632
|
+
|
|
595
633
|
// Create a message with both text and image content
|
|
634
|
+
console.log("Creating message with image content...");
|
|
596
635
|
const inputMessage = "Hello, what is in the image?";
|
|
597
636
|
const content = [
|
|
598
637
|
{
|
|
@@ -607,10 +646,8 @@ const content = [
|
|
|
607
646
|
},
|
|
608
647
|
},
|
|
609
648
|
];
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
content: content,
|
|
613
|
-
});
|
|
649
|
+
|
|
650
|
+
const message = await client.messages.create(thread.id, "user", content);
|
|
614
651
|
console.log(`Created message, message ID: ${message.id}`);
|
|
615
652
|
```
|
|
616
653
|
|
|
@@ -619,16 +656,16 @@ console.log(`Created message, message ID: ${message.id}`);
|
|
|
619
656
|
Here is an example of `createRun` and poll until the run is completed:
|
|
620
657
|
|
|
621
658
|
```ts snippet:createRun
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
) {
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
659
|
+
import { delay } from "@azure/core-util";
|
|
660
|
+
|
|
661
|
+
let run = await client.runs.create(thread.id, agent.id);
|
|
662
|
+
console.log(`Created run, run ID: ${run.id}`);
|
|
663
|
+
|
|
664
|
+
// Wait for run to complete
|
|
665
|
+
while (["queued", "in_progress", "requires_action"].includes(run.status)) {
|
|
666
|
+
await delay(1000);
|
|
667
|
+
run = await client.runs.get(thread.id, run.id);
|
|
668
|
+
console.log(`Run status: ${run.status}`);
|
|
632
669
|
}
|
|
633
670
|
```
|
|
634
671
|
|
|
@@ -637,7 +674,7 @@ To have the SDK poll on your behalf, use the `createThreadAndRun` method.
|
|
|
637
674
|
Here is an example:
|
|
638
675
|
|
|
639
676
|
```ts snippet:createThreadAndRun
|
|
640
|
-
const run = await client.
|
|
677
|
+
const run = await client.runs.createThreadAndRun(agent.id, {
|
|
641
678
|
thread: {
|
|
642
679
|
messages: [
|
|
643
680
|
{
|
|
@@ -654,7 +691,7 @@ With streaming, polling also need not be considered.
|
|
|
654
691
|
Here is an example:
|
|
655
692
|
|
|
656
693
|
```ts snippet:createRunStream
|
|
657
|
-
const streamEventMessages = await client.
|
|
694
|
+
const streamEventMessages = await client.runs.create(thread.id, agent.id).stream();
|
|
658
695
|
```
|
|
659
696
|
|
|
660
697
|
Event handling can be done as follows:
|
|
@@ -662,18 +699,20 @@ Event handling can be done as follows:
|
|
|
662
699
|
```ts snippet:eventHandling
|
|
663
700
|
import {
|
|
664
701
|
RunStreamEvent,
|
|
665
|
-
|
|
702
|
+
ThreadRun,
|
|
666
703
|
MessageStreamEvent,
|
|
667
704
|
MessageDeltaChunk,
|
|
668
705
|
MessageDeltaTextContent,
|
|
706
|
+
ErrorEvent,
|
|
669
707
|
DoneEvent,
|
|
670
|
-
} from "@azure/ai-
|
|
708
|
+
} from "@azure/ai-agents";
|
|
709
|
+
|
|
710
|
+
const streamEventMessages = await client.runs.create(thread.id, agent.id).stream();
|
|
671
711
|
|
|
672
|
-
const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();
|
|
673
712
|
for await (const eventMessage of streamEventMessages) {
|
|
674
713
|
switch (eventMessage.event) {
|
|
675
714
|
case RunStreamEvent.ThreadRunCreated:
|
|
676
|
-
console.log(`ThreadRun status: ${(eventMessage.data as
|
|
715
|
+
console.log(`ThreadRun status: ${(eventMessage.data as ThreadRun).status}`);
|
|
677
716
|
break;
|
|
678
717
|
case MessageStreamEvent.ThreadMessageDelta:
|
|
679
718
|
{
|
|
@@ -687,6 +726,7 @@ for await (const eventMessage of streamEventMessages) {
|
|
|
687
726
|
});
|
|
688
727
|
}
|
|
689
728
|
break;
|
|
729
|
+
|
|
690
730
|
case RunStreamEvent.ThreadRunCompleted:
|
|
691
731
|
console.log("Thread Run Completed");
|
|
692
732
|
break;
|
|
@@ -705,26 +745,23 @@ for await (const eventMessage of streamEventMessages) {
|
|
|
705
745
|
To retrieve messages from agents, use the following example:
|
|
706
746
|
|
|
707
747
|
```ts snippet:listMessages
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
const
|
|
711
|
-
|
|
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;
|
|
748
|
+
const messagesIterator = client.messages.list(thread.id);
|
|
749
|
+
const allMessages = [];
|
|
750
|
+
for await (const m of messagesIterator) {
|
|
751
|
+
allMessages.push(m);
|
|
718
752
|
}
|
|
753
|
+
console.log("Messages:", allMessages);
|
|
754
|
+
|
|
719
755
|
// The messages are following in the reverse order,
|
|
720
756
|
// we will iterate them and output only text contents.
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
757
|
+
const messages = await client.messages.list(thread.id, {
|
|
758
|
+
order: "asc",
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
for await (const dataPoint of messages) {
|
|
762
|
+
const textContent = dataPoint.content.find((item) => item.type === "text");
|
|
763
|
+
if (textContent && "text" in textContent) {
|
|
764
|
+
console.log(`${dataPoint.role}: ${textContent.text.value}`);
|
|
728
765
|
}
|
|
729
766
|
}
|
|
730
767
|
```
|
|
@@ -736,32 +773,34 @@ Files uploaded by Agents cannot be retrieved back. If your use case needs to acc
|
|
|
736
773
|
Here is an example retrieving file ids from messages:
|
|
737
774
|
|
|
738
775
|
```ts snippet:retrieveFile
|
|
739
|
-
import {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
776
|
+
import { isOutputOfType, MessageTextContent, MessageImageFileContent } from "@azure/ai-agents";
|
|
777
|
+
|
|
778
|
+
const messagesIterator = client.messages.list(thread.id);
|
|
779
|
+
const allMessages = [];
|
|
780
|
+
for await (const m of messagesIterator) {
|
|
781
|
+
allMessages.push(m);
|
|
782
|
+
}
|
|
783
|
+
console.log("Messages:", allMessages);
|
|
744
784
|
|
|
745
|
-
const messages = await client.agents.listMessages(thread.id);
|
|
746
785
|
// Get most recent message from the assistant
|
|
747
|
-
const assistantMessage =
|
|
786
|
+
const assistantMessage = allMessages.find((msg) => msg.role === "assistant");
|
|
748
787
|
if (assistantMessage) {
|
|
749
788
|
const textContent = assistantMessage.content.find((content) =>
|
|
750
|
-
isOutputOfType<
|
|
751
|
-
) as
|
|
789
|
+
isOutputOfType<MessageTextContent>(content, "text"),
|
|
790
|
+
) as MessageTextContent;
|
|
752
791
|
if (textContent) {
|
|
753
792
|
console.log(`Last message: ${textContent.text.value}`);
|
|
754
793
|
}
|
|
755
794
|
}
|
|
756
|
-
|
|
757
|
-
const
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
).body;
|
|
795
|
+
|
|
796
|
+
const imageFile = (allMessages[0].content[0] as MessageImageFileContent).imageFile;
|
|
797
|
+
const imageFileName = (await client.agents.files.get(imageFile.fileId)).filename;
|
|
798
|
+
|
|
799
|
+
const fileContent = await (await client.files.getContent(imageFile.fileId).asNodeStream()).body;
|
|
761
800
|
if (fileContent) {
|
|
762
801
|
const chunks: Buffer[] = [];
|
|
763
802
|
for await (const chunk of fileContent) {
|
|
764
|
-
chunks.push(Buffer.from(chunk));
|
|
803
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
765
804
|
}
|
|
766
805
|
const buffer = Buffer.concat(chunks);
|
|
767
806
|
fs.writeFileSync(imageFileName, buffer);
|
|
@@ -776,71 +815,14 @@ console.log(`Saved image file to: ${imageFileName}`);
|
|
|
776
815
|
To remove resources after completing tasks, use the following functions:
|
|
777
816
|
|
|
778
817
|
```ts snippet:teardown
|
|
779
|
-
await client.
|
|
818
|
+
await client.vectorStores.delete(vectorStore.id);
|
|
780
819
|
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
|
-
|
|
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.
|
|
790
|
-
|
|
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
820
|
|
|
812
|
-
|
|
821
|
+
await client.files.delete(file.id);
|
|
822
|
+
console.log(`Deleted file, file ID : ${file.id}`);
|
|
813
823
|
|
|
814
|
-
|
|
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
|
-
});
|
|
824
|
+
await client.deleteAgent(agent.id);
|
|
825
|
+
console.log(`Deleted agent, agent ID: ${agent.id}`);
|
|
844
826
|
```
|
|
845
827
|
|
|
846
828
|
## Troubleshooting
|
|
@@ -877,7 +859,7 @@ To report issues with the client library, or request additional features, please
|
|
|
877
859
|
|
|
878
860
|
## Next steps
|
|
879
861
|
|
|
880
|
-
Have a look at the [package samples](https://github.com/Azure/azure-sdk-for-js/tree/
|
|
862
|
+
Have a look at the [package samples](https://github.com/Azure/azure-sdk-for-js/tree/feature/azure-ai-agents/sdk/ai/ai-agents/samples) folder, containing fully runnable code.
|
|
881
863
|
|
|
882
864
|
## Contributing
|
|
883
865
|
|