@microsoft/m365-copilot-eval 1.0.1-preview.1 → 1.1.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,65 @@
1
- MIT License
1
+ MICROSOFT SOFTWARE LICENSE TERMS
2
+ M365 Copilot Agent Eval Tool
3
+ ________________________________________
4
+ IF YOU LIVE IN (OR ARE A BUSINESS WITH A PRINCIPAL PLACE OF BUSINESS IN) THE UNITED STATES, PLEASE READ THE “BINDING ARBITRATION AND CLASS ACTION WAIVER” SECTION BELOW. IT AFFECTS HOW DISPUTES ARE RESOLVED.
5
+ ________________________________________
6
+ These license terms are an agreement between you and Microsoft Corporation. They apply to the software named above and any Microsoft services or software updates (except to the extent such services or updates are accompanied by new or additional terms, in which case those different terms apply prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
7
+ 1. INSTALLATION AND USE RIGHTS.
8
+ a) General. You may install and use any number of copies of the software on your devices.
9
+ b) Included Microsoft Applications. The software may include other Microsoft applications. These license terms apply to those included applications, if any, unless other license terms are provided with the other Microsoft applications.
10
+ c) Work or School Accounts. You can sign into the software with a work or school email address. If you do, you agree that the owner of the domain associated with your email address may control and administer your account, and access and process your data, including the contents of your communications and files. You further agree that your use of the software may be subject to: i) your organization’s guidelines and policies regarding the use of the software; and ii) the agreements Microsoft has with you or your organization, and in such case these terms may not apply. If you already have a Microsoft account and you use a separate work or school email address to access the software, you may be prompted to update the email address associated with your Microsoft account to continue accessing the software.
11
+ d) Third Party Components. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
2
12
 
