@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 +61 -17
- package/README.md +11 -18
- package/package.json +4 -5
- package/src/clients/cli/requirements.txt +1 -1
- package/src/clients/node-js/bin/runevals.js +86 -59
- package/src/clients/node-js/config/default.js +1 -1
- package/src/clients/node-js/lib/progress.js +677 -0
- package/src/clients/node-js/lib/python-runtime.js +93 -19
- package/src/clients/node-js/lib/venv-manager.js +155 -17
- package/TERMS.txt +0 -65
|
@@ -4,6 +4,7 @@ import fs from 'fs/promises';
|
|
|
4
4
|
import crypto from 'crypto';
|
|
5
5
|
import { pipeline } from 'stream/promises';
|
|
6
6
|
import { createWriteStream } from 'fs';
|
|
7
|
+
import { Transform } from 'stream';
|
|
7
8
|
import fetch from 'node-fetch';
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -111,9 +112,15 @@ async function calculateFileHash(filePath) {
|
|
|
111
112
|
|
|
112
113
|
/**
|
|
113
114
|
* Download a file with progress indication
|
|
115
|
+
* @param {string} url - URL to download from
|
|
116
|
+
* @param {string} destPath - Destination file path
|
|
117
|
+
* @param {string} expectedHash - Expected SHA256 hash
|
|
118
|
+
* @param {Function} [onProgress] - Optional progress callback
|
|
114
119
|
*/
|
|
115
|
-
async function downloadFile(url, destPath, expectedHash) {
|
|
116
|
-
|
|
120
|
+
async function downloadFile(url, destPath, expectedHash, onProgress) {
|
|
121
|
+
if (!onProgress) {
|
|
122
|
+
console.log(`Downloading: ${url}`);
|
|
123
|
+
}
|
|
117
124
|
|
|
118
125
|
// Support proxy configuration
|
|
119
126
|
const fetchOptions = {};
|
|
@@ -134,12 +141,34 @@ async function downloadFile(url, destPath, expectedHash) {
|
|
|
134
141
|
// Create parent directory if needed
|
|
135
142
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
136
143
|
|
|
137
|
-
//
|
|
144
|
+
// Get total size from Content-Length header
|
|
145
|
+
const totalBytes = parseInt(response.headers.get('content-length'), 10) || 0;
|
|
146
|
+
let downloadedBytes = 0;
|
|
147
|
+
|
|
148
|
+
// Create transform stream to track progress
|
|
149
|
+
const progressStream = new Transform({
|
|
150
|
+
transform(chunk, encoding, callback) {
|
|
151
|
+
downloadedBytes += chunk.length;
|
|
152
|
+
if (onProgress && totalBytes > 0) {
|
|
153
|
+
onProgress({
|
|
154
|
+
type: 'progress',
|
|
155
|
+
phaseId: 'download',
|
|
156
|
+
current: downloadedBytes,
|
|
157
|
+
total: totalBytes,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
callback(null, chunk);
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Stream to file with progress tracking
|
|
138
165
|
const fileStream = createWriteStream(destPath);
|
|
139
|
-
await pipeline(response.body, fileStream);
|
|
166
|
+
await pipeline(response.body, progressStream, fileStream);
|
|
140
167
|
|
|
141
168
|
// Verify checksum
|
|
142
|
-
|
|
169
|
+
if (!onProgress) {
|
|
170
|
+
console.log('Verifying checksum...');
|
|
171
|
+
}
|
|
143
172
|
const actualHash = await calculateFileHash(destPath);
|
|
144
173
|
|
|
145
174
|
if (actualHash !== expectedHash) {
|
|
@@ -152,16 +181,23 @@ async function downloadFile(url, destPath, expectedHash) {
|
|
|
152
181
|
);
|
|
153
182
|
}
|
|
154
183
|
|
|
155
|
-
|
|
184
|
+
if (!onProgress) {
|
|
185
|
+
console.log('Checksum verified ✓');
|
|
186
|
+
}
|
|
156
187
|
}
|
|
157
188
|
|
|
158
189
|
/**
|
|
159
190
|
* Extract tar.gz archive
|
|
191
|
+
* @param {string} archivePath - Path to archive file
|
|
192
|
+
* @param {string} destDir - Destination directory
|
|
193
|
+
* @param {Function} [onProgress] - Optional progress callback
|
|
160
194
|
*/
|
|
161
|
-
async function extractTarGz(archivePath, destDir) {
|
|
195
|
+
async function extractTarGz(archivePath, destDir, onProgress) {
|
|
162
196
|
const tar = await import('tar');
|
|
163
197
|
|
|
164
|
-
|
|
198
|
+
if (!onProgress) {
|
|
199
|
+
console.log(`Extracting to: ${destDir}`);
|
|
200
|
+
}
|
|
165
201
|
await fs.mkdir(destDir, { recursive: true });
|
|
166
202
|
|
|
167
203
|
await tar.extract({
|
|
@@ -170,14 +206,18 @@ async function extractTarGz(archivePath, destDir) {
|
|
|
170
206
|
strip: 1, // Remove the top-level directory from archive
|
|
171
207
|
});
|
|
172
208
|
|
|
173
|
-
|
|
209
|
+
if (!onProgress) {
|
|
210
|
+
console.log('Extraction complete ✓');
|
|
211
|
+
}
|
|
174
212
|
}
|
|
175
213
|
|
|
176
214
|
/**
|
|
177
215
|
* Download and setup Python Build Standalone runtime
|
|
178
216
|
* Returns the path to the Python executable
|
|
217
|
+
* @param {boolean} [verbose=false] - Enable verbose output
|
|
218
|
+
* @param {Function} [onProgress] - Optional progress callback
|
|
179
219
|
*/
|
|
180
|
-
export async function ensurePythonRuntime(verbose = false) {
|
|
220
|
+
export async function ensurePythonRuntime(verbose = false, onProgress) {
|
|
181
221
|
const platformKey = getPlatformKey();
|
|
182
222
|
const distribution = PBS_DISTRIBUTIONS[platformKey];
|
|
183
223
|
|
|
@@ -197,39 +237,73 @@ export async function ensurePythonRuntime(verbose = false) {
|
|
|
197
237
|
pythonExe = path.join(pythonDir, 'bin', 'python3');
|
|
198
238
|
}
|
|
199
239
|
|
|
200
|
-
// Check if Python is already installed
|
|
240
|
+
// Check if Python is already installed (silent skip per FR-007)
|
|
201
241
|
try {
|
|
202
242
|
await fs.access(pythonExe);
|
|
203
243
|
if (verbose) {
|
|
204
244
|
console.log(`Using cached Python runtime: ${pythonExe}`);
|
|
205
245
|
}
|
|
246
|
+
// Skip both download and extract phases silently
|
|
247
|
+
onProgress?.({ type: 'skip', phaseId: 'download' });
|
|
248
|
+
onProgress?.({ type: 'skip', phaseId: 'extract' });
|
|
206
249
|
return pythonExe;
|
|
207
250
|
} catch {
|
|
208
251
|
// Python not found, proceed with download and extraction
|
|
209
252
|
}
|
|
210
253
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
254
|
+
if (!onProgress) {
|
|
255
|
+
console.log(
|
|
256
|
+
`Setting up Python ${PYTHON_VERSION} runtime for ${platformKey}...`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
214
259
|
|
|
215
260
|
// Download if not cached
|
|
261
|
+
let needsDownload = false;
|
|
216
262
|
try {
|
|
217
263
|
await fs.access(archivePath);
|
|
218
264
|
if (verbose) {
|
|
219
265
|
console.log('Using cached download');
|
|
220
266
|
}
|
|
267
|
+
// Skip download phase silently
|
|
268
|
+
onProgress?.({ type: 'skip', phaseId: 'download' });
|
|
221
269
|
} catch {
|
|
222
|
-
|
|
223
|
-
|
|
270
|
+
needsDownload = true;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (needsDownload) {
|
|
274
|
+
// Start download phase
|
|
275
|
+
onProgress?.({ type: 'start', phaseId: 'download' });
|
|
276
|
+
try {
|
|
277
|
+
const downloadUrl = `${PBS_BASE_URL}/${distribution.filename}`;
|
|
278
|
+
await downloadFile(
|
|
279
|
+
downloadUrl,
|
|
280
|
+
archivePath,
|
|
281
|
+
distribution.sha256,
|
|
282
|
+
onProgress
|
|
283
|
+
);
|
|
284
|
+
onProgress?.({ type: 'complete', phaseId: 'download' });
|
|
285
|
+
} catch (error) {
|
|
286
|
+
onProgress?.({ type: 'error', phaseId: 'download', error });
|
|
287
|
+
throw error;
|
|
288
|
+
}
|
|
224
289
|
}
|
|
225
290
|
|
|
226
|
-
// Extract
|
|
227
|
-
|
|
291
|
+
// Extract phase
|
|
292
|
+
onProgress?.({ type: 'start', phaseId: 'extract' });
|
|
293
|
+
try {
|
|
294
|
+
await extractTarGz(archivePath, pythonDir, onProgress);
|
|
295
|
+
onProgress?.({ type: 'complete', phaseId: 'extract' });
|
|
296
|
+
} catch (error) {
|
|
297
|
+
onProgress?.({ type: 'error', phaseId: 'extract', error });
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
228
300
|
|
|
229
301
|
// Verify Python executable exists
|
|
230
302
|
await fs.access(pythonExe);
|
|
231
303
|
|
|
232
|
-
|
|
304
|
+
if (!onProgress) {
|
|
305
|
+
console.log(`Python runtime ready: ${pythonExe}`);
|
|
306
|
+
}
|
|
233
307
|
return pythonExe;
|
|
234
308
|
}
|
|
235
309
|
|
|
@@ -6,12 +6,25 @@ import { getPythonExecutable, getCacheDir } from './python-runtime.js';
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Execute a command and return stdout
|
|
9
|
+
* @param {string} command - Command to execute
|
|
10
|
+
* @param {string[]} args - Command arguments
|
|
11
|
+
* @param {Object} options - Execution options
|
|
12
|
+
* @param {boolean} [options.verbose] - Enable verbose output
|
|
13
|
+
* @param {Function} [options.onStdout] - Callback for stdout data
|
|
9
14
|
*/
|
|
10
15
|
function execCommand(command, args, options = {}) {
|
|
11
16
|
return new Promise((resolve, reject) => {
|
|
12
|
-
|
|
17
|
+
// On Windows, we need shell for proper .exe execution, but passing args
|
|
18
|
+
// separately with shell:true triggers DEP0190. Join into single command.
|
|
19
|
+
const isWindows = process.platform === 'win32';
|
|
20
|
+
const spawnArgs = isWindows ? [] : args;
|
|
21
|
+
const spawnCommand = isWindows
|
|
22
|
+
? `"${command}" ${args.map((a) => `"${a}"`).join(' ')}`
|
|
23
|
+
: command;
|
|
24
|
+
|
|
25
|
+
const proc = spawn(spawnCommand, spawnArgs, {
|
|
13
26
|
...options,
|
|
14
|
-
shell:
|
|
27
|
+
shell: isWindows,
|
|
15
28
|
});
|
|
16
29
|
|
|
17
30
|
let stdout = '';
|
|
@@ -23,6 +36,10 @@ function execCommand(command, args, options = {}) {
|
|
|
23
36
|
if (options.verbose) {
|
|
24
37
|
process.stdout.write(data);
|
|
25
38
|
}
|
|
39
|
+
// Call onStdout callback if provided (for progress tracking)
|
|
40
|
+
if (options.onStdout) {
|
|
41
|
+
options.onStdout(data.toString());
|
|
42
|
+
}
|
|
26
43
|
});
|
|
27
44
|
}
|
|
28
45
|
|
|
@@ -91,9 +108,13 @@ function getVenvPip(venvDir) {
|
|
|
91
108
|
|
|
92
109
|
/**
|
|
93
110
|
* Create a virtual environment
|
|
111
|
+
* @param {string} pythonExe - Path to Python executable
|
|
112
|
+
* @param {string} venvDir - Path to venv directory
|
|
113
|
+
* @param {boolean} [verbose=false] - Enable verbose output
|
|
114
|
+
* @param {Function} [onProgress] - Optional progress callback
|
|
94
115
|
*/
|
|
95
|
-
async function createVenv(pythonExe, venvDir, verbose = false) {
|
|
96
|
-
if (verbose) {
|
|
116
|
+
async function createVenv(pythonExe, venvDir, verbose = false, onProgress) {
|
|
117
|
+
if (verbose && !onProgress) {
|
|
97
118
|
console.log(`Creating virtual environment at: ${venvDir}`);
|
|
98
119
|
}
|
|
99
120
|
|
|
@@ -101,18 +122,29 @@ async function createVenv(pythonExe, venvDir, verbose = false) {
|
|
|
101
122
|
|
|
102
123
|
await execCommand(pythonExe, ['-m', 'venv', venvDir], { verbose });
|
|
103
124
|
|
|
104
|
-
if (verbose) {
|
|
125
|
+
if (verbose && !onProgress) {
|
|
105
126
|
console.log('Virtual environment created ✓');
|
|
106
127
|
}
|
|
107
128
|
}
|
|
108
129
|
|
|
109
130
|
/**
|
|
110
131
|
* Install packages from requirements.txt into venv
|
|
132
|
+
* @param {string} venvDir - Path to venv directory
|
|
133
|
+
* @param {string} requirementsPath - Path to requirements.txt
|
|
134
|
+
* @param {boolean} [verbose=false] - Enable verbose output
|
|
135
|
+
* @param {Function} [onProgress] - Optional progress callback
|
|
111
136
|
*/
|
|
112
|
-
async function installRequirements(
|
|
137
|
+
async function installRequirements(
|
|
138
|
+
venvDir,
|
|
139
|
+
requirementsPath,
|
|
140
|
+
verbose = false,
|
|
141
|
+
onProgress
|
|
142
|
+
) {
|
|
113
143
|
const pipExe = getVenvPip(venvDir);
|
|
114
144
|
|
|
115
|
-
|
|
145
|
+
if (!onProgress) {
|
|
146
|
+
console.log('Installing Python dependencies...');
|
|
147
|
+
}
|
|
116
148
|
if (verbose) {
|
|
117
149
|
console.log(`Using pip: ${pipExe}`);
|
|
118
150
|
console.log(`Requirements: ${requirementsPath}`);
|
|
@@ -121,6 +153,12 @@ async function installRequirements(venvDir, requirementsPath, verbose = false) {
|
|
|
121
153
|
// Upgrade pip first
|
|
122
154
|
await execCommand(pipExe, ['install', '--upgrade', 'pip'], { verbose });
|
|
123
155
|
|
|
156
|
+
// Track progress through pip's phases: Collecting -> Downloading/Cached -> Installing
|
|
157
|
+
let collectingCount = 0;
|
|
158
|
+
let downloadingCount = 0;
|
|
159
|
+
let cachedCount = 0;
|
|
160
|
+
let pipPhase = 'collecting'; // 'collecting', 'resolving', 'downloading', 'installing'
|
|
161
|
+
|
|
124
162
|
// Install requirements with hash checking if available
|
|
125
163
|
const args = ['install', '-r', requirementsPath];
|
|
126
164
|
|
|
@@ -133,9 +171,81 @@ async function installRequirements(venvDir, requirementsPath, verbose = false) {
|
|
|
133
171
|
args.push('--trusted-host', process.env.PIP_TRUSTED_HOST);
|
|
134
172
|
}
|
|
135
173
|
|
|
136
|
-
|
|
174
|
+
// Track progress by parsing pip output through all phases
|
|
175
|
+
const onStdout = onProgress
|
|
176
|
+
? (output) => {
|
|
177
|
+
const line = output.trim();
|
|
178
|
+
|
|
179
|
+
// Phase 1: Collecting (dependency resolution)
|
|
180
|
+
if (line.includes('Collecting ')) {
|
|
181
|
+
collectingCount++;
|
|
182
|
+
pipPhase = 'collecting';
|
|
183
|
+
onProgress({
|
|
184
|
+
type: 'progress',
|
|
185
|
+
phaseId: 'deps',
|
|
186
|
+
current: collectingCount,
|
|
187
|
+
status: 'collecting',
|
|
188
|
+
message: line,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
// Using cached packages (can happen during collecting or after)
|
|
192
|
+
else if (line.includes('Using cached ')) {
|
|
193
|
+
cachedCount++;
|
|
194
|
+
onProgress({
|
|
195
|
+
type: 'progress',
|
|
196
|
+
phaseId: 'deps',
|
|
197
|
+
current: cachedCount,
|
|
198
|
+
status: 'cached',
|
|
199
|
+
message: line,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// Phase 2: Downloading packages
|
|
203
|
+
else if (line.includes('Downloading ')) {
|
|
204
|
+
if (pipPhase !== 'downloading') {
|
|
205
|
+
pipPhase = 'downloading';
|
|
206
|
+
downloadingCount = 0;
|
|
207
|
+
}
|
|
208
|
+
downloadingCount++;
|
|
209
|
+
onProgress({
|
|
210
|
+
type: 'progress',
|
|
211
|
+
phaseId: 'deps',
|
|
212
|
+
current: downloadingCount,
|
|
213
|
+
total: collectingCount, // Now we know the total from collecting phase
|
|
214
|
+
status: 'downloading',
|
|
215
|
+
message: line,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
// Phase 3: Installing packages
|
|
219
|
+
else if (line.includes('Installing collected packages')) {
|
|
220
|
+
pipPhase = 'installing';
|
|
221
|
+
onProgress({
|
|
222
|
+
type: 'progress',
|
|
223
|
+
phaseId: 'deps',
|
|
224
|
+
current: 0,
|
|
225
|
+
total: collectingCount,
|
|
226
|
+
status: 'installing',
|
|
227
|
+
message: 'Installing packages...',
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// Track successful completion
|
|
231
|
+
else if (line.includes('Successfully installed')) {
|
|
232
|
+
onProgress({
|
|
233
|
+
type: 'progress',
|
|
234
|
+
phaseId: 'deps',
|
|
235
|
+
current: collectingCount,
|
|
236
|
+
total: collectingCount,
|
|
237
|
+
status: 'done',
|
|
238
|
+
message: line,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
: undefined;
|
|
243
|
+
|
|
244
|
+
await execCommand(pipExe, args, { verbose, onStdout });
|
|
137
245
|
|
|
138
|
-
|
|
246
|
+
if (!onProgress) {
|
|
247
|
+
console.log('Dependencies installed ✓');
|
|
248
|
+
}
|
|
139
249
|
}
|
|
140
250
|
|
|
141
251
|
/**
|
|
@@ -171,21 +281,33 @@ async function writeRequirementsMarker(venvDir, requirementsHash) {
|
|
|
171
281
|
/**
|
|
172
282
|
* Ensure virtual environment is set up with all dependencies
|
|
173
283
|
* Returns the path to the venv Python executable
|
|
284
|
+
* @param {string} requirementsPath - Path to requirements.txt
|
|
285
|
+
* @param {boolean} [verbose=false] - Enable verbose output
|
|
286
|
+
* @param {Function} [onProgress] - Optional progress callback
|
|
174
287
|
*/
|
|
175
|
-
export async function ensureVenv(
|
|
288
|
+
export async function ensureVenv(
|
|
289
|
+
requirementsPath,
|
|
290
|
+
verbose = false,
|
|
291
|
+
onProgress
|
|
292
|
+
) {
|
|
176
293
|
const pythonExe = await getPythonExecutable();
|
|
177
294
|
const venvDir = getVenvDir();
|
|
178
295
|
const requirementsHash = await getRequirementsHash(requirementsPath);
|
|
179
296
|
|
|
180
|
-
// Check if venv is already set up and valid
|
|
297
|
+
// Check if venv is already set up and valid (silent skip per FR-007)
|
|
181
298
|
if (await isVenvValid(venvDir, requirementsHash)) {
|
|
182
299
|
if (verbose) {
|
|
183
300
|
console.log('Using existing virtual environment');
|
|
184
301
|
}
|
|
302
|
+
// Skip both venv and deps phases silently
|
|
303
|
+
onProgress?.({ type: 'skip', phaseId: 'venv' });
|
|
304
|
+
onProgress?.({ type: 'skip', phaseId: 'deps' });
|
|
185
305
|
return getVenvPython(venvDir);
|
|
186
306
|
}
|
|
187
307
|
|
|
188
|
-
|
|
308
|
+
if (!onProgress) {
|
|
309
|
+
console.log('Setting up Python virtual environment...');
|
|
310
|
+
}
|
|
189
311
|
|
|
190
312
|
// Remove old venv if it exists but is invalid
|
|
191
313
|
try {
|
|
@@ -194,16 +316,32 @@ export async function ensureVenv(requirementsPath, verbose = false) {
|
|
|
194
316
|
// Ignore errors during cleanup
|
|
195
317
|
}
|
|
196
318
|
|
|
197
|
-
// Create new venv
|
|
198
|
-
|
|
319
|
+
// Create new venv phase
|
|
320
|
+
onProgress?.({ type: 'start', phaseId: 'venv' });
|
|
321
|
+
try {
|
|
322
|
+
await createVenv(pythonExe, venvDir, verbose, onProgress);
|
|
323
|
+
onProgress?.({ type: 'complete', phaseId: 'venv' });
|
|
324
|
+
} catch (error) {
|
|
325
|
+
onProgress?.({ type: 'error', phaseId: 'venv', error });
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
199
328
|
|
|
200
|
-
// Install
|
|
201
|
-
|
|
329
|
+
// Install dependencies phase
|
|
330
|
+
onProgress?.({ type: 'start', phaseId: 'deps' });
|
|
331
|
+
try {
|
|
332
|
+
await installRequirements(venvDir, requirementsPath, verbose, onProgress);
|
|
333
|
+
onProgress?.({ type: 'complete', phaseId: 'deps' });
|
|
334
|
+
} catch (error) {
|
|
335
|
+
onProgress?.({ type: 'error', phaseId: 'deps', error });
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
202
338
|
|
|
203
339
|
// Mark as complete
|
|
204
340
|
await writeRequirementsMarker(venvDir, requirementsHash);
|
|
205
341
|
|
|
206
|
-
|
|
342
|
+
if (!onProgress) {
|
|
343
|
+
console.log('Virtual environment ready ✓');
|
|
344
|
+
}
|
|
207
345
|
return getVenvPython(venvDir);
|
|
208
346
|
}
|
|
209
347
|
|
package/TERMS.txt
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
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.
|
|
12
|
-
|
|
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.
|
|
14
|
-
|
|
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.
|
|
43
|
-
|
|
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.
|
|
51
|
-
|
|
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.
|