@salesforce/plugin-agent 1.14.2 → 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/lib/handleTestResults.d.ts +3 -0
- package/lib/handleTestResults.js +117 -2
- package/lib/handleTestResults.js.map +1 -1
- package/npm-shrinkwrap.json +205 -542
- package/oclif.lock +32 -69
- package/oclif.manifest.json +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -133,7 +133,7 @@ EXAMPLES
|
|
|
133
133
|
$ sf agent create --agent-name "Resort Manager" --spec specs/resortManagerAgent.yaml --preview
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
_See code: [src/commands/agent/create.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
136
|
+
_See code: [src/commands/agent/create.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/create.ts)_
|
|
137
137
|
|
|
138
138
|
## `sf agent generate agent-spec`
|
|
139
139
|
|
|
@@ -237,7 +237,7 @@ EXAMPLES
|
|
|
237
237
|
$ sf agent generate agent-spec --tone formal --agent-user resortmanager@myorg.com
|
|
238
238
|
```
|
|
239
239
|
|
|
240
|
-
_See code: [src/commands/agent/generate/agent-spec.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
240
|
+
_See code: [src/commands/agent/generate/agent-spec.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/generate/agent-spec.ts)_
|
|
241
241
|
|
|
242
242
|
## `sf agent generate template`
|
|
243
243
|
|
|
@@ -270,7 +270,7 @@ EXAMPLES
|
|
|
270
270
|
$ sf agent generate template --agent-api-name My_Packaged_Agent
|
|
271
271
|
```
|
|
272
272
|
|
|
273
|
-
_See code: [src/commands/agent/generate/template.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
273
|
+
_See code: [src/commands/agent/generate/template.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/generate/template.ts)_
|
|
274
274
|
|
|
275
275
|
## `sf agent generate test-spec`
|
|
276
276
|
|
|
@@ -293,7 +293,7 @@ EXAMPLES
|
|
|
293
293
|
$ sf agent generate test-spec
|
|
294
294
|
```
|
|
295
295
|
|
|
296
|
-
_See code: [src/commands/agent/generate/test-spec.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
296
|
+
_See code: [src/commands/agent/generate/test-spec.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/generate/test-spec.ts)_
|
|
297
297
|
|
|
298
298
|
## `sf agent preview`
|
|
299
299
|
|
|
@@ -328,7 +328,7 @@ FLAG DESCRIPTIONS
|
|
|
328
328
|
the API name of the agent? (TBD based on agents library)
|
|
329
329
|
```
|
|
330
330
|
|
|
331
|
-
_See code: [src/commands/agent/preview.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
331
|
+
_See code: [src/commands/agent/preview.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/preview.ts)_
|
|
332
332
|
|
|
333
333
|
## `sf agent test cancel`
|
|
334
334
|
|
|
@@ -365,7 +365,7 @@ EXAMPLES
|
|
|
365
365
|
$ sf agent test cancel --job-id 4KBfake0000003F4AQ --target-org my-org
|
|
366
366
|
```
|
|
367
367
|
|
|
368
|
-
_See code: [src/commands/agent/test/cancel.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
368
|
+
_See code: [src/commands/agent/test/cancel.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/test/cancel.ts)_
|
|
369
369
|
|
|
370
370
|
## `sf agent test create`
|
|
371
371
|
|
|
@@ -401,7 +401,7 @@ FLAG DESCRIPTIONS
|
|
|
401
401
|
More information about a flag. Don't repeat the summary.
|
|
402
402
|
```
|
|
403
403
|
|
|
404
|
-
_See code: [src/commands/agent/test/create.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
404
|
+
_See code: [src/commands/agent/test/create.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/test/create.ts)_
|
|
405
405
|
|
|
406
406
|
## `sf agent test list`
|
|
407
407
|
|
|
@@ -430,7 +430,7 @@ EXAMPLES
|
|
|
430
430
|
$ sf agent test list
|
|
431
431
|
```
|
|
432
432
|
|
|
433
|
-
_See code: [src/commands/agent/test/list.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
433
|
+
_See code: [src/commands/agent/test/list.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/test/list.ts)_
|
|
434
434
|
|
|
435
435
|
## `sf agent test results`
|
|
436
436
|
|
|
@@ -486,7 +486,7 @@ FLAG DESCRIPTIONS
|
|
|
486
486
|
test results aren't written.
|
|
487
487
|
```
|
|
488
488
|
|
|
489
|
-
_See code: [src/commands/agent/test/results.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
489
|
+
_See code: [src/commands/agent/test/results.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/test/results.ts)_
|
|
490
490
|
|
|
491
491
|
## `sf agent test resume`
|
|
492
492
|
|
|
@@ -549,7 +549,7 @@ FLAG DESCRIPTIONS
|
|
|
549
549
|
test results aren't written.
|
|
550
550
|
```
|
|
551
551
|
|
|
552
|
-
_See code: [src/commands/agent/test/resume.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
552
|
+
_See code: [src/commands/agent/test/resume.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/test/resume.ts)_
|
|
553
553
|
|
|
554
554
|
## `sf agent test run`
|
|
555
555
|
|
|
@@ -612,6 +612,6 @@ FLAG DESCRIPTIONS
|
|
|
612
612
|
test results aren't written.
|
|
613
613
|
```
|
|
614
614
|
|
|
615
|
-
_See code: [src/commands/agent/test/run.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.
|
|
615
|
+
_See code: [src/commands/agent/test/run.ts](https://github.com/salesforcecli/plugin-agent/blob/1.14.3/src/commands/agent/test/run.ts)_
|
|
616
616
|
|
|
617
617
|
<!-- commandsstop -->
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { AgentTestResultsResponse } from '@salesforce/agents';
|
|
2
|
+
export declare function truncate(value: number, decimals?: number): string;
|
|
3
|
+
export declare function readableTime(time: number, decimalPlaces?: number): string;
|
|
4
|
+
export declare function humanFormat(results: AgentTestResultsResponse): string;
|
|
2
5
|
export declare function handleTestResults({ id, format, results, jsonEnabled, outputDir, }: {
|
|
3
6
|
id: string;
|
|
4
7
|
format: 'human' | 'json' | 'junit' | 'tap';
|
package/lib/handleTestResults.js
CHANGED
|
@@ -6,13 +6,128 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { writeFile, mkdir } from 'node:fs/promises';
|
|
9
|
-
import { convertTestResultsToFormat } from '@salesforce/agents';
|
|
9
|
+
import { convertTestResultsToFormat, humanFriendlyName } from '@salesforce/agents';
|
|
10
10
|
import { Ux } from '@salesforce/sf-plugins-core/Ux';
|
|
11
|
+
import ansis from 'ansis';
|
|
11
12
|
async function writeFileToDir(outputDir, fileName, content) {
|
|
12
13
|
// if directory doesn't exist, create it
|
|
13
14
|
await mkdir(outputDir, { recursive: true });
|
|
14
15
|
await writeFile(join(outputDir, fileName), content);
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Clean a string by replacing HTML entities with their respective characters. Implementation done by copilot.
|
|
19
|
+
*
|
|
20
|
+
* This is only required until W-17594913 is resolved by SF Eval
|
|
21
|
+
*
|
|
22
|
+
* @param str - The string to clean.
|
|
23
|
+
* @returns The cleaned string with all HTML entities replaced with their respective characters.
|
|
24
|
+
*/
|
|
25
|
+
function decodeHtmlEntities(str) {
|
|
26
|
+
const entities = {
|
|
27
|
+
'"': '"',
|
|
28
|
+
''': "'",
|
|
29
|
+
'&': '&',
|
|
30
|
+
'<': '<',
|
|
31
|
+
'>': '>',
|
|
32
|
+
''': "'",
|
|
33
|
+
};
|
|
34
|
+
return str.replace(/&[a-zA-Z0-9#]+;/g, (entity) => entities[entity] || entity);
|
|
35
|
+
}
|
|
36
|
+
function makeSimpleTable(data, title) {
|
|
37
|
+
if (Object.keys(data).length === 0) {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
const longestKey = Object.keys(data).reduce((acc, key) => (key.length > acc ? key.length : acc), 0);
|
|
41
|
+
const longestValue = Object.values(data).reduce((acc, value) => (value.length > acc ? value.length : acc), 0);
|
|
42
|
+
const table = Object.entries(data)
|
|
43
|
+
.map(([key, value]) => `${key.padEnd(longestKey)} ${value.padEnd(longestValue)}`)
|
|
44
|
+
.join('\n');
|
|
45
|
+
return `${title}\n${table}`;
|
|
46
|
+
}
|
|
47
|
+
export function truncate(value, decimals = 2) {
|
|
48
|
+
const remainder = value % 1;
|
|
49
|
+
// truncate remainder to specified decimals
|
|
50
|
+
const fractionalPart = remainder ? remainder.toString().split('.')[1].slice(0, decimals) : '0'.repeat(decimals);
|
|
51
|
+
const wholeNumberPart = Math.floor(value).toString();
|
|
52
|
+
return decimals ? `${wholeNumberPart}.${fractionalPart}` : wholeNumberPart;
|
|
53
|
+
}
|
|
54
|
+
export function readableTime(time, decimalPlaces = 2) {
|
|
55
|
+
if (time < 1000) {
|
|
56
|
+
return '< 1s';
|
|
57
|
+
}
|
|
58
|
+
// if time < 1000ms, return time in ms
|
|
59
|
+
if (time < 1000) {
|
|
60
|
+
return `${time}ms`;
|
|
61
|
+
}
|
|
62
|
+
// if time < 60s, return time in seconds
|
|
63
|
+
if (time < 60_000) {
|
|
64
|
+
return `${truncate(time / 1000, decimalPlaces)}s`;
|
|
65
|
+
}
|
|
66
|
+
// if time < 60m, return time in minutes and seconds
|
|
67
|
+
if (time < 3_600_000) {
|
|
68
|
+
const minutes = Math.floor(time / 60_000);
|
|
69
|
+
const seconds = truncate((time % 60_000) / 1000, decimalPlaces);
|
|
70
|
+
return `${minutes}m ${seconds}s`;
|
|
71
|
+
}
|
|
72
|
+
// if time >= 60m, return time in hours and minutes
|
|
73
|
+
const hours = Math.floor(time / 3_600_000);
|
|
74
|
+
const minutes = Math.floor((time % 3_600_000) / 60_000);
|
|
75
|
+
return `${hours}h ${minutes}m`;
|
|
76
|
+
}
|
|
77
|
+
export function humanFormat(results) {
|
|
78
|
+
const ux = new Ux();
|
|
79
|
+
const tables = [];
|
|
80
|
+
for (const testCase of results.testCases) {
|
|
81
|
+
const table = ux.makeTable({
|
|
82
|
+
title: `${ansis.bold(`Test Case #${testCase.testNumber}`)}\n${ansis.dim('Utterance')}: ${testCase.inputs.utterance}`,
|
|
83
|
+
overflow: 'wrap',
|
|
84
|
+
columns: ['test', 'result', { key: 'expected', width: '40%' }, { key: 'actual', width: '40%' }],
|
|
85
|
+
data: testCase.testResults.map((r) => ({
|
|
86
|
+
test: humanFriendlyName(r.name),
|
|
87
|
+
result: r.result === 'PASS' ? ansis.green('Pass') : ansis.red('Fail'),
|
|
88
|
+
expected: decodeHtmlEntities(r.expectedValue),
|
|
89
|
+
actual: decodeHtmlEntities(r.actualValue),
|
|
90
|
+
})),
|
|
91
|
+
width: '100%',
|
|
92
|
+
});
|
|
93
|
+
tables.push(table);
|
|
94
|
+
}
|
|
95
|
+
const topicPassCount = results.testCases.reduce((acc, tc) => {
|
|
96
|
+
const topic = tc.testResults.find((r) => r.name === 'topic_sequence_match');
|
|
97
|
+
return topic?.result === 'PASS' ? acc + 1 : acc;
|
|
98
|
+
}, 0);
|
|
99
|
+
const topicPassPercent = (topicPassCount / results.testCases.length) * 100;
|
|
100
|
+
const actionPassCount = results.testCases.reduce((acc, tc) => {
|
|
101
|
+
const action = tc.testResults.find((r) => r.name === 'action_sequence_match');
|
|
102
|
+
return action?.result === 'PASS' ? acc + 1 : acc;
|
|
103
|
+
}, 0);
|
|
104
|
+
const actionPassPercent = (actionPassCount / results.testCases.length) * 100;
|
|
105
|
+
const outcomePassCount = results.testCases.reduce((acc, tc) => {
|
|
106
|
+
const outcome = tc.testResults.find((r) => r.name === 'bot_response_rating');
|
|
107
|
+
return outcome?.result === 'PASS' ? acc + 1 : acc;
|
|
108
|
+
}, 0);
|
|
109
|
+
const outcomePassPercent = (outcomePassCount / results.testCases.length) * 100;
|
|
110
|
+
const final = {
|
|
111
|
+
Status: results.status,
|
|
112
|
+
Duration: results.endTime
|
|
113
|
+
? readableTime(new Date(results.endTime).getTime() - new Date(results.startTime).getTime())
|
|
114
|
+
: 'Unknown',
|
|
115
|
+
'Topic Pass %': `${topicPassPercent.toFixed(2)}%`,
|
|
116
|
+
'Action Pass %': `${actionPassPercent.toFixed(2)}%`,
|
|
117
|
+
'Outcome Pass %': `${outcomePassPercent.toFixed(2)}%`,
|
|
118
|
+
};
|
|
119
|
+
const resultsTable = makeSimpleTable(final, ansis.bold.blue('Test Results'));
|
|
120
|
+
const failedTestCases = results.testCases.filter((tc) => tc.status.toLowerCase() === 'error');
|
|
121
|
+
const failedTestCasesObj = Object.fromEntries(Object.entries(failedTestCases).map(([, tc]) => [
|
|
122
|
+
`Test Case #${tc.testNumber}`,
|
|
123
|
+
tc.testResults
|
|
124
|
+
.filter((r) => r.result === 'FAILURE')
|
|
125
|
+
.map((r) => humanFriendlyName(r.name))
|
|
126
|
+
.join(', '),
|
|
127
|
+
]));
|
|
128
|
+
const failedTestCasesTable = makeSimpleTable(failedTestCasesObj, ansis.red.bold('Failed Test Cases'));
|
|
129
|
+
return tables.join('\n') + `\n${resultsTable}\n\n${failedTestCasesTable}\n`;
|
|
130
|
+
}
|
|
16
131
|
export async function handleTestResults({ id, format, results, jsonEnabled, outputDir, }) {
|
|
17
132
|
if (!results) {
|
|
18
133
|
// do nothing since there are no results to handle
|
|
@@ -20,7 +135,7 @@ export async function handleTestResults({ id, format, results, jsonEnabled, outp
|
|
|
20
135
|
}
|
|
21
136
|
const ux = new Ux({ jsonEnabled });
|
|
22
137
|
if (format === 'human') {
|
|
23
|
-
const formatted =
|
|
138
|
+
const formatted = humanFormat(results);
|
|
24
139
|
if (outputDir) {
|
|
25
140
|
const file = `test-result-${id}.txt`;
|
|
26
141
|
await writeFileToDir(outputDir, file, formatted);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleTestResults.js","sourceRoot":"","sources":["../src/handleTestResults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAA4B,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"handleTestResults.js","sourceRoot":"","sources":["../src/handleTestResults.ts"],"names":[],"mappings":"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"}
|