Skip to content

Commit

Permalink
feat(W-17669110): add list command (#63)
Browse files Browse the repository at this point in the history
* feat: add list command

* chore: bump agents
  • Loading branch information
mdonnalley authored Jan 27, 2025
1 parent 600bc64 commit a8b39fb
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 52 deletions.
8 changes: 8 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@
"flags": ["api-version", "flags-dir", "job-id", "json", "target-org", "use-most-recent"],
"plugin": "@salesforce/plugin-agent"
},
{
"alias": [],
"command": "agent:test:list",
"flagAliases": [],
"flagChars": ["o"],
"flags": ["api-version", "flags-dir", "json", "target-org"],
"plugin": "@salesforce/plugin-agent"
},
{
"alias": [],
"command": "agent:test:results",
Expand Down
11 changes: 11 additions & 0 deletions messages/agent.test.list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# summary

List the available tests in the org.

# description

Run this command to get a list of tests that are available in the org. This command will return the test ID, name, and created date of each test.

# examples

- <%= config.bin %> <%= command.id %>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@inquirer/prompts": "^7.2.0",
"@oclif/core": "^4",
"@oclif/multi-stage-output": "^0.7.12",
"@salesforce/agents": "^0.7.1",
"@salesforce/agents": "^0.8.0",
"@salesforce/core": "^8.8.0",
"@salesforce/kit": "^3.2.1",
"@salesforce/sf-plugins-core": "^12.1.0",
Expand Down
60 changes: 60 additions & 0 deletions schemas/agent-test-list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/AgentTestListResult",
"definitions": {
"AgentTestListResult": {
"type": "array",
"items": {
"$ref": "#/definitions/AvailableDefinition"
}
},
"AvailableDefinition": {
"type": "object",
"properties": {
"createdById": {
"type": "string"
},
"createdByName": {
"type": "string"
},
"createdDate": {
"type": "string"
},
"fileName": {
"type": "string"
},
"fullName": {
"type": "string"
},
"id": {
"type": "string"
},
"lastModifiedById": {
"type": "string"
},
"lastModifiedByName": {
"type": "string"
},
"lastModifiedDate": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"createdById",
"createdByName",
"createdDate",
"fileName",
"fullName",
"id",
"lastModifiedById",
"lastModifiedByName",
"lastModifiedDate",
"type"
],
"additionalProperties": false
}
}
}
43 changes: 26 additions & 17 deletions src/commands/agent/create-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const FLAGGABLE_PROMPTS = {
}
}
return 'Please enter a valid User ID (005 prefix)';
}
},
},
'enrich-logs': {
message: messages.getMessage('flags.enrich-logs.summary'),
Expand Down Expand Up @@ -130,14 +130,14 @@ export default class AgentCreateV2 extends SfCommand<AgentCreateResult> {

let title: string;
const stages = [MSO_STAGES.parse];
if (flags.preview) {
if (flags.preview) {
title = 'Previewing Agent Creation';
stages.push(MSO_STAGES.preview);
} else {
} else {
title = `Creating ${agentName as string} Agent`;
stages.push(MSO_STAGES.create);
stages.push(MSO_STAGES.retrieve);
}
}

const mso = new MultiStageOutput({
jsonEnabled: this.jsonEnabled(),
Expand All @@ -164,18 +164,18 @@ export default class AgentCreateV2 extends SfCommand<AgentCreateResult> {
companyName: inputSpec.companyName!,
companyDescription: inputSpec.companyDescription!,
preDefinedTopics: inputSpec.topics,
}
},
},
generationSettings: {},
}
};
if (inputSpec?.companyWebsite) {
agentConfig.generationInfo.defaultInfo.companyWebsite = inputSpec?.companyWebsite;
}
if (!flags.preview) {
agentConfig.saveAgent = true;
agentConfig.agentSettings = {
agentName: agentName!,
}
};
if (flags['agent-api-name']) {
agentConfig.agentSettings.agentApiName = flags['agent-api-name'];
}
Expand All @@ -194,11 +194,15 @@ export default class AgentCreateV2 extends SfCommand<AgentCreateResult> {

if (response.isSuccess) {
if (!flags.preview) {
this.log(colorize(
'green',
`Successfully created ${agentName as string} in ${flags['target-org'].getUsername() ?? 'the target org'}.`
));
this.log(`Use ${colorize('dim', `sf org open agent --name ${agentName as string}`)} to view the agent in the browser.`);
this.log(
colorize(
'green',
`Successfully created ${agentName as string} in ${flags['target-org'].getUsername() ?? 'the target org'}.`
)
);
this.log(
`Use ${colorize('dim', `sf org open agent --name ${agentName as string}`)} to view the agent in the browser.`
);
} else {
const previewFileName = `agentPreview_${new Date().toISOString()}.json`;
writeFileSync(previewFileName, JSON.stringify(response, null, 2));
Expand All @@ -207,20 +211,25 @@ export default class AgentCreateV2 extends SfCommand<AgentCreateResult> {
} else {
this.log(colorize('red', `failed to create agent: ${response.errorMessage ?? ''}`));
}

return response;
}
}

// The spec must define: agentType, role, companyName, companyDescription, and topics.
// Agent type must be 'customer' or 'internal'.
const validateSpec = (spec: Partial<AgentJobSpecV2>): void => {
const requiredSpecValues: Array<'agentType' | 'role' | 'companyName' | 'companyDescription' | 'topics'> =
['agentType', 'role', 'companyName', 'companyDescription', 'topics'];
const missingFlags = requiredSpecValues.filter(f => !spec[f]);
const requiredSpecValues: Array<'agentType' | 'role' | 'companyName' | 'companyDescription' | 'topics'> = [
'agentType',
'role',
'companyName',
'companyDescription',
'topics',
];
const missingFlags = requiredSpecValues.filter((f) => !spec[f]);
if (missingFlags.length) {
throw messages.createError('error.missingRequiredFlags', [missingFlags.join(', ')]);
}

validateAgentType(spec.agentType, true);
}
};
11 changes: 9 additions & 2 deletions src/commands/agent/generate/spec-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import YAML from 'yaml';
import { Agent, AgentJobSpecCreateConfigV2, AgentJobSpecV2 } from '@salesforce/agents';
import { FLAGGABLE_SPEC_PROMPTS, makeFlags, promptForFlag, validateAgentType, validateMaxTopics } from '../../../flags.js';
import {
FLAGGABLE_SPEC_PROMPTS,
makeFlags,
promptForFlag,
validateAgentType,
validateMaxTopics,
} from '../../../flags.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.generate.spec-v2');
Expand Down Expand Up @@ -78,7 +84,8 @@ export default class AgentCreateSpecV2 extends SfCommand<AgentCreateSpecResult>
}

