diff --git a/samples/microsoft/javascript/mslearn-resources/quickstart/src/quickstart.js b/samples/microsoft/javascript/mslearn-resources/quickstart/src/quickstart.js
index 6ca834dfc..5d3c53068 100644
--- a/samples/microsoft/javascript/mslearn-resources/quickstart/src/quickstart.js
+++ b/samples/microsoft/javascript/mslearn-resources/quickstart/src/quickstart.js
@@ -1,9 +1,14 @@
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
import { DefaultAzureCredential } from '@azure/identity';
import { AIProjectClient } from '@azure/ai-projects';
-import { AgentsClient } from '@azure/ai-agents';
+import { AgentsClient, ToolUtility, DoneEvent, ErrorEvent, RunStreamEvent, MessageStreamEvent } from '@azure/ai-agents';
import { config } from 'dotenv';
config();
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
async function chatCompletion() {
//
const endpoint = process.env.INFERENCE_ENDPOINT;
@@ -11,7 +16,6 @@ async function chatCompletion() {
const project = new AIProjectClient(endpoint, new DefaultAzureCredential());
const client = project.inference.azureOpenAI();
-
const chatCompletion = await client.chat.completions.create({
deployment,
messages: [
@@ -24,9 +28,9 @@ async function chatCompletion() {
//
}
-chatCompletion().catch(console.error);
+// chatCompletion().catch(console.error);
-async function runAgent() {
+async function runAgents() {
//
// Create an Azure AI Client
@@ -39,36 +43,140 @@ async function runAgent() {
name: 'my-agent',
instructions: 'You are a helpful agent',
});
+ console.log(`\n==================== ๐ต๏ธ POEM AGENT ====================`);
- // Create a thread and mesage
+ // Create a thread and message
const thread = await client.createThread();
- const message = await client.createMessage(thread.id, 'user', 'hello, world!');
-
- console.log(`Created message, message ID: ${message.id}`);
+ const prompt = 'Write me a poem about flowers';
+ console.log(`\n---------------- ๐ User Prompt ---------------- \n${prompt}`);
+ await client.createMessage(thread.id, 'user', prompt);
// Create run
let run = await client.createRun(thread.id, agent.id);
- console.log(`Usage for run ${run.id}:`, JSON.stringify(run.usage, null, 2));
// Wait for run to complete
+ console.log(`\n---------------- ๐ฆ Run Status ----------------`);
while (['queued', 'in_progress', 'requires_action'].includes(run.status)) {
+ // Avoid adding a lot of messages to the console
await new Promise((resolve) => setTimeout(resolve, 1000));
run = await client.getRun(thread.id, run.id);
console.log(`Run status: ${run.status}`);
}
- console.log(`Usage for run ${run.id}:`, JSON.stringify(run.usage, null, 2));
+ console.log('\n---------------- ๐ Token Usage ----------------');
+ console.table([run.usage]);
+
+ const messages = await client.listMessages(thread.id);
+ const assistantMessage = messages.data.find(m => m.role === 'assistant');
+ console.log('\n---------------- ๐ฌ Response ----------------');
+ printAssistantMessage(assistantMessage);
// Delete the Agent
await client.deleteAgent(agent.id);
console.log(`Deleted Agent, Agent ID: ${agent.id}`);
+
//
//
- // Create the file search agent
-
+ // Upload a file named product_info_1.md
+ console.log(`\n==================== ๐ต๏ธ FILE AGENT ====================`);
+ const filePath = path.join(__dirname, '../../../../data/product_info_1.md');
+ const fileStream = fs.createReadStream(filePath);
+ const file = await client.uploadFile(fileStream, 'assistants', {
+ fileName: 'product_info_1.md'
+ });
+ console.log(`Uploaded file, ID: ${file.id}`);
+ const vectorStore = await client.createVectorStore({
+ fileIds: [file.id],
+ name: 'my_vectorstore'
+ });
+ console.log('\n---------------- ๐๏ธ Vector Store Info ----------------');
+ console.table([
+ {
+ 'Vector Store ID': vectorStore.id,
+ 'Usage (bytes)': vectorStore.usageBytes,
+ 'File Count': vectorStore.fileCounts?.total ?? 'N/A'
+ }
+ ]);
+
+ // Create an Agent and a FileSearch tool
+ const fileSearchTool = ToolUtility.createFileSearchTool([vectorStore.id]);
+ const fileAgent = await client.createAgent(deployment, {
+ name: 'my-file-agent',
+ instructions: 'You are a helpful assistant and can search information from uploaded files',
+ tools: [fileSearchTool.definition],
+ toolResources: fileSearchTool.resources,
+ });
+
+ // Create a thread and message
+ const fileSearchThread = await client.createThread({ toolResources: fileSearchTool.resources });
+ const filePrompt = 'What are the steps to setup the TrailMaster X4 Tent?';
+ console.log(`\n---------------- ๐ User Prompt ---------------- \n${filePrompt}`);
+ await client.createMessage(fileSearchThread.id, 'user', filePrompt);
+
+ // Create run
+ let fileSearchRun = await client.createRun(fileSearchThread.id, fileAgent.id).stream();
+
+ for await (const eventMessage of fileSearchRun) {
+ switch (eventMessage.event) {
+ case RunStreamEvent.ThreadRunCreated:
+ break;
+ case MessageStreamEvent.ThreadMessageDelta:
+ {
+ const messageDelta = eventMessage.data;
+ messageDelta.delta.content.forEach((contentPart) => {
+ if (contentPart.type === "text") {
+ const textContent = contentPart;
+ const textValue = textContent.text?.value || "No text";
+ }
+ });
+ }
+ break;
+
+ case RunStreamEvent.ThreadRunCompleted:
+ break;
+ case ErrorEvent.Error:
+ console.log(`An error occurred. Data ${eventMessage.data}`);
+ break;
+ case DoneEvent.Done:
+ break;
+ }
+ }
+
+ const fileSearchMessages = await client.listMessages(fileSearchThread.id);
+ const fileAssistantMessage = fileSearchMessages.data.find(m => m.role === 'assistant');
+ console.log(`\n---------------- ๐ฌ Response ---------------- \n`);
+ printAssistantMessage(fileAssistantMessage);
+
+ client.deleteVectorStore(vectorStore.id);
+ client.deleteFile(file.id);
+ client.deleteAgent(fileAgent.id);
+ console.log(`\n๐งน Deleted VectorStore, File, and FileAgent. FileAgent ID: ${fileAgent.id}`);
+
//
}
-runAgent().catch(console.error);
+runAgents().catch(console.error);
+
+// Helper function to print assistant message content nicely (handles nested text.value)
+function printAssistantMessage(message) {
+ if (!message || !Array.isArray(message.content)) {
+ console.log('No assistant message found or content is not in expected format.');
+ return;
+ }
+ let output = message.content.map(c => {
+ if (typeof c.text === 'object' && c.text.value) {
+ return c.text.value;
+ } else if (typeof c.text === 'string') {
+ return c.text;
+ } else {
+ return JSON.stringify(c);
+ }
+ }).join('');
+ if (typeof output !== 'string') {
+ console.log('Value is not a string:', output);
+ return;
+ }
+ output.split('\n').forEach(line => console.log(line));
+}