├── .env.template
├── .github
├── CODE_OF_CONDUCT.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── downloads
└── .gitkeep
├── examples
├── 1-basic.ts
├── 2-threads.ts
├── 3-messages.ts
├── 4-streaming.ts
└── 5-run.ts
├── files
├── car_sales_data.csv
└── hotel_reviews_data.csv
├── images
├── prompt-1.mp4
├── prompt-2.mp4
├── prompt-3.mp4
├── prompt-4.mp4
├── prompt-6.mp4
├── prompt-7.mp4
└── prompts.png
├── package-lock.json
├── package.json
├── src
├── config
│ ├── env.ts
│ └── promptConfig.ts
├── index.ts
├── services
│ ├── agentService.ts
│ ├── threadService.ts
│ └── toolService.ts
├── types.ts
└── utils
│ ├── console.ts
│ └── formatting.ts
└── tsconfig.json
/.env.template:
--------------------------------------------------------------------------------
1 | AI_FOUNDRY_PROJECT_CONNECTION_STRING=
2 | BING_GROUNDING_CONNECTION_ID=
3 | AI_SEARCH_CONNECTION_ID=
4 | AI_MODEL=gpt-4o
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | > Please provide us with the following information:
5 | > ---------------------------------------------------------------
6 |
7 | ### This issue is for a: (mark with an `x`)
8 | ```
9 | - [ ] bug report -> please search issues before submitting
10 | - [ ] feature request
11 | - [ ] documentation issue or request
12 | - [ ] regression (a behavior that used to work and stopped in a new release)
13 | ```
14 |
15 | ### Minimal steps to reproduce
16 | >
17 |
18 | ### Any log messages given by the failure
19 | >
20 |
21 | ### Expected/desired behavior
22 | >
23 |
24 | ### OS and Version?
25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26 |
27 | ### Versions
28 | >
29 |
30 | ### Mention any other details that might be useful
31 |
32 | > ---------------------------------------------------------------
33 | > Thanks! We'll be in touch soon.
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | * ...
4 |
5 | ## Does this introduce a breaking change?
6 |
7 | ```
8 | [ ] Yes
9 | [ ] No
10 | ```
11 |
12 | ## Pull Request Type
13 | What kind of change does this Pull Request introduce?
14 |
15 |
16 | ```
17 | [ ] Bugfix
18 | [ ] Feature
19 | [ ] Code style update (formatting, local variables)
20 | [ ] Refactoring (no functional changes, no api changes)
21 | [ ] Documentation content changes
22 | [ ] Other... Please describe:
23 | ```
24 |
25 | ## How to Test
26 | * Get the code
27 |
28 | ```
29 | git clone [repo-address]
30 | cd [repo-name]
31 | git checkout [branch-name]
32 | npm install
33 | ```
34 |
35 | * Test the code
36 |
37 | ```
38 | ```
39 |
40 | ## What to Check
41 | Verify that the following are valid
42 | * ...
43 |
44 | ## Other Information
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # NPM
2 | node_modules
3 | npm-debug.log
4 | sandboxes.ts
5 |
6 | # Code Editor Settings
7 | .idea
8 | .vs
9 | .env
10 | credential.yaml
11 | connections.yaml
12 | downloads/*
13 |
14 | # Ignore any Webpack generated files
15 | dist
16 |
17 | tsconfig.tsbuildinfo
18 |
19 | .DS_Store
20 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [project-title] Changelog
2 |
3 |
4 | # x.y.z (yyyy-mm-dd)
5 |
6 | *Features*
7 | * ...
8 |
9 | *Bug Fixes*
10 | * ...
11 |
12 | *Breaking Changes*
13 | * ...
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to [project-title]
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
6 |
7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | - [Code of Conduct](#coc)
16 | - [Issues and Bugs](#issue)
17 | - [Feature Requests](#feature)
18 | - [Submission Guidelines](#submit)
19 |
20 | ## Code of Conduct
21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 |
23 | ## Found an Issue?
24 | If you find a bug in the source code or a mistake in the documentation, you can help us by
25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26 | [submit a Pull Request](#submit-pr) with a fix.
27 |
28 | ## Want a Feature?
29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30 | Repository. If you would like to *implement* a new feature, please submit an issue with
31 | a proposal for your work first, to be sure that we can use it.
32 |
33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34 |
35 | ## Submission Guidelines
36 |
37 | ### Submitting an Issue
38 | Before you submit an issue, search the archive, maybe your question was already answered.
39 |
40 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
41 | Help us to maximize the effort we can spend fixing issues and adding new
42 | features, by not reporting duplicate issues. Providing the following information will increase the
43 | chances of your issue being dealt with quickly:
44 |
45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46 | * **Version** - what version is affected (e.g. 0.1.2)
47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48 | * **Browsers and Operating System** - is this a problem with all browsers?
49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
50 | * **Related Issues** - has a similar issue been reported before?
51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52 | causing the problem (line of code or commit)
53 |
54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55 |
56 | ### Submitting a Pull Request (PR)
57 | Before you submit your Pull Request (PR) consider the following guidelines:
58 |
59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
60 | that relates to your submission. You don't want to duplicate effort.
61 |
62 | * Make your changes in a new git fork:
63 |
64 | * Commit your changes using a descriptive commit message
65 | * Push your fork to GitHub:
66 | * In GitHub, create a pull request
67 | * If we suggest changes then:
68 | * Make the required updates.
69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70 |
71 | ```shell
72 | git rebase master -i
73 | git push -f
74 | ```
75 |
76 | That's it! Thank you for your contribution!
77 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Azure AI Agent Service Demo
2 |
3 | This demo originally started out using the code from the [Azure AI Agent QuickStart](https://learn.microsoft.com/azure/ai-services/agents/quickstart), but has expanded to show different agent tooling features:
4 |
5 | - Perform a simple calculation (no tools)
6 | - Make function calls using Function Calling Tools
7 | - Create a function using code interpreter
8 | - Examine a CSV file and create diagrams from it using code interpreter
9 | - Examine a CSV file and provide analysis using code interpreter
10 | - Perform RAG functionality using AI search
11 | - Use real-time public web data using Bing Grounding
12 | - Return usage stats about in/out tokens
13 |
14 | 
15 |
16 | To use the demo you'll need to complete the steps in the [QuickStart](https://learn.microsoft.com/azure/ai-services/agents/quickstart?pivots=programming-language-javascript) to set up your Azure AI Foundry project. If you'd like to use the AI Search/RAG functionality in the demo, you'll find details about the setup in the [AI Search tooling](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/azure-ai-search?tabs=azurecli%2Cjavascript&pivots=code-examples) document.
17 |
18 | ## Running the Demo
19 |
20 | After going through the QuickStart steps (and optionally the AI Search and Bing Grounding tooling setup), perform the following steps:
21 |
22 | 1. Rename `.env.template` to `.env`.
23 |
24 | 1. Assign your Azure AI Foundry connection string, your AI Search and Bing Grounding connection name from Azure AI Foundry, and (optionally) the model deployment name to the `.env` file keys.
25 |
26 | 1. Install the project dependencies:
27 |
28 | ```bash
29 | npm install
30 | ```
31 |
32 | 1. Start the demo:
33 | ```bash
34 | npm start
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/downloads/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/downloads/.gitkeep
--------------------------------------------------------------------------------
/examples/1-basic.ts:
--------------------------------------------------------------------------------
1 | import { AIProjectsClient } from "@azure/ai-projects";
2 | import { DefaultAzureCredential } from "@azure/identity";
3 |
4 | import "dotenv/config";
5 |
6 | const connectionString =
7 | process.env["AI_FOUNDRY_PROJECT_CONNECTION_STRING"] ||
8 | "";
9 |
10 | const client = AIProjectsClient.fromConnectionString(
11 | connectionString || "",
12 | new DefaultAzureCredential()
13 | );
14 |
15 | const agent = await client.agents.createAgent("gpt-4o", {
16 | name: "my-ai-agent-hackathon",
17 | instructions: "You are helpful agent",
18 | });
19 | console.log(`Created agent, agent ID : ${agent.id}`);
20 |
21 | await client.agents.deleteAgent(agent.id);
22 | console.log(`Deleted agent, agent ID: ${agent.id}`);
23 |
--------------------------------------------------------------------------------
/examples/2-threads.ts:
--------------------------------------------------------------------------------
1 | import { AIProjectsClient } from "@azure/ai-projects";
2 | import { DefaultAzureCredential } from "@azure/identity";
3 |
4 | import "dotenv/config";
5 |
6 | const connectionString =
7 | process.env["AI_FOUNDRY_PROJECT_CONNECTION_STRING"] ||
8 | "";
9 |
10 | const client = AIProjectsClient.fromConnectionString(
11 | connectionString || "",
12 | new DefaultAzureCredential()
13 | );
14 |
15 | const thread = await client.agents.createThread();
16 | console.log(`Created thread, thread ID : ${thread.id}`);
17 |
18 | const _thread = await client.agents.getThread(thread.id);
19 | console.log(`Retrieved thread, thread ID : ${_thread.id}`);
20 |
21 | await client.agents.deleteThread(thread.id);
22 | console.log(`Deleted thread, thread ID : ${_thread.id}`);
23 |
--------------------------------------------------------------------------------
/examples/3-messages.ts:
--------------------------------------------------------------------------------
1 | import type { MessageTextContentOutput } from "@azure/ai-projects";
2 | import { AIProjectsClient } from "@azure/ai-projects";
3 | import { DefaultAzureCredential } from "@azure/identity";
4 |
5 | import "dotenv/config";
6 |
7 | const connectionString =
8 | process.env["AI_FOUNDRY_PROJECT_CONNECTION_STRING"] ||
9 | "";
10 |
11 | const client = AIProjectsClient.fromConnectionString(
12 | connectionString || "",
13 | new DefaultAzureCredential()
14 | );
15 | const agent = await client.agents.createAgent("gpt-4o", {
16 | name: "my-agent",
17 | instructions: "You are helpful agent",
18 | });
19 | const thread = await client.agents.createThread();
20 |
21 | const message = await client.agents.createMessage(thread.id, {
22 | role: "user",
23 | content: "hello, world!",
24 | });
25 | console.log(`Created message, message ID: ${message.id}`);
26 |
27 | const messages = await client.agents.listMessages(thread.id);
28 | console.log(
29 | `Message ${message.id} contents: ${
30 | (messages.data[0].content[0] as MessageTextContentOutput).text.value
31 | }`
32 | );
33 |
34 | await client.agents.deleteThread(thread.id);
35 | console.log(`Deleted thread, thread ID : ${thread.id}`);
36 |
37 | await client.agents.deleteAgent(agent.id);
38 | console.log(`Deleted agent, agent ID : ${agent.id}`);
39 |
--------------------------------------------------------------------------------
/examples/4-streaming.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | MessageDeltaChunk,
3 | MessageDeltaTextContent,
4 | ThreadRunOutput,
5 | } from "@azure/ai-projects";
6 | import {
7 | AIProjectsClient,
8 | DoneEvent,
9 | ErrorEvent,
10 | MessageStreamEvent,
11 | RunStreamEvent,
12 | } from "@azure/ai-projects";
13 | import { DefaultAzureCredential } from "@azure/identity";
14 |
15 | import "dotenv/config";
16 |
17 | const connectionString =
18 | process.env["AI_FOUNDRY_PROJECT_CONNECTION_STRING"] ||
19 | "";
20 |
21 | const client = AIProjectsClient.fromConnectionString(
22 | connectionString || "",
23 | new DefaultAzureCredential()
24 | );
25 |
26 | const agent = await client.agents.createAgent("gpt-4o", {
27 | name: "my-agent",
28 | instructions: "You are helpful agent",
29 | });
30 |
31 | console.log(`Created agent, agent ID : ${agent.id}`);
32 |
33 | const thread = await client.agents.createThread();
34 |
35 | console.log(`Created thread, thread ID : ${agent.id}`);
36 |
37 | await client.agents.createMessage(thread.id, {
38 | role: "user",
39 | content: "Hello, tell me a joke",
40 | });
41 |
42 | console.log(`Created message, thread ID : ${agent.id}`);
43 |
44 | const streamEventMessages = await client.agents
45 | .createRun(thread.id, agent.id)
46 | .stream();
47 |
48 | for await (const eventMessage of streamEventMessages) {
49 | switch (eventMessage.event) {
50 | case RunStreamEvent.ThreadRunCreated:
51 | console.log(
52 | `ThreadRun status: ${(eventMessage.data as ThreadRunOutput).status}`
53 | );
54 | break;
55 | case MessageStreamEvent.ThreadMessageDelta:
56 | {
57 | const messageDelta = eventMessage.data as MessageDeltaChunk;
58 | messageDelta.delta.content.forEach((contentPart) => {
59 | if (contentPart.type === "text") {
60 | const textContent = contentPart as MessageDeltaTextContent;
61 | const textValue = textContent.text?.value || "No text";
62 | console.log(`Text delta received:: ${textValue}`);
63 | }
64 | });
65 | }
66 | break;
67 |
68 | case RunStreamEvent.ThreadRunCompleted:
69 | console.log("Thread Run Completed");
70 | break;
71 | case ErrorEvent.Error:
72 | console.log(`An error occurred. Data ${eventMessage.data}`);
73 | break;
74 | case DoneEvent.Done:
75 | console.log("Stream completed.");
76 | break;
77 | }
78 | }
79 |
80 | await client.agents.deleteAgent(agent.id);
81 | console.log(`Delete agent, agent ID : ${agent.id}`);
82 |
--------------------------------------------------------------------------------
/examples/5-run.ts:
--------------------------------------------------------------------------------
1 | import { AIProjectsClient } from "@azure/ai-projects";
2 | import { DefaultAzureCredential } from "@azure/identity";
3 | import "dotenv/config";
4 |
5 | const connectionString =
6 | process.env["AI_FOUNDRY_PROJECT_CONNECTION_STRING"] ||
7 | "";
8 |
9 | const client = AIProjectsClient.fromConnectionString(
10 | connectionString || "",
11 | new DefaultAzureCredential()
12 | );
13 |
14 | // Create agent
15 | const agent = await client.agents.createAgent("gpt-4o", {
16 | name: "my-agent",
17 | instructions: "You are a helpful agent",
18 | });
19 | console.log(`Created agent, agent ID: ${agent.id}`);
20 |
21 | // Create thread
22 | const thread = await client.agents.createThread();
23 | console.log(`Created thread, thread ID: ${thread.id}`);
24 |
25 | // Create message
26 | const message = await client.agents.createMessage(thread.id, {
27 | role: "user",
28 | content: "hello, world!",
29 | });
30 | console.log(`Created message, message ID: ${message.id}`);
31 |
32 | // Create run
33 | let run = await client.agents.createRun(thread.id, agent.id);
34 | console.log(`Created run, run ID: ${run.id}`);
35 |
36 | // Wait for run to complete
37 | while (["queued", "in_progress", "requires_action"].includes(run.status)) {
38 | await new Promise((resolve) => setTimeout(resolve, 1000));
39 | run = await client.agents.getRun(thread.id, run.id);
40 | console.log(`Run status: ${run.status}`);
41 | }
42 |
43 | // List run steps
44 | const runSteps = await client.agents.listRunSteps(thread.id, run.id);
45 | console.log(`Listed run steps, run ID: ${run.id}`);
46 |
47 | runSteps.data.forEach(async (runStep) => {
48 | const step = await client.agents.getRunStep(thread.id, run.id, runStep.id);
49 | console.log(`Retrieved run step, step ID: ${step}`);
50 | });
51 |
52 | // Clean up
53 | await client.agents.deleteThread(thread.id);
54 | console.log(`Deleted thread, thread ID: ${thread.id}`);
55 | await client.agents.deleteAgent(agent.id);
56 | console.log(`Deleted agent, agent ID: ${agent.id}`);
57 |
--------------------------------------------------------------------------------
/files/car_sales_data.csv:
--------------------------------------------------------------------------------
1 | Date,Make,Model,Year,Color,Price,Mileage,Fuel_Type,Transmission,SalesPerson,CustomerAge,CustomerGender,Region,DaysToSale,PreviousOwners
2 | 2023-01-15,Toyota,Camry,2020,Silver,25400,15200,Gasoline,Automatic,John Smith,42,Male,Northeast,5,1
3 | 2023-01-17,Honda,Civic,2021,Blue,22800,8500,Gasoline,Automatic,Sarah Johnson,35,Female,West,8,0
4 | 2023-01-22,Ford,F-150,2019,Black,35600,22500,Gasoline,Automatic,Sarah Johnson,51,Male,South,12,1
5 | 2023-01-28,Tesla,Model 3,2022,White,48900,3200,Electric,Automatic,Sarah Johnson,39,Female,West,3,0
6 | 2023-02-03,Toyota,Camry,2020,Gray,24800,18700,Gasoline,Automatic,Michael Brown,45,Male,Northeast,15,1
7 | 2023-02-10,Honda,Civic,2021,Red,23500,12000,Gasoline,Automatic,Sarah Johnson,33,Female,Midwest,7,1
8 | 2023-02-15,Toyota,Corolla,2020,White,21100,19500,Gasoline,Automatic,John Smith,38,Male,South,10,2
9 | 2023-02-21,Subaru,Outback,2022,Green,33400,5600,Gasoline,Automatic,Emily Davis,41,Female,West,6,0
10 | 2023-02-28,Toyota,RAV4,2021,Black,32700,9800,Gasoline,Automatic,Sarah Johnson,47,Male,Northeast,14,1
11 | 2023-03-05,Toyota,RAV4,2022,Blue,32500,7200,Hybrid,Automatic,Michael Brown,36,Female,West,5,0
12 | 2023-03-11,Hyundai,Tucson,2021,Silver,26900,14300,Gasoline,Automatic,Sarah Johnson,43,Male,Midwest,9,1
13 | 2023-03-18,Honda,Civic,2020,Gray,21500,18200,Gasoline,Automatic,Sarah Johnson,32,Female,South,11,1
14 | 2023-03-24,Mazda,CX-5,2022,Red,29800,6400,Gasoline,Automatic,David Wilson,39,Male,West,8,0
15 | 2023-04-02,Toyota,Camry,2021,White,26200,11500,Gasoline,Automatic,Emily Davis,44,Female,Northeast,13,1
16 | 2023-04-09,Volkswagen,Tiguan,2020,Black,28900,16800,Gasoline,Automatic,Sarah Johnson,37,Male,Midwest,7,1
17 | 2023-04-15,Tesla,Model 3,2022,Blue,49700,4200,Electric,Automatic,Sarah Johnson,40,Female,West,4,0
18 | 2023-04-22,Ford,F-150,2021,Gray,36500,13600,Gasoline,Automatic,John Smith,48,Male,South,10,1
19 | 2023-04-28,Honda,Accord,2020,Silver,27300,17900,Gasoline,Automatic,David Wilson,34,Female,Northeast,9,1
20 | 2023-05-05,Toyota,Camry,2022,Black,27600,8100,Gasoline,Automatic,Sarah Johnson,52,Male,Midwest,11,0
21 | 2023-05-12,Toyota,Highlander,2021,White,41500,12400,Hybrid,Automatic,Michael Brown,38,Female,West,6,1
22 | 2023-05-19,Jeep,Grand Cherokee,2020,Green,36800,19700,Gasoline,Automatic,Emily Davis,45,Male,South,13,2
23 | 2023-05-26,Hyundai,Sonata,2022,Blue,25900,5900,Gasoline,Automatic,Sarah Johnson,33,Female,Northeast,7,0
24 | 2023-06-03,BMW,3 Series,2021,Black,44700,10800,Gasoline,Automatic,Sarah Johnson,41,Male,West,14,1
25 | 2023-06-10,Honda,Civic,2020,Gray,22500,15600,Gasoline,Automatic,John Smith,37,Female,Midwest,8,1
26 | 2023-06-17,Audi,Q5,2022,White,48900,6700,Gasoline,Automatic,John Smith,46,Male,South,12,0
27 | 2023-06-24,Toyota,RAV4,2021,Silver,31300,11900,Gasoline,Automatic,Sarah Johnson,35,Female,West,9,1
28 | 2023-07-01,Ford,Mustang,2022,Red,45800,7800,Gasoline,Automatic,Sarah Johnson,39,Male,Northeast,5,0
29 | 2023-07-08,Honda,Civic,2020,Blue,22700,16300,Gasoline,Automatic,Michael Brown,32,Female,Midwest,10,1
30 | 2023-07-15,Tesla,Model 3,2021,Black,47500,9200,Electric,Automatic,Sarah Johnson,48,Male,West,15,1
31 | 2023-07-22,Toyota,Tacoma,2022,Gray,38900,6100,Gasoline,Automatic,Michael Brown,36,Female,South,7,0
32 | 2023-07-29,Mazda,CX-9,2021,White,39200,12700,Gasoline,Automatic,Emily Davis,43,Male,Northeast,11,1
33 | 2023-08-05,Kia,Telluride,2022,Black,41600,5400,Gasoline,Automatic,Sarah Johnson,34,Female,Midwest,6,0
34 | 2023-08-12,Toyota,Camry,2020,Green,25800,18500,Gasoline,Automatic,David Wilson,42,Male,West,13,1
35 | 2023-08-19,Hyundai,Santa Fe,2021,Silver,32400,13200,Gasoline,Automatic,Sarah Johnson,38,Female,South,8,1
36 | 2023-08-26,Toyota,RAV4,2022,Blue,33700,7500,Hybrid,Automatic,Michael Brown,45,Male,Northeast,9,0
37 | 2023-09-02,Volkswagen,Atlas,2020,Gray,34900,16900,Gasoline,Automatic,Sarah Johnson,33,Female,Midwest,12,1
38 | 2023-09-09,Honda,Civic,2021,White,23800,12100,Gasoline,Automatic,David Wilson,44,Male,West,10,1
39 | 2023-09-16,Audi,Q7,2022,Black,59800,6800,Gasoline,Automatic,Sarah Johnson,37,Female,South,14,0
40 | 2023-09-23,Toyota,Corolla,2021,Red,22600,11400,Gasoline,Automatic,Emily Davis,46,Male,Northeast,11,1
41 | 2023-09-30,Subaru,Crosstrek,2020,Orange,26700,17800,Gasoline,Automatic,Sarah Johnson,32,Female,Midwest,9,1
42 | 2023-10-07,Toyota,Camry,2022,White,26900,5900,Gasoline,Automatic,John Smith,40,Male,West,8,0
43 | 2023-10-14,Honda,Pilot,2021,Black,39500,13800,Gasoline,Automatic,Sarah Johnson,35,Female,South,7,1
44 | 2023-10-21,Toyota,Sienna,2022,Silver,42700,6300,Hybrid,Automatic,Sarah Johnson,47,Male,Northeast,13,0
45 | 2023-10-28,Ford,F-150,2020,Blue,34300,18100,Gasoline,Automatic,Michael Brown,34,Female,Midwest,10,1
46 | 2023-11-04,Porsche,Cayenne,2021,Black,72900,10500,Gasoline,Automatic,Sarah Johnson,51,Male,West,15,1
47 | 2023-11-11,Honda,Civic,2022,Gray,24500,5700,Gasoline,Automatic,Emily Davis,38,Female,South,6,0
48 | 2023-11-18,Mazda,Mazda3,2020,Red,24700,16700,Gasoline,Automatic,Sarah Johnson,42,Male,Northeast,9,1
49 | 2023-11-25,Toyota,Camry,2021,White,25900,12900,Gasoline,Automatic,John Smith,31,Female,Midwest,8,1
50 | 2023-12-02,Tesla,Model 3,2022,Blue,51200,4800,Electric,Automatic,Sarah Johnson,49,Male,West,16,0
51 | 2023-12-09,Jeep,Cherokee,2020,Black,29800,19200,Gasoline,Automatic,David Wilson,36,Female,South,11,1
52 | 2023-12-16,Toyota,Corolla,2022,Silver,23600,5500,Gasoline,Automatic,Sarah Johnson,33,Male,Northeast,7,0
53 | 2023-12-23,Honda,Civic,2021,Gray,23200,13100,Gasoline,Automatic,Sarah Johnson,37,Female,Midwest,10,1
54 | 2023-12-30,Chevrolet,Malibu,2020,White,25900,17400,Gasoline,Automatic,Michael Brown,41,Male,West,12,1
55 | 2024-01-05,Toyota,RAV4,2023,Blue,34800,3200,Hybrid,Automatic,Sarah Johnson,39,Female,Northeast,6,0
56 | 2024-01-12,Honda,Civic,2022,Red,24500,7800,Gasoline,Automatic,Sarah Johnson,33,Male,South,8,1
57 | 2024-01-19,Ford,F-150,2023,Black,38900,2900,Gasoline,Automatic,Emily Davis,46,Male,West,9,0
58 | 2024-01-26,Tesla,Model 3,2023,White,52500,1800,Electric,Automatic,Sarah Johnson,41,Female,Midwest,4,0
59 | 2024-02-02,Toyota,Camry,2022,Gray,27200,9600,Gasoline,Automatic,John Smith,48,Male,Northeast,11,1
60 | 2024-02-09,Chevrolet,Tahoe,2023,Black,58700,3500,Gasoline,Automatic,Sarah Johnson,37,Female,West,7,0
61 | 2024-02-16,Toyota,RAV4,2022,Silver,33200,8700,Gasoline,Automatic,Sarah Johnson,44,Male,South,10,1
62 | 2024-02-23,Subaru,Forester,2023,Green,35600,2800,Gasoline,Automatic,David Wilson,39,Female,Northeast,8,0
63 | 2024-03-01,Toyota,Camry,2022,Black,27800,10200,Gasoline,Automatic,Sarah Johnson,45,Male,Midwest,12,1
64 | 2024-03-08,Toyota,RAV4,2023,Blue,35900,3800,Hybrid,Automatic,Michael Brown,34,Female,West,6,0
65 | 2024-03-15,Hyundai,Santa Fe,2022,White,33700,9200,Gasoline,Automatic,Sarah Johnson,42,Male,South,9,1
66 | 2024-03-22,Honda,Civic,2023,Silver,25200,2500,Gasoline,Automatic,Sarah Johnson,38,Female,Northeast,7,0
67 | 2024-03-29,Mazda,CX-9,2022,Red,38600,8800,Gasoline,Automatic,Emily Davis,47,Male,Midwest,10,1
68 | 2024-04-05,Toyota,RAV4,2023,White,35900,3100,Hybrid,Automatic,Sarah Johnson,40,Female,West,8,0
69 | 2024-04-12,Volkswagen,Tiguan,2022,Black,32500,9500,Gasoline,Automatic,John Smith,43,Male,South,11,1
70 | 2024-04-19,Tesla,Model 3,2023,Blue,51200,2200,Electric,Automatic,Sarah Johnson,36,Female,Northeast,5,0
71 | 2024-04-26,Ford,F-150,2022,Gray,37700,8900,Gasoline,Automatic,Sarah Johnson,49,Male,Midwest,9,1
72 | 2024-05-03,Honda,Civic,2023,Silver,24800,3600,Gasoline,Automatic,Michael Brown,35,Female,West,7,0
73 | 2024-05-10,Toyota,Camry,2022,Red,27900,9800,Gasoline,Automatic,David Wilson,44,Male,South,10,1
74 | 2024-05-17,Toyota,Highlander,2023,White,44500,2900,Hybrid,Automatic,Sarah Johnson,39,Female,Northeast,6,0
75 | 2024-05-24,Jeep,Wrangler,2022,Green,41700,10500,Gasoline,Automatic,John Smith,50,Male,Midwest,12,1
76 | 2024-05-31,Honda,Civic,2023,Black,24800,3300,Gasoline,Automatic,Sarah Johnson,32,Female,West,8,0
77 | 2024-06-07,BMW,5 Series,2022,Silver,59800,9700,Gasoline,Automatic,Sarah Johnson,46,Male,South,13,1
78 | 2024-06-14,Toyota,RAV4,2023,Blue,34900,2700,Gasoline,Automatic,Emily Davis,37,Female,Northeast,7,0
79 | 2024-06-21,Audi,Q7,2022,Black,64500,10100,Gasoline,Automatic,Michael Brown,48,Male,Midwest,11,1
80 | 2024-06-28,Honda,Civic,2023,White,23700,3500,Gasoline,Automatic,Sarah Johnson,34,Female,West,6,0
--------------------------------------------------------------------------------
/files/hotel_reviews_data.csv:
--------------------------------------------------------------------------------
1 | address,categories,city,country,latitude,longitude,name,postalCode,province,reviews_date,reviews_dateAdded,reviews_rating,reviews_text,reviews_title,reviews_username
2 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2013-09-22T00:00:00Z,2016-10-24T00:00:25Z,4,Pleasant 10 min walk along the sea front to the Water Bus. restaurants etc. Hotel was comfortable breakfast was good - quite a variety. Room aircon didn't work very well. Take mosquito repelant!,Good location away from the crouds,Russ (kent)
3 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-04-03T00:00:00Z,2016-10-24T00:00:25Z,5,Really lovely hotel. Stayed on the very top floor and were surprised by a Jacuzzi bath we didn't know we were getting! Staff were friendly and helpful and the included breakfast was great! Great location and great value for money. Didn't want to leave!,Great hotel with Jacuzzi bath!,A Traveler
4 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2013-10-27T00:00:00Z,2016-10-24T00:00:25Z,5,"We stayed here for four nights in October. The hotel staff were welcoming, friendly and helpful. Assisted in booking tickets for the opera. The rooms were clean and comfortable- good shower, light and airy rooms with windows you could open wide. Beds were comfortable. Plenty of choice for breakfast.Spa at hotel nearby which we used while we were there.",Good location on the Lido.,Julie
5 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-04-05T00:00:00Z,2016-10-24T00:00:25Z,5,"We loved staying on the island of Lido! You need to take a water is from Venice to get there. From the train station, a boat ride takes 45 minutes but has beautiful views along the way. Hotel is an EASY walk from the boat dock. The room was very clean and the breakfast was plentiful. We would definitely recommend this hotel!",Very nice hotel,A Traveler
6 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-05-14T00:00:00Z,2016-10-24T00:00:25Z,4,It was a bit far from city center,Lovely view out onto the lagoon. Excellent view.,A Traveler
7 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-05-24T00:00:00Z,2016-10-24T00:00:25Z,4,Nous avons pass 4 jours dans cet htel situ 5 mn pieds des des vaporetto. Le personnel est trs sympa parle franais. Toujours l pour donner de bons conseils sur les restaurants ou les visites. Rien redire. Tout tait bien. Chambres petit djeuner et environnement.,une belle semaine en Venise,serge
8 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-08-02T00:00:00Z,2016-10-24T00:00:25Z,3,It was ok hotel is nice from in and out but room was small we paid for double bed bat they atteched 2 single bed,It was ok hotel is nice from in and out but room,RJ
9 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2016-05-24T00:00:00Z,2016-10-24T00:00:25Z,4,"Hotel sympathique et silencieux sur l ile du Lido a quelques minutes en vaporetto de Venise. Personnels trs avenants et parlants plusieurs langues, dont le franais. Voyage dpaysant et inoubliable... aucune voiture l horyzon",;-),raoul
10 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2016-06-07T00:00:00Z,2016-10-24T00:00:25Z,4,"beautiful views of Venice in the lovely relaxed calmer area of Lido Di Venezia. Gorgeous sunsets and very easy to access Venice, rather than satying in the hustle and bustle. Close to only beaches in Venice. Staff were so helpful, especially Ivan and the lady we met on the desk each morning.",Tip top,A Traveler
11 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-06-05T00:00:00Z,2016-10-24T00:00:25Z,4,"Nice hotel , with very friendly staff and helpful - great choice for breakfast , something for everyone.",Nice hotel with very friendly and helpful staff,Mrs Gardner
12 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2014-05-23T00:00:00Z,2016-10-24T00:00:25Z,1,"It was a 10 min+ walk to water bus, would have liked it closer. Located on the water on Lido island, away from the rush of Venice",stayed before and after cruise,Joe S.
13 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-07-02T00:00:00Z,2016-10-24T00:00:25Z,1,"DON'T stay here unless you're less than 2 feet tall or like sleeping with centipedes. Our 4th floor room was an attic with a vaulted ceiling that angles down to 3ft. The bed is only accessible from one side. If you placed your head in the skylight on the other side you might able sit up. The bathtub was impractical with broken shower head. We moved to the 1st floor the next day and within minutes found a centipede on the wall and15 flies. We asked for a broom to get rid of the centipede. Later in the day the receptionist said she gave us something to control the bugs. We never complained about the drain flies so she must have noticed a problem. That night we spent 2 hrs catching 6 centipedes in our room. 2 came from throw pillows. We asked reception for a new room or hotel but there supposedly weren't any hotels with open rooms and if we wanted leave we would have to pay for transportation and both hotels. The next morning we went to reception to tell them about the bug problem. We barely said anything before the woman apologized and said they didn't put the bugs in the room on purpose so we should just go about our day and forget it. She added that she often goes on vacation with her children and sometimes things happen, so she tries to make the best of everything and not start a war. Adding, a few euros isn't going to make anything go away so we should just go enjoy the day because more we talk the less time we have.","Dungeons, Drain Flies and Centipedes",A Traveler
14 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-04-11T00:00:00Z,2016-10-24T00:00:25Z,5,"We had absolutely no problems whatsoever with this hotel and were very pleasantly surprised by the quality considering the low price. The dcor of the room was pleasant and flawless, unlike many of the Venice hotels I've stayed in. The breakfast buffet was delicious too. And to finish all this off, the staff couldn't have been friendlier or more helpful. In terms of location, the hotel is about 10 minutes walk from the Lido waterbus stop, then a boat takes around 15 mins to get into Venice. We didn't find this a problem at all - we knew this was going to be the case so had pre-booked transport tickets to save money. The surrounding Lido is pleasant and worth an explore in a spare couple of hours. In conclusion, I would book this again due to the fantastic quality of the hotel, despite the trade-off of not being in Venice itself.",Excellent hotel with good access to Venice,Simon
15 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-07-14T00:00:00Z,2016-10-24T00:00:25Z,5,"Lovely hotel, 10 min walk to the water bus stop on lido. Away from the madness of Venice, but close enough to be there in less than 20 minutes.",Lovely stay - second time staying at this hotel.,Martyn
16 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2014-09-30T00:00:00Z,2016-10-24T00:00:25Z,5,"Located on the Lido I would recommend this hotel if you require a little piece and quiet after the busy day's in Venice, facility's good, staff very friendly and very helpful. I requested flowers for the room as it was one of my wife's special birthday's, and yes they ordered exactly as requested, can't ask for more. Rooms are a little on the small side but in line with most European hotels of this standard so wasn't a surprise or a problem, room and bathroom was cleaned every day with fresh towels supplied each day. Buffet breakfast had various options to suit most peoples taste but It was a surprise to see sausage, bacon and scrambled eggs available, must have been put on to satisfy us Brits! We stayed during late September so the Lido is probably quieter at that time however we felt very safe walking around late at night back to the hotel but taxis are available if you feel a little vulnerable. Restaurants and coffee bars are located in the main commercial area close to the Waterbus stations and tend to be slightly cheaper than in Venice. We had a water taxi (think luxury speed boat!) from the airport to the hotel and back again, quite an experience, a little costly but well worth it, a lot quicker and less hassle than the Waterbus. Venice was very busy during the day time, St Marks Square at night is a must, fantastic atmosphere. All in all we had a great time in Venice, it can be a little expensive so don't ponder over the bills to much, just pay up with a smile!",A good Hotel on the Lido - Quiet location.,A & D
17 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2015-08-04T00:00:00Z,2016-10-24T00:00:25Z,4,"Nice staff. Nice location. We booked two nights at Russo hotel on Lido strip and two nights in the very center of Venice. This is a good balance. Lido is a bit further but it feels more local and is more relaxing too, it gave us a taste of Dolce Vita. We didn't see it on the hotel description but they offered us a taxi boat ride to Murano with another couple for free. The boat ride was very pleasant, they dropped us in a glass blowing factory shop, the glass making demonstration was nice and there was very little pressure to buy. Internet was free for 20 minutes/day but a bit slow like everywhere in Venice. So in short a good pick, good value for money.",Good pleasant pick,Niklas
18 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2016-05-16T00:00:00Z,2016-10-24T00:00:25Z,4,Great stay...close to ferry.food not so good nearby,Loved this Wonderful Boutique Hotel!,Armando
19 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2014-04-29T00:00:00Z,2016-10-24T00:00:25Z,5,"Stayed with parents, wife twin toddlers in two triple rooms. The hotel is easy to reach and the rooms were well placed well furnished. The best feature was extremely friendly helpful staff, particularly Ms. Annalucia Ms. Anna who were always ready to listen help out with big smiles. The breakfasts were very good, with good spread and the guests were made welcome to sit and eat at leisure (more important when you are with toddlers!) Would surely go back to Venice would happily stay again at Russo Palace.",I would come back,A Traveler
20 | Riviera San Nicol 11/a,Hotels,Mableton,US,45.421611,12.376187,Hotel Russo Palace,30126,GA,2014-10-06T00:00:00Z,2016-10-24T00:00:25Z,4,This hotel is in Lido which is a better choice than staying in crowded Venice. The water bus is very convenient and it takes only few more stops to the main attractions in Venice. We received excellent service - many thanks to Anna and Donnatella who made us feel at home.,Excellent Service,Mari_ana
21 |
--------------------------------------------------------------------------------
/images/prompt-1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompt-1.mp4
--------------------------------------------------------------------------------
/images/prompt-2.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompt-2.mp4
--------------------------------------------------------------------------------
/images/prompt-3.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompt-3.mp4
--------------------------------------------------------------------------------
/images/prompt-4.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompt-4.mp4
--------------------------------------------------------------------------------
/images/prompt-6.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompt-6.mp4
--------------------------------------------------------------------------------
/images/prompt-7.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompt-7.mp4
--------------------------------------------------------------------------------
/images/prompts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Azure-Samples/azure-ai-agents-javascript/701034066a98d4306d08a069199d0782c3744a1c/images/prompts.png
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "azure-ai-agents",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "azure-ai-agents",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "@azure/ai-projects": "^1.0.0-beta.4",
13 | "@azure/identity": "^4.8.0",
14 | "dotenv": "^16.4.7"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^22.13.10",
18 | "concurrently": "^9.1.2",
19 | "nodemon": "^3.1.9",
20 | "ts-node": "^10.9.2",
21 | "tsx": "^4.19.3",
22 | "typescript": "^5.8.2"
23 | }
24 | },
25 | "node_modules/@azure-rest/core-client": {
26 | "version": "2.3.4",
27 | "resolved": "https://registry.npmjs.org/@azure-rest/core-client/-/core-client-2.3.4.tgz",
28 | "integrity": "sha512-AQXtD5VqsoOswDmxQR0YyVkYa1tZ0HyfC/fsqfntYZ7EEgaimfCGN2nAfiN3KXy1F4TfcoByhmtX2bVOO2vAEQ==",
29 | "license": "MIT",
30 | "dependencies": {
31 | "@azure/abort-controller": "^2.0.0",
32 | "@azure/core-auth": "^1.3.0",
33 | "@azure/core-rest-pipeline": "^1.5.0",
34 | "@azure/core-tracing": "^1.0.1",
35 | "@azure/core-util": "^1.0.0",
36 | "tslib": "^2.6.2"
37 | },
38 | "engines": {
39 | "node": ">=18.0.0"
40 | }
41 | },
42 | "node_modules/@azure/abort-controller": {
43 | "version": "2.1.2",
44 | "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
45 | "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
46 | "license": "MIT",
47 | "dependencies": {
48 | "tslib": "^2.6.2"
49 | },
50 | "engines": {
51 | "node": ">=18.0.0"
52 | }
53 | },
54 | "node_modules/@azure/ai-projects": {
55 | "version": "1.0.0-beta.4",
56 | "resolved": "https://registry.npmjs.org/@azure/ai-projects/-/ai-projects-1.0.0-beta.4.tgz",
57 | "integrity": "sha512-+sRwbmNVQd/2atMF9lyfeIIhk7f0POyFiTUvdtiqRfqO6oeVOD4VhA3UaAFITD1JOIeAmRe4l+BwdX1Xy9FGzQ==",
58 | "license": "MIT",
59 | "dependencies": {
60 | "@azure-rest/core-client": "^2.1.0",
61 | "@azure/abort-controller": "^2.1.2",
62 | "@azure/core-auth": "^1.6.0",
63 | "@azure/core-lro": "^3.0.0",
64 | "@azure/core-paging": "^1.5.0",
65 | "@azure/core-rest-pipeline": "^1.5.0",
66 | "@azure/core-sse": "^2.1.3",
67 | "@azure/core-tracing": "^1.2.0",
68 | "@azure/core-util": "^1.9.0",
69 | "@azure/logger": "^1.1.4",
70 | "tslib": "^2.6.2"
71 | },
72 | "engines": {
73 | "node": ">=18.0.0"
74 | }
75 | },
76 | "node_modules/@azure/core-auth": {
77 | "version": "1.9.0",
78 | "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz",
79 | "integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==",
80 | "license": "MIT",
81 | "dependencies": {
82 | "@azure/abort-controller": "^2.0.0",
83 | "@azure/core-util": "^1.11.0",
84 | "tslib": "^2.6.2"
85 | },
86 | "engines": {
87 | "node": ">=18.0.0"
88 | }
89 | },
90 | "node_modules/@azure/core-client": {
91 | "version": "1.9.3",
92 | "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.3.tgz",
93 | "integrity": "sha512-/wGw8fJ4mdpJ1Cum7s1S+VQyXt1ihwKLzfabS1O/RDADnmzVc01dHn44qD0BvGH6KlZNzOMW95tEpKqhkCChPA==",
94 | "license": "MIT",
95 | "dependencies": {
96 | "@azure/abort-controller": "^2.0.0",
97 | "@azure/core-auth": "^1.4.0",
98 | "@azure/core-rest-pipeline": "^1.9.1",
99 | "@azure/core-tracing": "^1.0.0",
100 | "@azure/core-util": "^1.6.1",
101 | "@azure/logger": "^1.0.0",
102 | "tslib": "^2.6.2"
103 | },
104 | "engines": {
105 | "node": ">=18.0.0"
106 | }
107 | },
108 | "node_modules/@azure/core-lro": {
109 | "version": "3.1.0",
110 | "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-3.1.0.tgz",
111 | "integrity": "sha512-W/vVbZumJLFMvmiUspyBzKai0O3HiD6KmsWnpCLasFr92qmafwgz+tThmnpMFH7vCS4MUl4ehFd0Z6OWb8BPog==",
112 | "license": "MIT",
113 | "dependencies": {
114 | "@azure/abort-controller": "^2.0.0",
115 | "@azure/core-util": "^1.2.0",
116 | "@azure/logger": "^1.0.0",
117 | "tslib": "^2.6.2"
118 | },
119 | "engines": {
120 | "node": ">=18.0.0"
121 | }
122 | },
123 | "node_modules/@azure/core-paging": {
124 | "version": "1.6.2",
125 | "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz",
126 | "integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==",
127 | "license": "MIT",
128 | "dependencies": {
129 | "tslib": "^2.6.2"
130 | },
131 | "engines": {
132 | "node": ">=18.0.0"
133 | }
134 | },
135 | "node_modules/@azure/core-rest-pipeline": {
136 | "version": "1.19.1",
137 | "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.1.tgz",
138 | "integrity": "sha512-zHeoI3NCs53lLBbWNzQycjnYKsA1CVKlnzSNuSFcUDwBp8HHVObePxrM7HaX+Ha5Ks639H7chNC9HOaIhNS03w==",
139 | "license": "MIT",
140 | "dependencies": {
141 | "@azure/abort-controller": "^2.0.0",
142 | "@azure/core-auth": "^1.8.0",
143 | "@azure/core-tracing": "^1.0.1",
144 | "@azure/core-util": "^1.11.0",
145 | "@azure/logger": "^1.0.0",
146 | "http-proxy-agent": "^7.0.0",
147 | "https-proxy-agent": "^7.0.0",
148 | "tslib": "^2.6.2"
149 | },
150 | "engines": {
151 | "node": ">=18.0.0"
152 | }
153 | },
154 | "node_modules/@azure/core-sse": {
155 | "version": "2.1.3",
156 | "resolved": "https://registry.npmjs.org/@azure/core-sse/-/core-sse-2.1.3.tgz",
157 | "integrity": "sha512-KSSdIKy8kvWCpYr8Hzpu22j3wcXsVTYE0IlgmI1T/aHvBDsLgV91y90UTfVWnuiuApRLCCVC4gS09ApBGOmYQA==",
158 | "license": "MIT",
159 | "dependencies": {
160 | "tslib": "^2.6.2"
161 | },
162 | "engines": {
163 | "node": ">=18.0.0"
164 | }
165 | },
166 | "node_modules/@azure/core-tracing": {
167 | "version": "1.2.0",
168 | "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz",
169 | "integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==",
170 | "license": "MIT",
171 | "dependencies": {
172 | "tslib": "^2.6.2"
173 | },
174 | "engines": {
175 | "node": ">=18.0.0"
176 | }
177 | },
178 | "node_modules/@azure/core-util": {
179 | "version": "1.11.0",
180 | "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz",
181 | "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==",
182 | "license": "MIT",
183 | "dependencies": {
184 | "@azure/abort-controller": "^2.0.0",
185 | "tslib": "^2.6.2"
186 | },
187 | "engines": {
188 | "node": ">=18.0.0"
189 | }
190 | },
191 | "node_modules/@azure/identity": {
192 | "version": "4.8.0",
193 | "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.8.0.tgz",
194 | "integrity": "sha512-l9ALUGHtFB/JfsqmA+9iYAp2a+cCwdNO/cyIr2y7nJLJsz1aae6qVP8XxT7Kbudg0IQRSIMXj0+iivFdbD1xPA==",
195 | "license": "MIT",
196 | "dependencies": {
197 | "@azure/abort-controller": "^2.0.0",
198 | "@azure/core-auth": "^1.9.0",
199 | "@azure/core-client": "^1.9.2",
200 | "@azure/core-rest-pipeline": "^1.17.0",
201 | "@azure/core-tracing": "^1.0.0",
202 | "@azure/core-util": "^1.11.0",
203 | "@azure/logger": "^1.0.0",
204 | "@azure/msal-browser": "^4.2.0",
205 | "@azure/msal-node": "^3.2.3",
206 | "events": "^3.0.0",
207 | "jws": "^4.0.0",
208 | "open": "^10.1.0",
209 | "stoppable": "^1.1.0",
210 | "tslib": "^2.2.0"
211 | },
212 | "engines": {
213 | "node": ">=18.0.0"
214 | }
215 | },
216 | "node_modules/@azure/logger": {
217 | "version": "1.1.4",
218 | "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz",
219 | "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==",
220 | "license": "MIT",
221 | "dependencies": {
222 | "tslib": "^2.6.2"
223 | },
224 | "engines": {
225 | "node": ">=18.0.0"
226 | }
227 | },
228 | "node_modules/@azure/msal-browser": {
229 | "version": "4.7.0",
230 | "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.7.0.tgz",
231 | "integrity": "sha512-H4AIPhIQVe1qW4+BJaitqod6UGQiXE3juj7q2ZBsOPjuZicQaqcbnBp2gCroF/icS0+TJ9rGuyCBJbjlAqVOGA==",
232 | "license": "MIT",
233 | "dependencies": {
234 | "@azure/msal-common": "15.2.1"
235 | },
236 | "engines": {
237 | "node": ">=0.8.0"
238 | }
239 | },
240 | "node_modules/@azure/msal-common": {
241 | "version": "15.2.1",
242 | "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.1.tgz",
243 | "integrity": "sha512-eZHtYE5OHDN0o2NahCENkczQ6ffGc0MoUSAI3hpwGpZBHJXaEQMMZPWtIx86da2L9w7uT+Tr/xgJbGwIkvTZTQ==",
244 | "license": "MIT",
245 | "engines": {
246 | "node": ">=0.8.0"
247 | }
248 | },
249 | "node_modules/@azure/msal-node": {
250 | "version": "3.3.0",
251 | "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.3.0.tgz",
252 | "integrity": "sha512-ulsT3EHF1RQ29X55cxBLgKsIKWni9JdbUqG7sipGVP4uhWcBpmm/vhKOMH340+27Acm9+kHGnN/5XmQ5LrIDgA==",
253 | "license": "MIT",
254 | "dependencies": {
255 | "@azure/msal-common": "15.2.1",
256 | "jsonwebtoken": "^9.0.0",
257 | "uuid": "^8.3.0"
258 | },
259 | "engines": {
260 | "node": ">=16"
261 | }
262 | },
263 | "node_modules/@cspotcode/source-map-support": {
264 | "version": "0.8.1",
265 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
266 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
267 | "dev": true,
268 | "license": "MIT",
269 | "dependencies": {
270 | "@jridgewell/trace-mapping": "0.3.9"
271 | },
272 | "engines": {
273 | "node": ">=12"
274 | }
275 | },
276 | "node_modules/@esbuild/darwin-arm64": {
277 | "version": "0.25.1",
278 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
279 | "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
280 | "cpu": [
281 | "arm64"
282 | ],
283 | "dev": true,
284 | "license": "MIT",
285 | "optional": true,
286 | "os": [
287 | "darwin"
288 | ],
289 | "engines": {
290 | "node": ">=18"
291 | }
292 | },
293 | "node_modules/@jridgewell/resolve-uri": {
294 | "version": "3.1.2",
295 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
296 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
297 | "dev": true,
298 | "license": "MIT",
299 | "engines": {
300 | "node": ">=6.0.0"
301 | }
302 | },
303 | "node_modules/@jridgewell/sourcemap-codec": {
304 | "version": "1.5.0",
305 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
306 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
307 | "dev": true,
308 | "license": "MIT"
309 | },
310 | "node_modules/@jridgewell/trace-mapping": {
311 | "version": "0.3.9",
312 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
313 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
314 | "dev": true,
315 | "license": "MIT",
316 | "dependencies": {
317 | "@jridgewell/resolve-uri": "^3.0.3",
318 | "@jridgewell/sourcemap-codec": "^1.4.10"
319 | }
320 | },
321 | "node_modules/@tsconfig/node10": {
322 | "version": "1.0.11",
323 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
324 | "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
325 | "dev": true,
326 | "license": "MIT"
327 | },
328 | "node_modules/@tsconfig/node12": {
329 | "version": "1.0.11",
330 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
331 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
332 | "dev": true,
333 | "license": "MIT"
334 | },
335 | "node_modules/@tsconfig/node14": {
336 | "version": "1.0.3",
337 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
338 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
339 | "dev": true,
340 | "license": "MIT"
341 | },
342 | "node_modules/@tsconfig/node16": {
343 | "version": "1.0.4",
344 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
345 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
346 | "dev": true,
347 | "license": "MIT"
348 | },
349 | "node_modules/@types/node": {
350 | "version": "22.13.10",
351 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
352 | "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
353 | "dev": true,
354 | "license": "MIT",
355 | "dependencies": {
356 | "undici-types": "~6.20.0"
357 | }
358 | },
359 | "node_modules/acorn": {
360 | "version": "8.14.1",
361 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
362 | "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
363 | "dev": true,
364 | "license": "MIT",
365 | "bin": {
366 | "acorn": "bin/acorn"
367 | },
368 | "engines": {
369 | "node": ">=0.4.0"
370 | }
371 | },
372 | "node_modules/acorn-walk": {
373 | "version": "8.3.4",
374 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
375 | "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
376 | "dev": true,
377 | "license": "MIT",
378 | "dependencies": {
379 | "acorn": "^8.11.0"
380 | },
381 | "engines": {
382 | "node": ">=0.4.0"
383 | }
384 | },
385 | "node_modules/agent-base": {
386 | "version": "7.1.3",
387 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
388 | "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
389 | "license": "MIT",
390 | "engines": {
391 | "node": ">= 14"
392 | }
393 | },
394 | "node_modules/ansi-regex": {
395 | "version": "5.0.1",
396 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
397 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
398 | "dev": true,
399 | "license": "MIT",
400 | "engines": {
401 | "node": ">=8"
402 | }
403 | },
404 | "node_modules/ansi-styles": {
405 | "version": "4.3.0",
406 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
407 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
408 | "dev": true,
409 | "license": "MIT",
410 | "dependencies": {
411 | "color-convert": "^2.0.1"
412 | },
413 | "engines": {
414 | "node": ">=8"
415 | },
416 | "funding": {
417 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
418 | }
419 | },
420 | "node_modules/anymatch": {
421 | "version": "3.1.3",
422 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
423 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
424 | "dev": true,
425 | "license": "ISC",
426 | "dependencies": {
427 | "normalize-path": "^3.0.0",
428 | "picomatch": "^2.0.4"
429 | },
430 | "engines": {
431 | "node": ">= 8"
432 | }
433 | },
434 | "node_modules/arg": {
435 | "version": "4.1.3",
436 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
437 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
438 | "dev": true,
439 | "license": "MIT"
440 | },
441 | "node_modules/balanced-match": {
442 | "version": "1.0.2",
443 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
444 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
445 | "dev": true,
446 | "license": "MIT"
447 | },
448 | "node_modules/binary-extensions": {
449 | "version": "2.3.0",
450 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
451 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
452 | "dev": true,
453 | "license": "MIT",
454 | "engines": {
455 | "node": ">=8"
456 | },
457 | "funding": {
458 | "url": "https://github.com/sponsors/sindresorhus"
459 | }
460 | },
461 | "node_modules/brace-expansion": {
462 | "version": "1.1.11",
463 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
464 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
465 | "dev": true,
466 | "license": "MIT",
467 | "dependencies": {
468 | "balanced-match": "^1.0.0",
469 | "concat-map": "0.0.1"
470 | }
471 | },
472 | "node_modules/braces": {
473 | "version": "3.0.3",
474 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
475 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
476 | "dev": true,
477 | "license": "MIT",
478 | "dependencies": {
479 | "fill-range": "^7.1.1"
480 | },
481 | "engines": {
482 | "node": ">=8"
483 | }
484 | },
485 | "node_modules/buffer-equal-constant-time": {
486 | "version": "1.0.1",
487 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
488 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
489 | "license": "BSD-3-Clause"
490 | },
491 | "node_modules/bundle-name": {
492 | "version": "4.1.0",
493 | "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
494 | "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
495 | "license": "MIT",
496 | "dependencies": {
497 | "run-applescript": "^7.0.0"
498 | },
499 | "engines": {
500 | "node": ">=18"
501 | },
502 | "funding": {
503 | "url": "https://github.com/sponsors/sindresorhus"
504 | }
505 | },
506 | "node_modules/chalk": {
507 | "version": "4.1.2",
508 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
509 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
510 | "dev": true,
511 | "license": "MIT",
512 | "dependencies": {
513 | "ansi-styles": "^4.1.0",
514 | "supports-color": "^7.1.0"
515 | },
516 | "engines": {
517 | "node": ">=10"
518 | },
519 | "funding": {
520 | "url": "https://github.com/chalk/chalk?sponsor=1"
521 | }
522 | },
523 | "node_modules/chalk/node_modules/supports-color": {
524 | "version": "7.2.0",
525 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
526 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
527 | "dev": true,
528 | "license": "MIT",
529 | "dependencies": {
530 | "has-flag": "^4.0.0"
531 | },
532 | "engines": {
533 | "node": ">=8"
534 | }
535 | },
536 | "node_modules/chokidar": {
537 | "version": "3.6.0",
538 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
539 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
540 | "dev": true,
541 | "license": "MIT",
542 | "dependencies": {
543 | "anymatch": "~3.1.2",
544 | "braces": "~3.0.2",
545 | "glob-parent": "~5.1.2",
546 | "is-binary-path": "~2.1.0",
547 | "is-glob": "~4.0.1",
548 | "normalize-path": "~3.0.0",
549 | "readdirp": "~3.6.0"
550 | },
551 | "engines": {
552 | "node": ">= 8.10.0"
553 | },
554 | "funding": {
555 | "url": "https://paulmillr.com/funding/"
556 | },
557 | "optionalDependencies": {
558 | "fsevents": "~2.3.2"
559 | }
560 | },
561 | "node_modules/cliui": {
562 | "version": "8.0.1",
563 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
564 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
565 | "dev": true,
566 | "license": "ISC",
567 | "dependencies": {
568 | "string-width": "^4.2.0",
569 | "strip-ansi": "^6.0.1",
570 | "wrap-ansi": "^7.0.0"
571 | },
572 | "engines": {
573 | "node": ">=12"
574 | }
575 | },
576 | "node_modules/color-convert": {
577 | "version": "2.0.1",
578 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
579 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
580 | "dev": true,
581 | "license": "MIT",
582 | "dependencies": {
583 | "color-name": "~1.1.4"
584 | },
585 | "engines": {
586 | "node": ">=7.0.0"
587 | }
588 | },
589 | "node_modules/color-name": {
590 | "version": "1.1.4",
591 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
592 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
593 | "dev": true,
594 | "license": "MIT"
595 | },
596 | "node_modules/concat-map": {
597 | "version": "0.0.1",
598 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
599 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
600 | "dev": true,
601 | "license": "MIT"
602 | },
603 | "node_modules/concurrently": {
604 | "version": "9.1.2",
605 | "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz",
606 | "integrity": "sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==",
607 | "dev": true,
608 | "license": "MIT",
609 | "dependencies": {
610 | "chalk": "^4.1.2",
611 | "lodash": "^4.17.21",
612 | "rxjs": "^7.8.1",
613 | "shell-quote": "^1.8.1",
614 | "supports-color": "^8.1.1",
615 | "tree-kill": "^1.2.2",
616 | "yargs": "^17.7.2"
617 | },
618 | "bin": {
619 | "conc": "dist/bin/concurrently.js",
620 | "concurrently": "dist/bin/concurrently.js"
621 | },
622 | "engines": {
623 | "node": ">=18"
624 | },
625 | "funding": {
626 | "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
627 | }
628 | },
629 | "node_modules/create-require": {
630 | "version": "1.1.1",
631 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
632 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
633 | "dev": true,
634 | "license": "MIT"
635 | },
636 | "node_modules/debug": {
637 | "version": "4.4.0",
638 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
639 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
640 | "license": "MIT",
641 | "dependencies": {
642 | "ms": "^2.1.3"
643 | },
644 | "engines": {
645 | "node": ">=6.0"
646 | },
647 | "peerDependenciesMeta": {
648 | "supports-color": {
649 | "optional": true
650 | }
651 | }
652 | },
653 | "node_modules/default-browser": {
654 | "version": "5.2.1",
655 | "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
656 | "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
657 | "license": "MIT",
658 | "dependencies": {
659 | "bundle-name": "^4.1.0",
660 | "default-browser-id": "^5.0.0"
661 | },
662 | "engines": {
663 | "node": ">=18"
664 | },
665 | "funding": {
666 | "url": "https://github.com/sponsors/sindresorhus"
667 | }
668 | },
669 | "node_modules/default-browser-id": {
670 | "version": "5.0.0",
671 | "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
672 | "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
673 | "license": "MIT",
674 | "engines": {
675 | "node": ">=18"
676 | },
677 | "funding": {
678 | "url": "https://github.com/sponsors/sindresorhus"
679 | }
680 | },
681 | "node_modules/define-lazy-prop": {
682 | "version": "3.0.0",
683 | "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
684 | "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
685 | "license": "MIT",
686 | "engines": {
687 | "node": ">=12"
688 | },
689 | "funding": {
690 | "url": "https://github.com/sponsors/sindresorhus"
691 | }
692 | },
693 | "node_modules/diff": {
694 | "version": "4.0.2",
695 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
696 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
697 | "dev": true,
698 | "license": "BSD-3-Clause",
699 | "engines": {
700 | "node": ">=0.3.1"
701 | }
702 | },
703 | "node_modules/dotenv": {
704 | "version": "16.4.7",
705 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
706 | "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
707 | "license": "BSD-2-Clause",
708 | "engines": {
709 | "node": ">=12"
710 | },
711 | "funding": {
712 | "url": "https://dotenvx.com"
713 | }
714 | },
715 | "node_modules/ecdsa-sig-formatter": {
716 | "version": "1.0.11",
717 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
718 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
719 | "license": "Apache-2.0",
720 | "dependencies": {
721 | "safe-buffer": "^5.0.1"
722 | }
723 | },
724 | "node_modules/emoji-regex": {
725 | "version": "8.0.0",
726 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
727 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
728 | "dev": true,
729 | "license": "MIT"
730 | },
731 | "node_modules/esbuild": {
732 | "version": "0.25.1",
733 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
734 | "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
735 | "dev": true,
736 | "hasInstallScript": true,
737 | "license": "MIT",
738 | "bin": {
739 | "esbuild": "bin/esbuild"
740 | },
741 | "engines": {
742 | "node": ">=18"
743 | },
744 | "optionalDependencies": {
745 | "@esbuild/aix-ppc64": "0.25.1",
746 | "@esbuild/android-arm": "0.25.1",
747 | "@esbuild/android-arm64": "0.25.1",
748 | "@esbuild/android-x64": "0.25.1",
749 | "@esbuild/darwin-arm64": "0.25.1",
750 | "@esbuild/darwin-x64": "0.25.1",
751 | "@esbuild/freebsd-arm64": "0.25.1",
752 | "@esbuild/freebsd-x64": "0.25.1",
753 | "@esbuild/linux-arm": "0.25.1",
754 | "@esbuild/linux-arm64": "0.25.1",
755 | "@esbuild/linux-ia32": "0.25.1",
756 | "@esbuild/linux-loong64": "0.25.1",
757 | "@esbuild/linux-mips64el": "0.25.1",
758 | "@esbuild/linux-ppc64": "0.25.1",
759 | "@esbuild/linux-riscv64": "0.25.1",
760 | "@esbuild/linux-s390x": "0.25.1",
761 | "@esbuild/linux-x64": "0.25.1",
762 | "@esbuild/netbsd-arm64": "0.25.1",
763 | "@esbuild/netbsd-x64": "0.25.1",
764 | "@esbuild/openbsd-arm64": "0.25.1",
765 | "@esbuild/openbsd-x64": "0.25.1",
766 | "@esbuild/sunos-x64": "0.25.1",
767 | "@esbuild/win32-arm64": "0.25.1",
768 | "@esbuild/win32-ia32": "0.25.1",
769 | "@esbuild/win32-x64": "0.25.1"
770 | }
771 | },
772 | "node_modules/escalade": {
773 | "version": "3.2.0",
774 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
775 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
776 | "dev": true,
777 | "license": "MIT",
778 | "engines": {
779 | "node": ">=6"
780 | }
781 | },
782 | "node_modules/events": {
783 | "version": "3.3.0",
784 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
785 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
786 | "license": "MIT",
787 | "engines": {
788 | "node": ">=0.8.x"
789 | }
790 | },
791 | "node_modules/fill-range": {
792 | "version": "7.1.1",
793 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
794 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
795 | "dev": true,
796 | "license": "MIT",
797 | "dependencies": {
798 | "to-regex-range": "^5.0.1"
799 | },
800 | "engines": {
801 | "node": ">=8"
802 | }
803 | },
804 | "node_modules/fsevents": {
805 | "version": "2.3.3",
806 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
807 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
808 | "dev": true,
809 | "hasInstallScript": true,
810 | "license": "MIT",
811 | "optional": true,
812 | "os": [
813 | "darwin"
814 | ],
815 | "engines": {
816 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
817 | }
818 | },
819 | "node_modules/get-caller-file": {
820 | "version": "2.0.5",
821 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
822 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
823 | "dev": true,
824 | "license": "ISC",
825 | "engines": {
826 | "node": "6.* || 8.* || >= 10.*"
827 | }
828 | },
829 | "node_modules/get-tsconfig": {
830 | "version": "4.10.0",
831 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
832 | "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
833 | "dev": true,
834 | "license": "MIT",
835 | "dependencies": {
836 | "resolve-pkg-maps": "^1.0.0"
837 | },
838 | "funding": {
839 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
840 | }
841 | },
842 | "node_modules/glob-parent": {
843 | "version": "5.1.2",
844 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
845 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
846 | "dev": true,
847 | "license": "ISC",
848 | "dependencies": {
849 | "is-glob": "^4.0.1"
850 | },
851 | "engines": {
852 | "node": ">= 6"
853 | }
854 | },
855 | "node_modules/has-flag": {
856 | "version": "4.0.0",
857 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
858 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
859 | "dev": true,
860 | "license": "MIT",
861 | "engines": {
862 | "node": ">=8"
863 | }
864 | },
865 | "node_modules/http-proxy-agent": {
866 | "version": "7.0.2",
867 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
868 | "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
869 | "license": "MIT",
870 | "dependencies": {
871 | "agent-base": "^7.1.0",
872 | "debug": "^4.3.4"
873 | },
874 | "engines": {
875 | "node": ">= 14"
876 | }
877 | },
878 | "node_modules/https-proxy-agent": {
879 | "version": "7.0.6",
880 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
881 | "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
882 | "license": "MIT",
883 | "dependencies": {
884 | "agent-base": "^7.1.2",
885 | "debug": "4"
886 | },
887 | "engines": {
888 | "node": ">= 14"
889 | }
890 | },
891 | "node_modules/ignore-by-default": {
892 | "version": "1.0.1",
893 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
894 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
895 | "dev": true,
896 | "license": "ISC"
897 | },
898 | "node_modules/is-binary-path": {
899 | "version": "2.1.0",
900 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
901 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
902 | "dev": true,
903 | "license": "MIT",
904 | "dependencies": {
905 | "binary-extensions": "^2.0.0"
906 | },
907 | "engines": {
908 | "node": ">=8"
909 | }
910 | },
911 | "node_modules/is-docker": {
912 | "version": "3.0.0",
913 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
914 | "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
915 | "license": "MIT",
916 | "bin": {
917 | "is-docker": "cli.js"
918 | },
919 | "engines": {
920 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
921 | },
922 | "funding": {
923 | "url": "https://github.com/sponsors/sindresorhus"
924 | }
925 | },
926 | "node_modules/is-extglob": {
927 | "version": "2.1.1",
928 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
929 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
930 | "dev": true,
931 | "license": "MIT",
932 | "engines": {
933 | "node": ">=0.10.0"
934 | }
935 | },
936 | "node_modules/is-fullwidth-code-point": {
937 | "version": "3.0.0",
938 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
939 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
940 | "dev": true,
941 | "license": "MIT",
942 | "engines": {
943 | "node": ">=8"
944 | }
945 | },
946 | "node_modules/is-glob": {
947 | "version": "4.0.3",
948 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
949 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
950 | "dev": true,
951 | "license": "MIT",
952 | "dependencies": {
953 | "is-extglob": "^2.1.1"
954 | },
955 | "engines": {
956 | "node": ">=0.10.0"
957 | }
958 | },
959 | "node_modules/is-inside-container": {
960 | "version": "1.0.0",
961 | "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
962 | "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
963 | "license": "MIT",
964 | "dependencies": {
965 | "is-docker": "^3.0.0"
966 | },
967 | "bin": {
968 | "is-inside-container": "cli.js"
969 | },
970 | "engines": {
971 | "node": ">=14.16"
972 | },
973 | "funding": {
974 | "url": "https://github.com/sponsors/sindresorhus"
975 | }
976 | },
977 | "node_modules/is-number": {
978 | "version": "7.0.0",
979 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
980 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
981 | "dev": true,
982 | "license": "MIT",
983 | "engines": {
984 | "node": ">=0.12.0"
985 | }
986 | },
987 | "node_modules/is-wsl": {
988 | "version": "3.1.0",
989 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
990 | "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
991 | "license": "MIT",
992 | "dependencies": {
993 | "is-inside-container": "^1.0.0"
994 | },
995 | "engines": {
996 | "node": ">=16"
997 | },
998 | "funding": {
999 | "url": "https://github.com/sponsors/sindresorhus"
1000 | }
1001 | },
1002 | "node_modules/jsonwebtoken": {
1003 | "version": "9.0.2",
1004 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
1005 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
1006 | "license": "MIT",
1007 | "dependencies": {
1008 | "jws": "^3.2.2",
1009 | "lodash.includes": "^4.3.0",
1010 | "lodash.isboolean": "^3.0.3",
1011 | "lodash.isinteger": "^4.0.4",
1012 | "lodash.isnumber": "^3.0.3",
1013 | "lodash.isplainobject": "^4.0.6",
1014 | "lodash.isstring": "^4.0.1",
1015 | "lodash.once": "^4.0.0",
1016 | "ms": "^2.1.1",
1017 | "semver": "^7.5.4"
1018 | },
1019 | "engines": {
1020 | "node": ">=12",
1021 | "npm": ">=6"
1022 | }
1023 | },
1024 | "node_modules/jsonwebtoken/node_modules/jwa": {
1025 | "version": "1.4.1",
1026 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
1027 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
1028 | "license": "MIT",
1029 | "dependencies": {
1030 | "buffer-equal-constant-time": "1.0.1",
1031 | "ecdsa-sig-formatter": "1.0.11",
1032 | "safe-buffer": "^5.0.1"
1033 | }
1034 | },
1035 | "node_modules/jsonwebtoken/node_modules/jws": {
1036 | "version": "3.2.2",
1037 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
1038 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
1039 | "license": "MIT",
1040 | "dependencies": {
1041 | "jwa": "^1.4.1",
1042 | "safe-buffer": "^5.0.1"
1043 | }
1044 | },
1045 | "node_modules/jwa": {
1046 | "version": "2.0.0",
1047 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
1048 | "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
1049 | "license": "MIT",
1050 | "dependencies": {
1051 | "buffer-equal-constant-time": "1.0.1",
1052 | "ecdsa-sig-formatter": "1.0.11",
1053 | "safe-buffer": "^5.0.1"
1054 | }
1055 | },
1056 | "node_modules/jws": {
1057 | "version": "4.0.0",
1058 | "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
1059 | "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
1060 | "license": "MIT",
1061 | "dependencies": {
1062 | "jwa": "^2.0.0",
1063 | "safe-buffer": "^5.0.1"
1064 | }
1065 | },
1066 | "node_modules/lodash": {
1067 | "version": "4.17.21",
1068 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
1069 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
1070 | "dev": true,
1071 | "license": "MIT"
1072 | },
1073 | "node_modules/lodash.includes": {
1074 | "version": "4.3.0",
1075 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
1076 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
1077 | "license": "MIT"
1078 | },
1079 | "node_modules/lodash.isboolean": {
1080 | "version": "3.0.3",
1081 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
1082 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
1083 | "license": "MIT"
1084 | },
1085 | "node_modules/lodash.isinteger": {
1086 | "version": "4.0.4",
1087 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
1088 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
1089 | "license": "MIT"
1090 | },
1091 | "node_modules/lodash.isnumber": {
1092 | "version": "3.0.3",
1093 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
1094 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
1095 | "license": "MIT"
1096 | },
1097 | "node_modules/lodash.isplainobject": {
1098 | "version": "4.0.6",
1099 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
1100 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
1101 | "license": "MIT"
1102 | },
1103 | "node_modules/lodash.isstring": {
1104 | "version": "4.0.1",
1105 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
1106 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
1107 | "license": "MIT"
1108 | },
1109 | "node_modules/lodash.once": {
1110 | "version": "4.1.1",
1111 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
1112 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
1113 | "license": "MIT"
1114 | },
1115 | "node_modules/make-error": {
1116 | "version": "1.3.6",
1117 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
1118 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
1119 | "dev": true,
1120 | "license": "ISC"
1121 | },
1122 | "node_modules/minimatch": {
1123 | "version": "3.1.2",
1124 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1125 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1126 | "dev": true,
1127 | "license": "ISC",
1128 | "dependencies": {
1129 | "brace-expansion": "^1.1.7"
1130 | },
1131 | "engines": {
1132 | "node": "*"
1133 | }
1134 | },
1135 | "node_modules/ms": {
1136 | "version": "2.1.3",
1137 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1138 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1139 | "license": "MIT"
1140 | },
1141 | "node_modules/nodemon": {
1142 | "version": "3.1.9",
1143 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
1144 | "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
1145 | "dev": true,
1146 | "license": "MIT",
1147 | "dependencies": {
1148 | "chokidar": "^3.5.2",
1149 | "debug": "^4",
1150 | "ignore-by-default": "^1.0.1",
1151 | "minimatch": "^3.1.2",
1152 | "pstree.remy": "^1.1.8",
1153 | "semver": "^7.5.3",
1154 | "simple-update-notifier": "^2.0.0",
1155 | "supports-color": "^5.5.0",
1156 | "touch": "^3.1.0",
1157 | "undefsafe": "^2.0.5"
1158 | },
1159 | "bin": {
1160 | "nodemon": "bin/nodemon.js"
1161 | },
1162 | "engines": {
1163 | "node": ">=10"
1164 | },
1165 | "funding": {
1166 | "type": "opencollective",
1167 | "url": "https://opencollective.com/nodemon"
1168 | }
1169 | },
1170 | "node_modules/nodemon/node_modules/has-flag": {
1171 | "version": "3.0.0",
1172 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1173 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
1174 | "dev": true,
1175 | "license": "MIT",
1176 | "engines": {
1177 | "node": ">=4"
1178 | }
1179 | },
1180 | "node_modules/nodemon/node_modules/supports-color": {
1181 | "version": "5.5.0",
1182 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1183 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1184 | "dev": true,
1185 | "license": "MIT",
1186 | "dependencies": {
1187 | "has-flag": "^3.0.0"
1188 | },
1189 | "engines": {
1190 | "node": ">=4"
1191 | }
1192 | },
1193 | "node_modules/normalize-path": {
1194 | "version": "3.0.0",
1195 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1196 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1197 | "dev": true,
1198 | "license": "MIT",
1199 | "engines": {
1200 | "node": ">=0.10.0"
1201 | }
1202 | },
1203 | "node_modules/open": {
1204 | "version": "10.1.0",
1205 | "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
1206 | "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
1207 | "license": "MIT",
1208 | "dependencies": {
1209 | "default-browser": "^5.2.1",
1210 | "define-lazy-prop": "^3.0.0",
1211 | "is-inside-container": "^1.0.0",
1212 | "is-wsl": "^3.1.0"
1213 | },
1214 | "engines": {
1215 | "node": ">=18"
1216 | },
1217 | "funding": {
1218 | "url": "https://github.com/sponsors/sindresorhus"
1219 | }
1220 | },
1221 | "node_modules/picomatch": {
1222 | "version": "2.3.1",
1223 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1224 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1225 | "dev": true,
1226 | "license": "MIT",
1227 | "engines": {
1228 | "node": ">=8.6"
1229 | },
1230 | "funding": {
1231 | "url": "https://github.com/sponsors/jonschlinkert"
1232 | }
1233 | },
1234 | "node_modules/pstree.remy": {
1235 | "version": "1.1.8",
1236 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
1237 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
1238 | "dev": true,
1239 | "license": "MIT"
1240 | },
1241 | "node_modules/readdirp": {
1242 | "version": "3.6.0",
1243 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1244 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1245 | "dev": true,
1246 | "license": "MIT",
1247 | "dependencies": {
1248 | "picomatch": "^2.2.1"
1249 | },
1250 | "engines": {
1251 | "node": ">=8.10.0"
1252 | }
1253 | },
1254 | "node_modules/require-directory": {
1255 | "version": "2.1.1",
1256 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1257 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
1258 | "dev": true,
1259 | "license": "MIT",
1260 | "engines": {
1261 | "node": ">=0.10.0"
1262 | }
1263 | },
1264 | "node_modules/resolve-pkg-maps": {
1265 | "version": "1.0.0",
1266 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
1267 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
1268 | "dev": true,
1269 | "license": "MIT",
1270 | "funding": {
1271 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
1272 | }
1273 | },
1274 | "node_modules/run-applescript": {
1275 | "version": "7.0.0",
1276 | "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
1277 | "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
1278 | "license": "MIT",
1279 | "engines": {
1280 | "node": ">=18"
1281 | },
1282 | "funding": {
1283 | "url": "https://github.com/sponsors/sindresorhus"
1284 | }
1285 | },
1286 | "node_modules/rxjs": {
1287 | "version": "7.8.2",
1288 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
1289 | "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
1290 | "dev": true,
1291 | "license": "Apache-2.0",
1292 | "dependencies": {
1293 | "tslib": "^2.1.0"
1294 | }
1295 | },
1296 | "node_modules/safe-buffer": {
1297 | "version": "5.2.1",
1298 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1299 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1300 | "funding": [
1301 | {
1302 | "type": "github",
1303 | "url": "https://github.com/sponsors/feross"
1304 | },
1305 | {
1306 | "type": "patreon",
1307 | "url": "https://www.patreon.com/feross"
1308 | },
1309 | {
1310 | "type": "consulting",
1311 | "url": "https://feross.org/support"
1312 | }
1313 | ],
1314 | "license": "MIT"
1315 | },
1316 | "node_modules/semver": {
1317 | "version": "7.7.1",
1318 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
1319 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
1320 | "license": "ISC",
1321 | "bin": {
1322 | "semver": "bin/semver.js"
1323 | },
1324 | "engines": {
1325 | "node": ">=10"
1326 | }
1327 | },
1328 | "node_modules/shell-quote": {
1329 | "version": "1.8.2",
1330 | "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
1331 | "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
1332 | "dev": true,
1333 | "license": "MIT",
1334 | "engines": {
1335 | "node": ">= 0.4"
1336 | },
1337 | "funding": {
1338 | "url": "https://github.com/sponsors/ljharb"
1339 | }
1340 | },
1341 | "node_modules/simple-update-notifier": {
1342 | "version": "2.0.0",
1343 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
1344 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
1345 | "dev": true,
1346 | "license": "MIT",
1347 | "dependencies": {
1348 | "semver": "^7.5.3"
1349 | },
1350 | "engines": {
1351 | "node": ">=10"
1352 | }
1353 | },
1354 | "node_modules/stoppable": {
1355 | "version": "1.1.0",
1356 | "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
1357 | "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
1358 | "license": "MIT",
1359 | "engines": {
1360 | "node": ">=4",
1361 | "npm": ">=6"
1362 | }
1363 | },
1364 | "node_modules/string-width": {
1365 | "version": "4.2.3",
1366 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1367 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1368 | "dev": true,
1369 | "license": "MIT",
1370 | "dependencies": {
1371 | "emoji-regex": "^8.0.0",
1372 | "is-fullwidth-code-point": "^3.0.0",
1373 | "strip-ansi": "^6.0.1"
1374 | },
1375 | "engines": {
1376 | "node": ">=8"
1377 | }
1378 | },
1379 | "node_modules/strip-ansi": {
1380 | "version": "6.0.1",
1381 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1382 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1383 | "dev": true,
1384 | "license": "MIT",
1385 | "dependencies": {
1386 | "ansi-regex": "^5.0.1"
1387 | },
1388 | "engines": {
1389 | "node": ">=8"
1390 | }
1391 | },
1392 | "node_modules/supports-color": {
1393 | "version": "8.1.1",
1394 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
1395 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
1396 | "dev": true,
1397 | "license": "MIT",
1398 | "dependencies": {
1399 | "has-flag": "^4.0.0"
1400 | },
1401 | "engines": {
1402 | "node": ">=10"
1403 | },
1404 | "funding": {
1405 | "url": "https://github.com/chalk/supports-color?sponsor=1"
1406 | }
1407 | },
1408 | "node_modules/to-regex-range": {
1409 | "version": "5.0.1",
1410 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1411 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1412 | "dev": true,
1413 | "license": "MIT",
1414 | "dependencies": {
1415 | "is-number": "^7.0.0"
1416 | },
1417 | "engines": {
1418 | "node": ">=8.0"
1419 | }
1420 | },
1421 | "node_modules/touch": {
1422 | "version": "3.1.1",
1423 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
1424 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
1425 | "dev": true,
1426 | "license": "ISC",
1427 | "bin": {
1428 | "nodetouch": "bin/nodetouch.js"
1429 | }
1430 | },
1431 | "node_modules/tree-kill": {
1432 | "version": "1.2.2",
1433 | "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
1434 | "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
1435 | "dev": true,
1436 | "license": "MIT",
1437 | "bin": {
1438 | "tree-kill": "cli.js"
1439 | }
1440 | },
1441 | "node_modules/ts-node": {
1442 | "version": "10.9.2",
1443 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
1444 | "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
1445 | "dev": true,
1446 | "license": "MIT",
1447 | "dependencies": {
1448 | "@cspotcode/source-map-support": "^0.8.0",
1449 | "@tsconfig/node10": "^1.0.7",
1450 | "@tsconfig/node12": "^1.0.7",
1451 | "@tsconfig/node14": "^1.0.0",
1452 | "@tsconfig/node16": "^1.0.2",
1453 | "acorn": "^8.4.1",
1454 | "acorn-walk": "^8.1.1",
1455 | "arg": "^4.1.0",
1456 | "create-require": "^1.1.0",
1457 | "diff": "^4.0.1",
1458 | "make-error": "^1.1.1",
1459 | "v8-compile-cache-lib": "^3.0.1",
1460 | "yn": "3.1.1"
1461 | },
1462 | "bin": {
1463 | "ts-node": "dist/bin.js",
1464 | "ts-node-cwd": "dist/bin-cwd.js",
1465 | "ts-node-esm": "dist/bin-esm.js",
1466 | "ts-node-script": "dist/bin-script.js",
1467 | "ts-node-transpile-only": "dist/bin-transpile.js",
1468 | "ts-script": "dist/bin-script-deprecated.js"
1469 | },
1470 | "peerDependencies": {
1471 | "@swc/core": ">=1.2.50",
1472 | "@swc/wasm": ">=1.2.50",
1473 | "@types/node": "*",
1474 | "typescript": ">=2.7"
1475 | },
1476 | "peerDependenciesMeta": {
1477 | "@swc/core": {
1478 | "optional": true
1479 | },
1480 | "@swc/wasm": {
1481 | "optional": true
1482 | }
1483 | }
1484 | },
1485 | "node_modules/tslib": {
1486 | "version": "2.8.1",
1487 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1488 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1489 | "license": "0BSD"
1490 | },
1491 | "node_modules/tsx": {
1492 | "version": "4.19.3",
1493 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz",
1494 | "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==",
1495 | "dev": true,
1496 | "license": "MIT",
1497 | "dependencies": {
1498 | "esbuild": "~0.25.0",
1499 | "get-tsconfig": "^4.7.5"
1500 | },
1501 | "bin": {
1502 | "tsx": "dist/cli.mjs"
1503 | },
1504 | "engines": {
1505 | "node": ">=18.0.0"
1506 | },
1507 | "optionalDependencies": {
1508 | "fsevents": "~2.3.3"
1509 | }
1510 | },
1511 | "node_modules/typescript": {
1512 | "version": "5.8.2",
1513 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
1514 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
1515 | "dev": true,
1516 | "license": "Apache-2.0",
1517 | "bin": {
1518 | "tsc": "bin/tsc",
1519 | "tsserver": "bin/tsserver"
1520 | },
1521 | "engines": {
1522 | "node": ">=14.17"
1523 | }
1524 | },
1525 | "node_modules/undefsafe": {
1526 | "version": "2.0.5",
1527 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1528 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
1529 | "dev": true,
1530 | "license": "MIT"
1531 | },
1532 | "node_modules/undici-types": {
1533 | "version": "6.20.0",
1534 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
1535 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
1536 | "dev": true,
1537 | "license": "MIT"
1538 | },
1539 | "node_modules/uuid": {
1540 | "version": "8.3.2",
1541 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
1542 | "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
1543 | "license": "MIT",
1544 | "bin": {
1545 | "uuid": "dist/bin/uuid"
1546 | }
1547 | },
1548 | "node_modules/v8-compile-cache-lib": {
1549 | "version": "3.0.1",
1550 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
1551 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
1552 | "dev": true,
1553 | "license": "MIT"
1554 | },
1555 | "node_modules/wrap-ansi": {
1556 | "version": "7.0.0",
1557 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1558 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1559 | "dev": true,
1560 | "license": "MIT",
1561 | "dependencies": {
1562 | "ansi-styles": "^4.0.0",
1563 | "string-width": "^4.1.0",
1564 | "strip-ansi": "^6.0.0"
1565 | },
1566 | "engines": {
1567 | "node": ">=10"
1568 | },
1569 | "funding": {
1570 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1571 | }
1572 | },
1573 | "node_modules/y18n": {
1574 | "version": "5.0.8",
1575 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1576 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1577 | "dev": true,
1578 | "license": "ISC",
1579 | "engines": {
1580 | "node": ">=10"
1581 | }
1582 | },
1583 | "node_modules/yargs": {
1584 | "version": "17.7.2",
1585 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
1586 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
1587 | "dev": true,
1588 | "license": "MIT",
1589 | "dependencies": {
1590 | "cliui": "^8.0.1",
1591 | "escalade": "^3.1.1",
1592 | "get-caller-file": "^2.0.5",
1593 | "require-directory": "^2.1.1",
1594 | "string-width": "^4.2.3",
1595 | "y18n": "^5.0.5",
1596 | "yargs-parser": "^21.1.1"
1597 | },
1598 | "engines": {
1599 | "node": ">=12"
1600 | }
1601 | },
1602 | "node_modules/yargs-parser": {
1603 | "version": "21.1.1",
1604 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
1605 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
1606 | "dev": true,
1607 | "license": "ISC",
1608 | "engines": {
1609 | "node": ">=12"
1610 | }
1611 | },
1612 | "node_modules/yn": {
1613 | "version": "3.1.1",
1614 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
1615 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
1616 | "dev": true,
1617 | "license": "MIT",
1618 | "engines": {
1619 | "node": ">=6"
1620 | }
1621 | }
1622 | }
1623 | }
1624 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "azure-ai-agents",
3 | "version": "1.0.0",
4 | "description": "Azure AI Agents QuickStart demo",
5 | "license": "ISC",
6 | "author": "Dan Wahlin",
7 | "type": "module",
8 | "main": "index.js",
9 | "scripts": {
10 | "start": "tsx ./src/index.ts",
11 | "build": "npx tsc",
12 | "basic": "tsx ./examples/1-basic.ts",
13 | "threads": "tsx ./examples/2-threads.ts",
14 | "messages": "tsx ./examples/3-messages.ts",
15 | "streaming": "tsx ./examples/4-streaming.ts",
16 | "run": "tsx ./examples/5-run.ts"
17 | },
18 | "dependencies": {
19 | "@azure/ai-projects": "^1.0.0-beta.4",
20 | "@azure/identity": "^4.8.0",
21 | "dotenv": "^16.4.7"
22 | },
23 | "devDependencies": {
24 | "@types/node": "^22.13.10",
25 | "concurrently": "^9.1.2",
26 | "nodemon": "^3.1.9",
27 | "ts-node": "^10.9.2",
28 | "tsx": "^4.19.3",
29 | "typescript": "^5.8.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/config/env.ts:
--------------------------------------------------------------------------------
1 | import { config } from 'dotenv';
2 | config();
3 |
4 | export const aiFoundryConnectionString = process.env.AI_FOUNDRY_PROJECT_CONNECTION_STRING || '';
5 | export const aiSearchConnectionId = process.env.AI_SEARCH_CONNECTION_ID || '';
6 | export const bingGroundingConnectionId = process.env.BING_GROUNDING_CONNECTION_ID || '';
7 | export const model = process.env.AI_MODEL || '';
8 |
9 | validateEnvironment();
10 |
11 | function validateEnvironment(): void {
12 | if (!aiFoundryConnectionString) {
13 | throw new Error('Please set the AI_FOUNDRY_PROJECT_CONNECTION_STRING environment variable.');
14 | }
15 |
16 | if (!aiSearchConnectionId) {
17 | console.warn('AI_SEARCH_CONNECTION_ID is not set. AI Search features will not work.');
18 | }
19 |
20 | if (!model) {
21 | throw new Error('Please set the AI_MODEL environment variable.');
22 | }
23 |
24 | if (!bingGroundingConnectionId) {
25 | throw new Error('Please set the BING_GROUNDING_CONNECTION_ID environment variable.');
26 | }
27 | }
--------------------------------------------------------------------------------
/src/config/promptConfig.ts:
--------------------------------------------------------------------------------
1 | import { PromptConfig } from '../types.js';
2 |
3 | export const promptConfig: Record = {
4 | solveEquation: {
5 | prompt: 'I need to solve the equation `3x + 11 = 14`. Can you help me?',
6 | instructions: 'You are a math agent. Use your knowledge to solve the equation.',
7 | emoji: '🧮'
8 | },
9 | localCpusUsage: {
10 | prompt: 'What is the average CPUs usage on my local machine?',
11 | instructions: 'You are a system administrator agent specializing in system performance and monitoring. Use the provided function to get the average CPU usage.',
12 | emoji: '💾',
13 | tool: 'function-tool',
14 | executor: null, // set at runtime (see toolService.ts)
15 | },
16 | codeGenerator: {
17 | prompt: 'Write a function that finds prime numbers',
18 | instructions: 'You are a math genius and a coding agent, specilizing in assisting with code generation.',
19 | tool: 'code-interpreter',
20 | emoji: '💻'
21 | },
22 | dataVisualization: {
23 | prompt: `Create visualizations from the car_sales.csv data. Include charts for:
24 | - Sales by Region
25 | - Relationships between Price, Mileage, and Year.
26 | - Sales by SalesPerson.
27 | - Sales by Make, Model, and Year for 2023.`,
28 | instructions: 'You are a data visualization agent. Use the remote code interpreter to analyze the data.',
29 | tool: 'code-interpreter',
30 | filePath: './files/car_sales_data.csv',
31 | emoji: '📊'
32 | },
33 | hotelReviews: {
34 | prompt: 'Tell me about the hotel reviews in the hotel_reviews_data.csv.',
35 | instructions: 'You are a data analysis agent. Use the remote code interpreter to analyze the data.',
36 | tool: 'code-interpreter',
37 | fileId: '',
38 | filePath: './files/hotel_reviews_data.csv',
39 | emoji: '🏨'
40 | },
41 | insuranceCoverage: {
42 | prompt: 'What are my health insurance plan coverage types?',
43 | instructions: 'You are a health insurance agent. Use the provided AI search tool to analyze the data.',
44 | tool: 'ai-search',
45 | emoji: '🏥'
46 | },
47 | stockMarket: {
48 | prompt: 'What are the latest trends in the stock market?',
49 | instructions: 'You are a stock market analyst. Use the provided Bing Grounding tool to analyze the data.',
50 | tool: 'bing-grounding',
51 | emoji: '📈'
52 | }
53 | };
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { DefaultAzureCredential } from '@azure/identity';
2 | import { AIProjectsClient } from '@azure/ai-projects';
3 | import { aiFoundryConnectionString } from './config/env.js';
4 | import { promptConfig } from './config/promptConfig.js';
5 | import { processSelectedPrompt } from './services/agentService.js';
6 | import { displayAvailablePrompts, getPromptSelection } from './utils/console.js';
7 |
8 | async function main() {
9 | try {
10 | const client = AIProjectsClient.fromConnectionString(
11 | aiFoundryConnectionString,
12 | new DefaultAzureCredential()
13 | );
14 |
15 | let continueLoop = true;
16 |
17 | while (continueLoop) {
18 | displayAvailablePrompts(promptConfig);
19 |
20 | const selectedIndex = await getPromptSelection();
21 | const promptKeys = Object.keys(promptConfig);
22 |
23 | // Check if user wants to exit
24 | if (selectedIndex === promptKeys.length) {
25 | console.log('Exiting application.');
26 | continueLoop = false;
27 | continue;
28 | }
29 |
30 | if (isNaN(selectedIndex) || selectedIndex < 0 || selectedIndex >= promptKeys.length) {
31 | console.error('Invalid selection. Please enter a number between 1 and ' + (promptKeys.length + 1));
32 | continue;
33 | }
34 |
35 | await processSelectedPrompt(client, promptKeys[selectedIndex]);
36 | }
37 | } catch (err) {
38 | console.error('The application encountered an error:', err);
39 | }
40 | }
41 |
42 | // Start the application
43 | main().catch((err) => {
44 | console.error('The sample encountered an error:', err);
45 | process.exit(1);
46 | });
--------------------------------------------------------------------------------
/src/services/agentService.ts:
--------------------------------------------------------------------------------
1 | import { AIProjectsClient, AgentOutput } from '@azure/ai-projects';
2 | import { model } from '../config/env.js';
3 | import { promptConfig } from '../config/promptConfig.js';
4 | import { PromptConfig } from '../types.js';
5 | import { createTools } from './toolService.js';
6 | import { addMessageToThread, getRunStats, printThreadMessages, runAgent } from './threadService.js';
7 | import { formatKeyToTitleCase } from '../utils/formatting.js';
8 |
9 | export async function processSelectedPrompt(client: AIProjectsClient, selectedKey: string) {
10 | const selectedPromptConfig = promptConfig[selectedKey];
11 | const emoji = selectedPromptConfig.emoji || '📝';
12 | console.log(`\nSelected: ${emoji} ${formatKeyToTitleCase(selectedKey)}`);
13 | console.log('Tools: ' + (selectedPromptConfig.tool ? selectedPromptConfig.tool : 'None'));
14 | console.log('Prompt: ' + selectedPromptConfig.prompt);
15 |
16 |
17 | try {
18 | await createTools(selectedPromptConfig, client);
19 |
20 | const agent = await client.agents.createAgent(model, {
21 | name: `agent-${selectedKey}`,
22 | instructions: selectedPromptConfig.instructions || `You are a helpful agent that can assist with ${selectedKey}.`,
23 | temperature: 0.5,
24 | tools: selectedPromptConfig.tools,
25 | toolResources: selectedPromptConfig.toolResources,
26 | requestOptions: {
27 | headers: { "x-ms-enable-preview": "true" },
28 | },
29 | });
30 |
31 | const thread = await client.agents.createThread();
32 | await addMessageToThread(client, thread.id, selectedPromptConfig.prompt);
33 |
34 | const runId = await runAgent(client, thread, agent, selectedPromptConfig);
35 | await printThreadMessages(selectedPromptConfig, client, thread.id);
36 | await getRunStats(runId, client, thread);
37 |
38 | await dispose(selectedPromptConfig, client, agent);
39 | } catch (error) {
40 | console.error(`Error processing prompt "${selectedKey}":`, error);
41 | }
42 | }
43 |
44 | /**
45 | * Cleans up resources created during the prompt execution
46 | */
47 | export async function dispose(selectedPromptConfig: PromptConfig, client: AIProjectsClient, agent: AgentOutput) {
48 | if (selectedPromptConfig.fileId) {
49 | console.log(`\nDeleting file with ID: ${selectedPromptConfig.fileId}`);
50 | await client.agents.deleteFile(selectedPromptConfig.fileId);
51 | }
52 | console.log(`\nDeleting agent with ID: ${agent.id}`);
53 | await client.agents.deleteAgent(agent.id);
54 | }
--------------------------------------------------------------------------------
/src/services/threadService.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | AgentOutput,
3 | FunctionToolDefinitionOutput,
4 | MessageDeltaChunk,
5 | MessageDeltaTextContent,
6 | MessageImageFileContentOutput,
7 | MessageTextContentOutput,
8 | OpenAIPageableListOfThreadMessageOutput,
9 | SubmitToolOutputsActionOutput,
10 | ThreadRunOutput,
11 | ToolOutput,
12 | } from "@azure/ai-projects";
13 | import {
14 | AIProjectsClient,
15 | AgentThreadOutput,
16 | DoneEvent,
17 | ErrorEvent,
18 | MessageStreamEvent,
19 | RunStreamEvent,
20 | isOutputOfType
21 | } from "@azure/ai-projects";
22 | import fs from "fs";
23 | import { PromptConfig } from "../types.js";
24 |
25 | export async function addMessageToThread(
26 | client: AIProjectsClient,
27 | threadId: string,
28 | message: string
29 | ) {
30 | await client.agents.createMessage(threadId, {
31 | role: "user",
32 | content: message,
33 | });
34 | }
35 |
36 | export async function printThreadMessages(
37 | selectedPromptConfig: PromptConfig,
38 | client: AIProjectsClient,
39 | threadId: string
40 | ) {
41 | const messages = await client.agents.listMessages(threadId);
42 | console.log("\nMessages:\n----------------------------------------------");
43 |
44 | // Messages iterate from oldest to newest - messages[0] is the most recent
45 | const messagesArray = messages.data;
46 | for (let i = messagesArray.length - 1; i >= 0; i--) {
47 | const m = messagesArray[i];
48 | const content = m.content[0];
49 |
50 | if (!content) {
51 | // Skip if no content
52 | continue;
53 | }
54 |
55 | console.log(`Type: ${m.content[0].type}`);
56 | if (isOutputOfType(m.content[0], "text")) {
57 | const textContent = m.content[0] as MessageTextContentOutput;
58 | const role = m.role === "user" ? "User" : "Agent";
59 | console.log(`${role}: ${textContent.text.value}`);
60 | }
61 | }
62 |
63 | if (
64 | selectedPromptConfig.tool === "code-interpreter" &&
65 | selectedPromptConfig.filePath
66 | ) {
67 | await getImages(client, messages);
68 | }
69 | }
70 |
71 | export async function getImages(
72 | client: AIProjectsClient,
73 | messages: OpenAIPageableListOfThreadMessageOutput
74 | ) {
75 | console.log("Looking for image files...");
76 | const fileIds: string[] = [];
77 | for (const data of messages.data) {
78 | for (const content of data.content) {
79 | const imageFile = (content as MessageImageFileContentOutput).imageFile;
80 | if (imageFile) {
81 | fileIds.push(imageFile.fileId);
82 | const imageFileName = (await client.agents.getFile(imageFile.fileId))
83 | .filename;
84 |
85 | const fileContent = await (
86 | await client.agents.getFileContent(imageFile.fileId).asNodeStream()
87 | ).body;
88 | if (fileContent) {
89 | const chunks: Buffer[] = [];
90 | for await (const chunk of fileContent) {
91 | chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
92 | }
93 | const buffer = Buffer.concat(chunks);
94 |
95 | // Ensure downloads directory exists
96 | if (!fs.existsSync("./downloads")) {
97 | fs.mkdirSync("./downloads", { recursive: true });
98 | }
99 |
100 | fs.writeFileSync(`./downloads/${imageFileName}`, buffer);
101 | } else {
102 | console.error(
103 | "Failed to retrieve file content: fileContent is undefined"
104 | );
105 | }
106 | console.log(`Saved image file to: ${imageFileName}`);
107 | }
108 | }
109 | }
110 |
111 | //Delete remote files
112 | for (const fileId of fileIds) {
113 | console.log(`Deleting remote image file with ID: ${fileId}`);
114 | await client.agents.deleteFile(fileId);
115 | }
116 | }
117 |
118 | export async function getRunStats(
119 | runId: string,
120 | client: AIProjectsClient,
121 | thread: AgentThreadOutput
122 | ) {
123 | if (runId) {
124 | const completedRun = await client.agents.getRun(thread.id, runId);
125 | console.log("\nToken usage:", completedRun.usage);
126 | }
127 | }
128 |
129 | export async function runAgent(
130 | client: AIProjectsClient,
131 | thread: AgentThreadOutput,
132 | agent: AgentOutput,
133 | promptConfig: PromptConfig
134 | ): Promise {
135 | const run = client.agents.createRun(thread.id, agent.id, {parallelToolCalls: false});
136 | let streamEventMessages = await run.stream();
137 | let runId = "";
138 |
139 | for await (const eventMessage of streamEventMessages) {
140 |
141 | switch (eventMessage.event) {
142 | case RunStreamEvent.ThreadRunCreated:
143 | runId = (eventMessage.data as ThreadRunOutput).id;
144 | break;
145 |
146 | case MessageStreamEvent.ThreadMessageDelta:
147 | {
148 | const messageDelta = eventMessage.data as MessageDeltaChunk;
149 | messageDelta.delta.content.forEach(async (contentPart) => {
150 | if (contentPart.type === "text") {
151 | const textContent = contentPart as MessageDeltaTextContent;
152 | const textValue = textContent.text?.value || "";
153 | process.stdout.write(textValue);
154 | }
155 | if (contentPart.type === "image_file") {
156 | process.stdout.write(`\nReceived image file\n`);
157 | }
158 | });
159 | }
160 | break;
161 |
162 | case RunStreamEvent.ThreadRunRequiresAction:
163 | let runOutput = eventMessage.data as ThreadRunOutput;
164 | if (runOutput.requiredAction) {
165 | const runStream = await processRequiredAction(
166 | client,
167 | thread,
168 | runOutput,
169 | promptConfig
170 | );
171 | if (runStream) {
172 | streamEventMessages = runStream;
173 | }
174 | }
175 | break;
176 |
177 | case RunStreamEvent.ThreadRunCompleted:
178 | console.log("\nThread run completed.");
179 | break;
180 |
181 | case ErrorEvent.Error:
182 | console.error("Error:", eventMessage.data);
183 | break;
184 |
185 | case DoneEvent.Done:
186 | // Nothing to do here
187 | break;
188 | }
189 | }
190 |
191 | return runId;
192 | }
193 |
194 | async function processRequiredAction(
195 | client: AIProjectsClient,
196 | thread: AgentThreadOutput,
197 | run: ThreadRunOutput,
198 | promptConfig: PromptConfig
199 | ) {
200 | if (
201 | run.requiredAction &&
202 | isOutputOfType(
203 | run.requiredAction,
204 | "submit_tool_outputs"
205 | )
206 | ) {
207 | const submitToolOutputsActionOutput = run.requiredAction;
208 | const toolCalls = submitToolOutputsActionOutput.submitToolOutputs.toolCalls;
209 | const toolResponses: ToolOutput[] = [];
210 | for (const toolCall of toolCalls) {
211 | if (isOutputOfType(toolCall, "function")) {
212 | const toolResponse = promptConfig.executor?.invokeTool(
213 | toolCall
214 | ) as ToolOutput;
215 | console.log(`💡 Function tool ${toolCall.id} - ${toolResponse.output}`);
216 | if (toolResponse) {
217 | toolResponses.push(toolResponse);
218 | }
219 | }
220 | }
221 | if (toolResponses.length > 0) {
222 | console.log(`Submitting tool outputs to run ID ${run.id}`);
223 | return client.agents
224 | .submitToolOutputsToRun(thread.id, run.id, toolResponses)
225 | .stream();
226 | }
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/src/services/toolService.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import { cpus } from "os";
3 | import {
4 | AIProjectsClient,
5 | connectionToolType,
6 | FunctionToolDefinition,
7 | FunctionToolDefinitionOutput,
8 | RequiredToolCallOutput,
9 | ToolOutput,
10 | ToolUtility,
11 | } from "@azure/ai-projects";
12 | import {
13 | aiSearchConnectionId,
14 | bingGroundingConnectionId,
15 | } from "../config/env.js";
16 | import { PromptConfig } from "../types.js";
17 |
18 | export async function createTools(
19 | selectedPromptConfig: PromptConfig,
20 | client: AIProjectsClient
21 | ) {
22 | if (selectedPromptConfig.tool === "code-interpreter") {
23 | const { codeInterpreterTool, file } = await getCodeInterpreter(
24 | selectedPromptConfig,
25 | client
26 | );
27 | if (file) {
28 | selectedPromptConfig.fileId = file?.id;
29 | }
30 | selectedPromptConfig.tools = [codeInterpreterTool.definition];
31 | selectedPromptConfig.toolResources = codeInterpreterTool.resources;
32 | }
33 |
34 | if (selectedPromptConfig.tool === "ai-search") {
35 | const azureAISearchTool = await createAISearchTool(client);
36 | selectedPromptConfig.tools = [azureAISearchTool.definition];
37 | selectedPromptConfig.toolResources = azureAISearchTool.resources;
38 | }
39 |
40 | if (selectedPromptConfig.tool === "function-tool") {
41 | selectedPromptConfig.executor = FunctionToolExecutor;
42 | selectedPromptConfig.tools = [
43 | ...FunctionToolExecutor.getFunctionDefinitions(),
44 | ];
45 | selectedPromptConfig.toolResources = {};
46 | }
47 |
48 | if (selectedPromptConfig.tool === "bing-grounding") {
49 | const bingTool = await createBingGroundingTool(client);
50 | selectedPromptConfig.tools = [bingTool.definition];
51 | }
52 | }
53 |
54 | export async function getCodeInterpreter(
55 | selectedPromptConfig: PromptConfig,
56 | client: AIProjectsClient
57 | ) {
58 | if (selectedPromptConfig.filePath) {
59 | const fileStream = fs.createReadStream(selectedPromptConfig.filePath);
60 | const file = await client.agents.uploadFile(fileStream, "assistants", {
61 | fileName: selectedPromptConfig.filePath,
62 | });
63 | console.log(
64 | `Uploaded ${selectedPromptConfig.filePath}. File ID: ${file.id}`
65 | );
66 | const codeInterpreterTool = ToolUtility.createCodeInterpreterTool([
67 | file.id,
68 | ]);
69 | return { codeInterpreterTool, file };
70 | }
71 | return {
72 | codeInterpreterTool: ToolUtility.createCodeInterpreterTool([]),
73 | file: null,
74 | };
75 | }
76 |
77 | export async function createAISearchTool(client: AIProjectsClient) {
78 | const aiSearchConnection = await client.connections.getConnection(
79 | aiSearchConnectionId
80 | );
81 | return ToolUtility.createAzureAISearchTool(
82 | aiSearchConnection.id,
83 | aiSearchConnection.name
84 | );
85 | }
86 |
87 | async function createBingGroundingTool(client: AIProjectsClient) {
88 | const bingConnection = await client.connections.getConnection(
89 | bingGroundingConnectionId
90 | );
91 | const connectionId = bingConnection.id;
92 | return ToolUtility.createConnectionTool(connectionToolType.BingGrounding, [
93 | connectionId,
94 | ]);
95 | }
96 |
97 | class FunctionToolFactory {
98 | static getCpuUsage() {
99 | return `CPU Usage: ${cpus()[0].model} ${Math.floor(
100 | cpus().reduce((acc, core) => acc + core.speed, 0) / 1000
101 | )}%`;
102 | }
103 | }
104 |
105 | export class FunctionToolExecutor {
106 | static functionTools: {
107 | func: Function;
108 | definition: FunctionToolDefinition;
109 | }[] = [
110 | {
111 | func: FunctionToolFactory.getCpuUsage,
112 | ...ToolUtility.createFunctionTool({
113 | name: "getCpuUsage",
114 | description: "Gets the current CPU usage of the system.",
115 | parameters: {},
116 | }),
117 | },
118 | ];
119 |
120 | public static invokeTool(
121 | toolCall: RequiredToolCallOutput & FunctionToolDefinitionOutput
122 | ): ToolOutput | undefined {
123 | console.log(`💡 Function tool ${toolCall.id} - ${toolCall.function.name}`);
124 | const args: string[] = [];
125 | if (toolCall.function.parameters) {
126 | try {
127 | const params = JSON.parse(toolCall.function.parameters) as Record<
128 | string,
129 | string
130 | >;
131 | for (const key in params) {
132 | if (Object.prototype.hasOwnProperty.call(params, key)) {
133 | args.push(params[key] as string);
134 | }
135 | }
136 | } catch (error) {
137 | console.error(
138 | `Failed to parse parameters: ${toolCall.function.parameters}`,
139 | error
140 | );
141 | return undefined;
142 | }
143 | }
144 | const result = this.functionTools
145 | .find((tool) => tool.definition.function.name === toolCall.function.name)
146 | ?.func(...args);
147 |
148 | console.log(`💡 Function tool ${toolCall.id} - completed`);
149 |
150 | return result
151 | ? {
152 | toolCallId: toolCall.id,
153 | output: JSON.stringify(result),
154 | }
155 | : undefined;
156 | }
157 |
158 | public static getFunctionDefinitions(): FunctionToolDefinition[] {
159 | return FunctionToolExecutor.functionTools.map((tool) => {
160 | return tool.definition;
161 | });
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolDefinition } from '@azure/ai-projects';
2 |
3 | export interface PromptConfig {
4 | prompt: string;
5 | instructions?: string;
6 | emoji?: string;
7 | tool?: "code-interpreter" | "function-tool" | "ai-search" | "bing-grounding";
8 | filePath?: string;
9 | fileId?: string;
10 | aiSearch?: boolean;
11 | executor?: any;
12 | tools?: ToolDefinition[];
13 | toolResources?: any;
14 | }
--------------------------------------------------------------------------------
/src/utils/console.ts:
--------------------------------------------------------------------------------
1 | import readline from 'readline';
2 | import { PromptConfig } from '../types.js';
3 | import { formatKeyToTitleCase } from './formatting.js';
4 |
5 | export function displayAvailablePrompts(promptConfig: Record) {
6 | console.log('\nAvailable prompts:');
7 | console.log('------------------');
8 | const promptKeys = Object.keys(promptConfig);
9 | promptKeys.forEach((key, index) => {
10 | const formattedKey = formatKeyToTitleCase(key);
11 | const emoji = promptConfig[key].emoji || '📝'; // Default emoji if none is specified
12 | console.log(`${index + 1}. ${emoji} ${formattedKey}: ${promptConfig[key].prompt}`);
13 | });
14 | console.log(`${promptKeys.length + 1}. 👋 Exit`);
15 | }
16 |
17 | export async function getPromptSelection(): Promise {
18 | const selection = await promptUser('\nSelect a prompt by number: ');
19 | return parseInt(selection) - 1;
20 | }
21 |
22 | export function promptUser(question: string): Promise {
23 | const rl = readline.createInterface({
24 | input: process.stdin,
25 | output: process.stdout
26 | });
27 |
28 | return new Promise((resolve) => {
29 | rl.question(question, (answer) => {
30 | rl.close();
31 | resolve(answer);
32 | });
33 | });
34 | }
--------------------------------------------------------------------------------
/src/utils/formatting.ts:
--------------------------------------------------------------------------------
1 | export function formatKeyToTitleCase(key: string): string {
2 | const withSpaces = key.replace(/([A-Z])/g, ' $1').trim().toLowerCase();
3 |
4 | return withSpaces
5 | .split(' ')
6 | .map(word => word.charAt(0).toUpperCase() + word.slice(1))
7 | .join(' ');
8 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "outDir": "./dist",
6 | "rootDir": "./src",
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "moduleResolution": "NodeNext",
11 | "incremental": true,
12 | "skipLibCheck": true,
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "allowSyntheticDefaultImports": true,
16 | "noEmitOnError": true,
17 | "useDefineForClassFields": true
18 | },
19 | "include": ["src/**/*"],
20 | "exclude": ["node_modules", "dist"]
21 | }
--------------------------------------------------------------------------------