3
- Copyright (c) Microsoft Corporation.
13
+ e) Microsoft Services Agreement. Some features of the software provide access to, or rely on, online services. The use of those services (but not the software) is governed by the separate terms and privacy policies in the Microsoft Services Agreement at http://go.microsoft.com/fwlink/?linkid=398923. Please read them. The services may not be available in all regions.
4
14
 
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:
15
+ 2. TIME-SENSITIVE SOFTWARE.
16
+ a) Period. This agreement is effective on your acceptance and terminates on the earlier of (i) 30 days following first availability of a commercial release of the software or (ii) upon termination by Microsoft. Microsoft may extend this agreement in its discretion.
17
+ b) Notice. You may receive periodic reminder notices of this date through the software.
18
+ c) Access to data. You may not be able to access data used in the software when it stops running.
19
+ 3. SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to):
20
+ a) work around any technical limitations in the software that only allow you to use it in certain ways;
21
+ b) reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software;
22
+ c) remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software;
23
+ d) use the software for commercial, non-profit, or revenue-generating activities unless you have commercial use rights under a separate agreement;
24
+ e) use the software in any way that is against the law or to create or propagate malware; or
25
+ f) share, publish, distribute, or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.
26
+ 4. PRE-RELEASE SOFTWARE. The software is a pre-release version. It may not operate correctly. It may be different from the commercially released version. Customer further acknowledges that the tool is provided in preview and that Customer’s use of any preview features is governed by the Preview Terms within the Product Terms (Microsoft Azure Legal Information | Microsoft Azure, Preview Terms Of Use | Microsoft Azure), as well as the applicable preview provisions of the Data Protection Addendum (DPA)
27
+ 5. FEEDBACK. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because Microsoft includes your feedback in them. These rights survive this agreement.
28
+ 6. DATA. This software may interact with other Microsoft products that collect data that is transmitted to Microsoft. To learn more about how Microsoft processes personal data we collect, please see the Microsoft Privacy Statement at https://go.microsoft.com/fwlink/?LinkId=248681. Customer is solely responsible for determining what data is submitted for evaluation and for ensuring that such data is handled in compliance with applicable laws, internal policies, and contractual obligations.[A1.1]
29
+ 7. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit https://aka.ms/exporting.
30
+ 8. SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind.
31
+ 9. UPDATES. The software may periodically check for updates, and download and install them for you. You may obtain updates only from Microsoft or authorized sources. Microsoft may need to update your system to provide you with updates. You agree to receive these automatic updates without any additional notice. Updates may not include or support all existing software features, services, or peripheral devices.
32
+ 10. BINDING ARBITRATION AND CLASS ACTION WAIVER. This Section applies if you live in (or, if a business, your principal place of business is in) the United States. If you and Microsoft have a dispute, you and Microsoft agree to try for 60 days to resolve it informally. If you and Microsoft can’t, you and Microsoft agree to binding individual arbitration before the American Arbitration Association under the Federal Arbitration Act (“FAA”), and not to sue in court in front of a judge or jury. Instead, a neutral arbitrator will decide. Class action lawsuits, class-wide arbitrations, private attorney-general actions, and any other proceeding where someone acts in a representative capacity are not allowed; nor is combining individual proceedings without the consent of all parties. The complete Arbitration Agreement contains more terms and is at https://aka.ms/arb-agreement-4. You and Microsoft agree to these terms.
33
+ 11. TERMINATION. Without prejudice to any other rights, Microsoft may terminate this agreement if you fail to comply with any of its terms or conditions. In such event, you must destroy all copies of the software and all of its component parts.
34
+ 12. ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software.
35
+ 13. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States or Canada, the laws of the state or province where you live (or, if a business, where your principal place of business is located) govern the interpretation of this agreement, claims for its breach, and all other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of laws principles, except that the FAA governs everything related to arbitration. If you acquired the software in any other country, its laws apply, except that the FAA governs everything related to arbitration. If U.S. federal jurisdiction exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, Washington for all disputes heard in court (excluding arbitration). If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court (excluding arbitration).
36
+ 14. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state, province, or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state, province, or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
37
+ a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
38
+ b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
39
+ c) Germany and Austria.
40
+ i. Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
41
+ ii. Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
42
+ Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
11
43
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
44
+ 15. CONFIDENTIAL INFORMATION. The software, including its user interface, features and documentation, is confidential and proprietary to Microsoft and its suppliers.
45
+ c) Use. For five years after installation of the software or its commercial release, whichever is first, you may not disclose confidential information to third parties. You may disclose confidential information only to your employees and consultants who need to know the information. You must have written agreements with them that protect the confidential information at least as much as this agreement.
46
+ c) Survival. Your duty to protect confidential information survives this agreement.
47
+ c) Exclusions. You may disclose confidential information in response to a judicial or governmental order. You must first give written notice to Microsoft to allow it to seek a protective order or otherwise protect the information. Confidential information does not include information that:
48
+ 1. becomes publicly known through no wrongful act;
49
+ 2. you received from a third party who did not breach confidentiality obligations to Microsoft or its suppliers; or
50
+ 3. you developed independently.
14
51
 
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
52
+ 16. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED AS IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
53
+ 17. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
54
+ This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to the extent permitted by applicable law.
55
+ It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state, province, or country may not allow the exclusion or limitation of incidental, consequential, or other damages.
56
+
57
+ Please note: As this software is distributed in Canada, some of the clauses in this agreement are provided below in French.
58
+ Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français.
59
+ EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues.
60
+ LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
61
+ Cette limitation concerne:
62
+ • tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et
63
+ • les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.
64
+ Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre égard.
65
+ EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.
package/README.md CHANGED
@@ -25,11 +25,8 @@ A **zero-configuration** CLI for evaluating M365 Copilot agents. Send prompts to
25
25
 
26
26
  ### Install the Tool
27
27
 
28
- 1. Go to the releases → https://github.com/microsoft/M365-Copilot-Agent-Evals/releases and click on the most latest release.
29
- 2. Click on the `Source code (tar.gz)`
30
- 3. This should download the package to your device.
31
- 4. Go to the folder where this tar.gz file is. This will now be your project root folder.
32
- 5. Run `npm install -g <filename.tar.gz>` e.g., `npm install -g M365-Copilot-Agent-Evals-<version>.tar.gz`
28
+ 1. Make sure you have Node.js
29
+ 2. Run `npm install @microsoft/m365-copilot-eval`
33
30
 
34
31
  ### Setup Steps
35
32
 
@@ -105,20 +102,10 @@ Alternatively, if you have the Azure CLI installed:
105
102
  az account show --query tenantId