// Flags override inputSpec values. Prompt if neither is set.
const type = flags.type ?? validateAgentType(inputSpec?.agentType) ?? (await promptForFlag(FLAGGABLE_SPEC_PROMPTS.type));
const type =
flags.type ?? validateAgentType(inputSpec?.agentType) ?? (await promptForFlag(FLAGGABLE_SPEC_PROMPTS.type));
const role = flags.role ?? inputSpec?.role ?? (await promptForFlag(FLAGGABLE_SPEC_PROMPTS.role));
const companyName =
flags['company-name'] ?? inputSpec?.companyName ?? (await promptForFlag(FLAGGABLE_SPEC_PROMPTS['company-name']));
Expand Down
44 changes: 44 additions & 0 deletions src/commands/agent/test/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { AgentTester, type AvailableDefinition } from '@salesforce/agents';
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.test.list');

export type AgentTestListResult = AvailableDefinition[];

export default class AgentTestList extends SfCommand<AgentTestListResult> {
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');

public static readonly flags = {
'target-org': Flags.requiredOrg(),
'api-version': Flags.orgApiVersion(),
};

public async run(): Promise<AgentTestListResult> {
const { flags } = await this.parse(AgentTestList);

const agentTester = new AgentTester(flags['target-org'].getConnection(flags['api-version']));
const results = await agentTester.list();
this.table({
data: results,
columns: [
{ key: 'fullName', name: 'Name' },
{ key: 'id', name: 'Id' },
{ key: 'createdDate', name: 'Created Date' },
],
sort: { fullName: 'asc' },
});

return results;
}
}
39 changes: 7 additions & 32 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1462,10 +1462,10 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==

"@salesforce/agents@^0.7.1":
version "0.7.1"
resolved "https://registry.yarnpkg.com/@salesforce/agents/-/agents-0.7.1.tgz#13d497222766b405966e22cae77dde6a92946c62"
integrity sha512-toLqqYGof8D0mMPxBNJIeMeRmLCP786qXboA/Xl8mjhr7FRL57toyusltOnFqw7HwuIGCY5H2N6D6sM9RZD6BQ==
"@salesforce/agents@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@salesforce/agents/-/agents-0.8.0.tgz#fb823e19ed1a49b895f98426a50faea4923286a4"
integrity sha512-m+PNYaqPoKQbTCkudJFRdgON0wBJV3kW1uBHi9IevEqCWbrBcK4JVDmsb5C9IOTBwt9wVfSWi9Dvpqh0oU75mQ==
dependencies:
"@salesforce/core" "^8.8.2"
"@salesforce/kit" "^3.2.3"
Expand Down Expand Up @@ -7477,16 +7477,7 @@ stack-utils@^2.0.6:
dependencies:
escape-string-regexp "^2.0.0"

"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -7581,14 +7572,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

[email protected], strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", [email protected], strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -8197,7 +8181,7 @@ workerpool@^6.5.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544"
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -8215,15 +8199,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down

0 comments on commit a8b39fb

Please sign in to comment.