Skip to content

Commit

Permalink
Merge pull request #11 from salesforcecli/sh/agent-create-mocking
Browse files Browse the repository at this point in the history
fix: some mocking around agent creation
  • Loading branch information
shetzel authored Nov 7, 2024
2 parents bdb45c2 + 5546f2a commit 9735c06
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 25 deletions.
11 changes: 6 additions & 5 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@
"alias": [],
"command": "agent:create",
"flagAliases": [],
"flagChars": ["f", "o", "p"],
"flags": ["api-version", "flags-dir", "json", "planner", "spec", "target-org"],
"flagChars": ["f", "o"],
"flags": ["api-version", "flags-dir", "json", "spec", "target-org"],
"plugin": "@salesforce/plugin-agent"
},
{
"alias": [],
"command": "agent:create:spec",
"flagAliases": [],
"flagChars": ["d", "o"],
"flagChars": ["d", "n", "o", "t"],
"flags": [
"agent-type",
"api-version",
"company-description",
"company-name",
"company-website",
"flags-dir",
"json",
"name",
"output-dir",
"role",
"target-org"
"target-org",
"type"
],
"plugin": "@salesforce/plugin-agent"
},
Expand Down
8 changes: 2 additions & 6 deletions messages/agent.create.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ Create an Agent from an agent spec.

Create an Agent from an agent spec. Agent metadata is created in the target org and retrieved to the local project.

# flags.planner.summary

The agent planner API name.

# flags.spec.summary

The path to an agent spec file.

# flags.spec.description

The agent spec file defines job descriptions for the agent and can be created using the `sf agent create spec` command.
The agent spec file defines job titles and descriptions for the agent and can be created using the `sf agent create spec` command.

# examples

- Create an Agent:

<%= config.bin %> <%= command.id %> --planner MyAgentPlanner --spec ./agent-spec.json
<%= config.bin %> <%= command.id %> --spec ./agent-spec.json
10 changes: 7 additions & 3 deletions messages/agent.create.spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ Create an Agent spec.

# description

Create an Agent spec, which is a list of job descriptions for the agent.
Create an Agent spec, which is a list of job titles and descriptions that the agent performs.

# flags.agent-type.summary
# flags.name.summary

The name of the agent to create.

# flags.type.summary

The type of agent to create.

Expand Down Expand Up @@ -34,4 +38,4 @@ The location within the project where the agent spec will be written.

- Create an Agent spec in the default location:

<%= config.bin %> <%= command.id %> --agent-type customer-facing --role Support --company-name "Coral Cloud" --company-description "A meaningful description"
<%= config.bin %> <%= command.id %> --type customer_facing --role Support --company-name "Coral Cloud" --company-description "A meaningful description"
13 changes: 7 additions & 6 deletions src/commands/agent/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { Duration, sleep } from '@salesforce/kit';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-agent', 'agent.create');
Expand All @@ -16,7 +17,9 @@ export type AgentCreateResult = {
errorMessage?: string;
};

// This is a POST to /services/data/{api-version}/connect/attach-agent-topics
// There is no API for this yet. It's being planned/built by the Agent Creator team.
// However, we could possibly use:
// /services/data/{api-version}/connect/attach-agent-topics

export default class AgentCreate extends SfCommand<AgentCreateResult> {
public static readonly summary = messages.getMessage('summary');
Expand All @@ -32,11 +35,6 @@ export default class AgentCreate extends SfCommand<AgentCreateResult> {
summary: messages.getMessage('flags.spec.summary'),
description: messages.getMessage('flags.spec.description'),
}),
planner: Flags.string({
char: 'p',
required: true,
summary: messages.getMessage('flags.spec.summary'),
}),
};

public async run(): Promise<AgentCreateResult> {
Expand All @@ -46,6 +44,9 @@ export default class AgentCreate extends SfCommand<AgentCreateResult> {

// POST to /services/data/{api-version}/connect/attach-agent-topics

// To simulate time spent on the server generating the spec.
await sleep(Duration.seconds(5));

return { isSuccess: true };
}
}
62 changes: 57 additions & 5 deletions src/commands/agent/create/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,41 @@
* 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 { join } from 'node:path';
import { writeFileSync } from 'node:fs';
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { Duration, sleep } from '@salesforce/kit';

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

export type AgentCreateSpecResult = {
isSuccess: boolean;
errorMessage?: string;
jobSpec?: string;
jobSpec?: string; // the location of the job spec file
// We probably need more than this in the returned JSON like
// all the parameters used to generate the spec and the spec contents
};

// This is a GET of '/services/data/v62.0/connect/agent-job-spec?agentType...

// Mocked job spec, which is a list of AI generated jobs to be done
const jobSpecContent = [
{
jobTitle: 'My first job title',
jobDescription: 'This is what the first job does',
},
{
jobTitle: 'My second job title',
jobDescription: 'This is what the second job does',
},
{
jobTitle: 'My third job title',
jobDescription: 'This is what the third job does',
},
];

export default class AgentCreateSpec extends SfCommand<AgentCreateSpecResult> {
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
Expand All @@ -27,9 +47,15 @@ export default class AgentCreateSpec extends SfCommand<AgentCreateSpecResult> {
public static readonly flags = {
'target-org': Flags.requiredOrg(),
'api-version': Flags.orgApiVersion(),
'agent-type': Flags.string({
name: Flags.string({
char: 'n',
required: true,
summary: messages.getMessage('flags.agent-type.summary'),
summary: messages.getMessage('flags.name.summary'),
}),
type: Flags.string({
char: 't',
required: true,
summary: messages.getMessage('flags.type.summary'),
options: ['customer_facing', 'employee_facing'],
}),
role: Flags.string({
Expand Down Expand Up @@ -58,14 +84,40 @@ export default class AgentCreateSpec extends SfCommand<AgentCreateSpecResult> {
public async run(): Promise<AgentCreateSpecResult> {
const { flags } = await this.parse(AgentCreateSpec);

this.log(`Creating agent spec in: ${flags['output-dir']}`);
// We'll need to generate a GenAiPlanner using the name flag and deploy it
// as part of this, at least for now. We won't have to do this with the
// new API being created for us.

this.log();
this.styledHeader('Agent Details');
this.log('Name:', flags.name);
this.log('Type:', flags.type);
this.log('Role:', flags.role);
this.log('Company Name:', flags['company-name']);
this.log('Company Description:', flags['company-description']);
if (flags['company-website']) {
this.log('Company Website:', flags['company-website']);
}

this.log();
this.spinner.start('Creating agent spec');

// To simulate time spent on the server generating the spec.
await sleep(Duration.seconds(2));

// GET to /services/data/{api-version}/connect/agent-job-spec

// Write a file with the returned job specs
const filePath = join(flags['output-dir'], 'agentSpec.json');
writeFileSync(filePath, JSON.stringify(jobSpecContent, null, 4));

this.spinner.stop();

this.log(`\nSaved agent spec: ${filePath}`);

return {
isSuccess: true,
jobSpec: filePath,
};
}
}

0 comments on commit 9735c06

Please sign in to comment.