106
103
  ```
107
104
 
108
- ### 2. Agent ID (Only for MSIT)
105
+ ### 2. Agent ID
109
106
  - If you have created your agent using Agents Toolkit, then the agent-id is the M365_TITLE_ID in .env.local file
110
- - If you did not, then you can get your agent-id by
111
- ```
112
- 1. Open aka.ms/devui in your browser
113
- 2. Click on `Configuration`
114
- 3. In the dialog that opens, click on `Untitled Config`
115
- 4. Click on the `Payload` tab
116
- 5. If you scroll down on this tab, you will see `DA (Declarative Agent)`
117
- 6. In this dropdown, you will see all the agents that are installed for you.
118
- 7. Select the agent that you want to evaluate.
119
- 8. Copy the `gpts.id` value before .declarativeAgent.
120
- 9. This is your `agent-id`. It would look like `U_0dc4a8a2-b95f-edac-91c8-d802023ec2d4`
121
- ```
107
+ - If you don't know your agent-id, the tool offers agent selection when you try to submit a job. The agent selection has both the name, description, agent-id so that you can select the right agent.
108
+
122
109
 
123
110
  ### 3. Azure OpenAI Endpoint and API Key
124
111
 
@@ -413,3 +400,9 @@ trademarks or logos is subject to and must follow
413
400
  [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general).
414
401
  Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
415
402
  Any use of third-party trademarks or logos are subject to those third-party's policies.
403
+
404
+ ## Terms of Use
405
+
406
+ By using this tool, you agree to the [Microsoft Software License Terms](https://aka.ms/evaltoolterms).
407
+
408
+ See [LICENSE](./LICENSE) for the full license text.
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "@microsoft/m365-copilot-eval",
3
- "version": "1.0.1-preview.1",
3
+ "version": "1.1.0-preview.1",
4
4
  "description": "Zero-config Node.js wrapper for M365 Copilot Agent Evaluations CLI (Python-based Azure AI Evaluation SDK)",
5
- "publishDate": "2026-01-21",
5
+ "publishDate": "2026-02-03",
6
6
  "main": "src/clients/node-js/lib/index.js",
7
7
  "type": "module",
8
8
  "bin": {
9
9
  "runevals": "./src/clients/node-js/bin/runevals.js"
10
10
  },
11
11
  "scripts": {
12
- "postinstall": "node -e \"console.log('By installing this package, you agree to:\\n'); require('fs').readFile('./TERMS.txt', 'utf8', (err, content) => { if (!err) console.log(content); else console.error('Read about the Terms for M365 Copilot Agent Eval Tool here - aka.ms/evaltoolterms'); });\"",
13
12
  "prebuild": "node scripts/generate-defaults.js",
14
13
  "build": "npm run prettier:check && npm run clean && npm run lint",
15
14
  "clean": "rimraf node_modules/.cache dist coverage",
@@ -41,7 +40,7 @@
41
40
  "dependencies": {
42
41
  "commander": "^12.1.0",
43
42
  "node-fetch": "^3.3.2",
44
- "tar": "^7.4.3",
43
+ "tar": "^7.5.4",
45
44
  "https-proxy-agent": "^7.0.5"
46
45
  },
47
46
  "devDependencies": {
@@ -73,7 +72,7 @@
73
72
  "src/clients/cli/requirements.txt",
74
73
  "src/clients/cli/samples/",
75
74
  "README.md",
76
- "TERMS.txt"
75
+ "LICENSE"
77
76
  ],
78
77
  "repository": {
79
78
  "type": "git",
@@ -3,7 +3,7 @@ azure-ai-evaluation==1.10.0
3
3
  azure-ai-projects==1.0.0
4
4
  msal[broker]>=1.34,<2
5
5
  msal-extensions>=1.3.1
6
- pip==25.3
6
+ PyJWT>=2.11.0
7
7
  python-dotenv==1.1.1
8
8
  markdown==3.8.2
9
9
  promptflow>=1.18.1
@@ -8,7 +8,7 @@ import { ensurePythonRuntime, getCacheDir } from '../lib/python-runtime.js';
8
8
  import { ensureVenv, executePythonCli } from '../lib/venv-manager.js';
9
9
  import { getCacheStats, clearCache, formatBytes } from '../lib/cache-utils.js';
10
10
  import { checkPackageExpiry } from '../lib/expiry-check.js';
11
- import config from '../config/default.js';
11
+ import { ProgressReporter } from '../lib/progress.js';
12
12
 
13
13
  // Check package expiry (exits if expired, warns if close to expiry)
14
14
  checkPackageExpiry();
@@ -26,11 +26,22 @@ const PYTHON_CLI_DIR = path.join(__dirname, '..', '..', 'cli');
26
26
  const MAIN_SCRIPT = path.join(PYTHON_CLI_DIR, 'main.py');
27
27
  const REQUIREMENTS_FILE = path.join(PYTHON_CLI_DIR, 'requirements.txt');
28
28
 
29
+ /**
30
+ * Display usage terms notice
31
+ * Called before running evaluations (but not for --init-only, cache commands, or --signout)
32
+ * This notice MUST be displayed even in quiet mode per legal requirements (FR-006)
33
+ */
34
+ function displayUsageTerms() {
35
+ console.log('By using this tool, you agree to the Terms of Use: https://aka.ms/evaltoolterms\n');
36
+ }
37
+
29
38
  /**
30
39
  * Set default environment constants that cannot be overridden
31
40
  * This ensures these values are always set regardless of .env files
41
+ * Config is loaded lazily so --init-only works without build-time config
32
42
  */
33
- function setDefaultEnvironmentConstants() {
43
+ async function setDefaultEnvironmentConstants() {
44
+ const config = (await import('../config/default.js')).default;
34
45
  process.env.M365_EVAL_CLIENT_ID = config.copilotApi.m365EvalClientId;
35
46
  process.env.COPILOT_API_ENDPOINT = config.copilotApi.copilotApiEndpoint;
36
47
  process.env.COPILOT_SCOPES = config.copilotApi.copilotScopes;
@@ -89,7 +100,7 @@ function loadEnvFile(envFilePath) {
89
100
  /**
90
101
  * Check for required environment variables and provide helpful guidance
91
102
  */
92
- function validateEnvironmentVariables(envName, detectedVars) {
103
+ function validateEnvironmentVariables(envName, detectedVars, quiet = false) {
93
104
  const required = [
94
105
  { key: 'TENANT_ID', description: 'Your Tenant ID' },
95
106
  { key: 'AZURE_AI_OPENAI_ENDPOINT', description: 'Azure OpenAI endpoint URL' },
@@ -106,11 +117,12 @@ function validateEnvironmentVariables(envName, detectedVars) {
106
117
  return true; // All required vars present
107
118
  }
108
119
 
109
- // Show error with helpful guidance
110
- console.error('\n❌ Missing required environment variables:\n');
120
+ // Show error with helpful guidance (skip output in quiet mode, but still return false)
121
+ if (!quiet) {
122
+ console.error('\n❌ Missing required environment variables:\n');
111
123
 
112
- const envFile = envName ? `env/.env.${envName}` : '.env.local or env/env.local';
113
- console.error(`Create ${envFile} with:\n`);
124
+ const envFile = envName ? `env/.env.${envName}` : '.env.local or env/env.local';
125
+ console.error(`Create ${envFile} with:\n`);
114
126
 
115
127
  for (const req of missing) {
116
128
  console.error(` ${req.key}="<your-${req.description.toLowerCase().replace(/\s+/g, '-')}>"`);
@@ -124,8 +136,8 @@ function validateEnvironmentVariables(envName, detectedVars) {
124
136
  }
125
137
  }
126
138
 
127
- console.error(`\nThen run: npx runevals${envName ? ` --env ${envName}` : ''}\n`);
128
- console.error('📖 See README.md for complete setup guide.\n');
139
+ console.error('\n📖 Setup guide: https://www.npmjs.com/package/@microsoft/m365-copilot-eval?activeTab=readme\n');
140
+ }
129
141
 
130
142
  return false;
131
143
  }
@@ -146,29 +158,36 @@ function constructAgentId(envVars) {
146
158
 
147
159
  /**
148
160
  * Initialize the Python environment (download, venv, pip install)
161
+ * @param {boolean} [verbose=false] - Enable verbose output
162
+ * @param {boolean} [quiet=false] - Suppress progress output
149
163
  */
150
- async function initializePythonEnvironment(verbose = false) {
164
+ async function initializePythonEnvironment(verbose = false, quiet = false) {
165
+ // Create progress reporter (silent if quiet mode)
166
+ const reporter = new ProgressReporter({ verbose, quiet });
167
+ const onProgress = reporter.createCallback();
168
+
151
169
  try {
152
- // Step 1: Ensure Python runtime is available
153
- await ensurePythonRuntime(verbose);
154
-
155
- // Step 2: Ensure venv with dependencies is set up
156
- await ensureVenv(REQUIREMENTS_FILE, verbose);
157
-
170
+ // Step 1: Ensure Python runtime is available (handles download + extract phases)
171
+ await ensurePythonRuntime(verbose, onProgress);
172
+
173
+ // Step 2: Ensure venv with dependencies is set up (handles venv + deps phases)
174
+ await ensureVenv(REQUIREMENTS_FILE, verbose, onProgress);
175
+
176
+ // Show completion summary
177
+ reporter.complete();
178
+
158
179
  } catch (error) {
159
- console.error('\n❌ Failed to initialize Python environment:');
160
- console.error(error.message);
161
-
180
+ // Error is already displayed by reporter.failPhase() via callback
162
181
  if (verbose) {
163
182
  console.error('\nFull error:', error);
164
183
  }
165
-
184
+
166
185
  console.error('\nTroubleshooting:');
167
186
  console.error(' - Check your internet connection');
168
187
  console.error(' - If behind a proxy, set HTTP_PROXY/HTTPS_PROXY environment variables');
169
188
  console.error(' - For SSL issues, set NODE_EXTRA_CA_CERTS or PIP_CERT');
170
189
  console.error(' - Run with --verbose for detailed output');
171
-
190
+
172
191
  process.exit(1);
173
192
  }
174
193
  }
@@ -177,11 +196,8 @@ async function initializePythonEnvironment(verbose = false) {
177
196
  * Main CLI entry point
178
197
  */
179
198
  async function main() {
180
- // Set default environment constants.
181
- setDefaultEnvironmentConstants();
182
-
183
199
  const program = new Command();
184
-
200
+
185
201
  program
186
202
  .name('runevals')
187
203
  .description('M365 Copilot Agent Evaluations CLI - Zero-config Python evaluation tool')
@@ -200,11 +216,11 @@ async function main() {
200
216
  .option('--cache-clear', 'clear the cache (removes Python runtime and venv)')
201
217
  .option('--cache-dir', 'print the cache directory path')
202
218
  .option('--signout', 'sign out and clear cached authentication tokens');
203
-
219
+
204
220
  program.parse(process.argv);
205
221
  const options = program.opts();
206
-
207
- // Handle cache commands first (they don't need environment validation)
222
+
223
+ // Handle cache commands first (they don't need environment validation or config)
208
224
  if (options.cacheInfo) {
209
225
  console.log('🗂️ Cache Information\n');
210
226
  const stats = await getCacheStats();
@@ -245,15 +261,37 @@ async function main() {
245
261
  process.exit(0);
246
262
  }
247
263
 
248
- // Load environment file if specified
264
+ // Initialize Python environment (do this early for --init-only)
265
+ // Skip env file loading for --init-only since it's not needed
266
+ if (!options.quiet) {
267
+ console.log('🚀 M365 Copilot Agent Evaluations CLI\n');
268
+ }
269
+ await initializePythonEnvironment(options.verbose, options.quiet);
270
+
271
+ // If --init-only, stop here (no config or env files needed)
272
+ if (options.initOnly) {
273
+ if (!options.quiet) {
274
+ console.log('\n✅ Python environment initialized successfully!\n');
275
+ console.log('⚠️ Note: Configure environment variables before running evaluations.');
276
+ console.log('📖 See README.md for complete setup guide.\n');
277
+ }
278
+ return;
279
+ }
280
+
281
+ // === From here on, we're running actual evals - load config and env files ===
282
+
283
+ displayUsageTerms();
284
+ // Load build-time config
285
+ await setDefaultEnvironmentConstants();
286
+
287
+ // Load environment files
249
288
  const envVars = {};
250
289
  let resolvedAgentId = options.agentId;
251
-
290
+
252
291
  // Check for .env.local in current directory (ATK projects)
253
- // First check for .env.local directly in current directory
254
292
  let localEnvPath = path.join(process.cwd(), '.env.local');
255
293
  let localEnvFound = false;
256
-
294
+
257
295
  if (fs.existsSync(localEnvPath)) {
258
296
  if (!options.quiet && options.verbose) {
259
297
  console.log(`📂 Loading .env.local from current directory`);
@@ -262,8 +300,8 @@ async function main() {
262
300
  Object.assign(envVars, localEnvVars);
263
301
  localEnvFound = true;
264
302
  }
265
-
266
- // If not found, check for env.local in env subfolder of current directory
303
+
304
+ // If not found, check for env.local in env subfolder
267
305
  if (!localEnvFound) {
268
306
  localEnvPath = path.join(process.cwd(), 'env', 'env.local');
269
307
  if (fs.existsSync(localEnvPath)) {
@@ -275,12 +313,12 @@ async function main() {
275
313
  localEnvFound = true;
276
314
  }
277
315
  }
278
-
316
+
279
317
  if (options.env) {
280
318
  // First check current directory's env folder
281
319
  let envFilePath = path.join(process.cwd(), 'env', `.env.${options.env}`);
282
320
  let envFileFound = false;
283
-
321
+
284
322
  if (fs.existsSync(envFilePath)) {
285
323
  if (!options.quiet) {
286
324
  console.log(`📂 Loading environment: ${options.env} from current directory env folder`);
@@ -291,7 +329,7 @@ async function main() {
291
329
  } else {
292
330
  // Fallback to package's env directory
293
331
  envFilePath = path.join(__dirname, '..', 'env', `.env.${options.env}`);
294
-
332
+
295
333
  if (fs.existsSync(envFilePath)) {
296
334
  if (!options.quiet) {
297
335
  console.log(`📂 Loading environment: ${options.env} from package env folder`);
@@ -301,7 +339,7 @@ async function main() {
301
339
  envFileFound = true;
302
340
  }
303
341
  }
304
-
342
+
305
343
  if (envFileFound) {
306
344
  // Auto-construct agent ID if not explicitly provided
307
345
  if (!resolvedAgentId) {
@@ -317,7 +355,7 @@ async function main() {
317
355
  console.warn(` Continuing with system environment variables...\n`);
318
356
  }
319
357
  }
320
-
358
+
321
359
  // Auto-construct agent ID from loaded env vars if not explicitly provided
322
360
  if (!resolvedAgentId && Object.keys(envVars).length > 0) {
323
361
  resolvedAgentId = constructAgentId(envVars);
@@ -325,34 +363,23 @@ async function main() {
325
363
  console.log(`🤖 Agent ID (from M365_TITLE_ID): ${resolvedAgentId}`);
326
364
  }
327
365
  }
328
-
366
+
329
367
  // Fallback to M365_AGENT_ID env var if still not resolved
330
368
  if (!resolvedAgentId) {
331
369
  resolvedAgentId = process.env.M365_AGENT_ID;
332
370
  }
333
-
334
- // Validate required environment variables (skip for init-only and cache commands)
335
- if (!options.initOnly && !options.quiet) {
336
- if (!validateEnvironmentVariables(options.env, envVars)) {
337
- process.exit(1);
371
+
372
+ // Validate required environment variables (always validate, quiet just suppresses output)
373
+ if (!validateEnvironmentVariables(options.env, envVars, options.quiet)) {
374
+ if (options.quiet) {
375
+ console.error('📖 Setup guide: https://www.npmjs.com/package/@microsoft/m365-copilot-eval?activeTab=readme\n');
338
376
  }
377
+ process.exit(1);
339
378
  }
340
-
341
- // Initialize Python environment
342
- console.log('🚀 M365 Copilot Agent Evaluations CLI\n');
343
- await initializePythonEnvironment(options.verbose);
344
-
345
- // If --init-only, stop here
346
- if (options.initOnly) {
347
- console.log('\n✅ Python environment initialized successfully!\n');
348
- console.log('⚠️ Note: Configure environment variables before running evaluations.');
349
- console.log('📖 See README.md for complete setup guide.\n');
350
- return;
351
- }
352
-
379
+
353
380
  // Build arguments to pass to Python CLI
354
381
  const pythonArgs = [];
355
-
382
+
356
383
  if (options.verbose) pythonArgs.push('--verbose');
357
384
  if (options.quiet) pythonArgs.push('--quiet');
358
385
  if (options.interactive) pythonArgs.push('--interactive');
@@ -2,7 +2,7 @@
2
2
  * Build-time injected default values
3
3
  * DO NOT EDIT - This file is auto-generated during build.
4
4
  *
5
- * Generated: 2026-01-21T21:10:04.863Z
5
+ * Generated: 2026-02-03T22:27:55.106Z
6
6
  *
7
7
  * @copyright Microsoft Corporation. All rights reserved.
8
8
  * @license MIT