Skip to content

Commit f59bc39

Browse files
Merge pull request #164 from forcedotcom/er/searchFileInMultipleDirectories
W-19838570: utility method to search for authoring bundles accepts array of directories
2 parents c4ada07 + c4a75d7 commit f59bc39

10 files changed

+178
-167
lines changed

src/agent.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ import {
3333
type BotActivationResponse,
3434
type BotMetadata,
3535
type BotVersionMetadata,
36-
type CreateAfScriptResponse,
37-
type CompileAfScriptResponse,
36+
type CreateAgentResponse,
37+
type CompileAgentResponse,
3838
type DraftAgentTopicsBody,
3939
type DraftAgentTopicsResponse,
4040
PublishAgentJsonResponse,
41-
AfScript,
41+
AgentString,
4242
PublishAgent,
4343
} from './types.js';
4444
import { MaybeMock } from './maybe-mock';
@@ -290,46 +290,46 @@ export class Agent {
290290
}
291291

292292
/**
293-
* Creates AF Script using agent job spec data.
293+
* Creates Agent as string using agent job spec data.
294294
*
295295
* @param connection The connection to the org
296296
* @param agentJobSpec The agent specification data
297-
* @returns Promise<AfScript> The generated AF Script as a string
297+
* @returns Promise<AgentString> The generated Agent as a string
298298
* @beta
299299
*/
300-
public static async createAfScript(connection: Connection, agentJobSpec: AgentJobSpec): Promise<AfScript> {
300+
public static async createAgent(connection: Connection, agentJobSpec: AgentJobSpec): Promise<AgentString> {
301301
const url = '/connect/ai-assist/create-af-script';
302302
const maybeMock = new MaybeMock(connection);
303303

304-
getLogger().debug(`Generating AF Script with agent spec data: ${JSON.stringify(agentJobSpec)}`);
304+
getLogger().debug(`Generating Agent with spec data: ${JSON.stringify(agentJobSpec)}`);
305305

306-
const response = await maybeMock.request<CreateAfScriptResponse>('POST', url, agentJobSpec);
307-
if (response.isSuccess && response.afScript) {
308-
return response.afScript;
306+
const response = await maybeMock.request<CreateAgentResponse>('POST', url, agentJobSpec);
307+
if (response.isSuccess && response.agentString) {
308+
return response.agentString;
309309
} else {
310310
throw SfError.create({
311-
name: 'CreateAfScriptError',
311+
name: 'CreateAgentError',
312312
message: response.errorMessage ?? 'unknown',
313313
data: response,
314314
});
315315
}
316316
}
317317

318318
/**
319-
* Creates agent JSON from compiling AF Script on the server.
319+
* Creates agent JSON from compiling the Agent as a string on the server.
320320
*
321321
* @param connection The connection to the org
322-
* @param afScript The agent AF Script as a string
322+
* @param AgentString The agent Agent as a string
323323
* @returns Promise<string> The generated Agent JSON as a string
324324
* @beta
325325
*/
326-
public static async compileAfScript(connection: Connection, afScript: AfScript): Promise<AgentJson> {
326+
public static async compileAgent(connection: Connection, agentString: AgentString): Promise<AgentJson> {
327327
const url = '/einstein/ai-agent/v1.1/authoring/compile';
328328
const maybeMock = new MaybeMock(connection);
329329

330-
getLogger().debug(`Generating Agent JSON with AF Script: ${afScript}`);
330+
getLogger().debug(`Generating Agent JSON with: ${agentString}`);
331331

332-
const response = await maybeMock.request<CompileAfScriptResponse>('POST', url, { afScript });
332+
const response = await maybeMock.request<CompileAgentResponse>('POST', url, { agentString });
333333
if (response.status === 'success') {
334334
return response.compiledArtifact;
335335
} else {
@@ -361,7 +361,7 @@ export class Agent {
361361
const maybeMock = new MaybeMock(connection);
362362
let developerName: string;
363363

364-
getLogger().debug('Publishing AfScript');
364+
getLogger().debug('Publishing Agent');
365365

366366
const url = '/einstein/ai-agent/v1.1/authoring/publish';
367367
const response = await maybeMock.request<PublishAgentJsonResponse>('POST', url, { agentJson });

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
export {
18-
type AfScript,
18+
type AgentString,
1919
type AgentCreateConfig,
2020
type AgentCreateResponse,
2121
type AgentJobSpec,

src/types.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,10 @@ export type DraftAgentTopicsResponse = {
269269
/**
270270
* The response from the `create-af-script` API.
271271
*/
272-
export type CreateAfScriptResponse = {
272+
export type CreateAgentResponse = {
273273
isSuccess: boolean;
274274
errorMessage?: string;
275-
afScript?: AfScript;
275+
agentString?: AgentString;
276276
};
277277

278278
// ====================================================
@@ -604,7 +604,7 @@ export type AgentTraceResponse = {
604604
}>;
605605
};
606606

607-
export type CompileAfScriptResponse = AgentCompilationSuccess | AgentCompilationError;
607+
export type CompileAgentResponse = AgentCompilationSuccess | AgentCompilationError;
608608

609609
export type PublishAgentJsonResponse = {
610610
botVersionId: string;
@@ -708,4 +708,4 @@ export type AgentJson = {
708708
};
709709
};
710710

711-
export type AfScript = string;
711+
export type AgentString = string;

src/utils.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,24 @@ export const decodeHtmlEntities = (str: string = ''): string => {
7878
};
7979

8080
/**
81-
* Find the authoring bundle directory for a given bot name by recursively searching from a starting directory.
81+
* Find the authoring bundle directory for a given bot name by recursively searching from a starting directory or directories.
8282
*
83-
* @param dir - The directory to start searching from
83+
* @param dirOrDirs - The directory or array of directories to start searching from
8484
* @param botName - The name of the bot to find the authoring bundle directory for
8585
* @returns The path to the authoring bundle directory if found, undefined otherwise
8686
*/
87-
export const findAuthoringBundle = (dir: string, botName: string): string | undefined => {
87+
export const findAuthoringBundle = (dirOrDirs: string | string[], botName: string): string | undefined => {
88+
// If it's an array of directories, search in each one
89+
if (Array.isArray(dirOrDirs)) {
90+
for (const dir of dirOrDirs) {
91+
const found = findAuthoringBundle(dir, botName);
92+
if (found) return found;
93+
}
94+
return undefined;
95+
}
96+
97+
// Single directory search logic
98+
const dir = dirOrDirs;
8899
try {
89100
const files: string[] = readdirSync(dir);
90101

test/agents.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ describe('Agents', () => {
5858
expect(output.topics[0]).to.have.property('name', 'Guest_Experience_Enhancement');
5959
});
6060

61-
it('createAfScript (mock behavior) should return AF Script', async () => {
62-
process.env.SF_MOCK_DIR = join('test', 'mocks', 'createAfScript');
61+
it('createAgent (mock behavior) should return an Agent as a string', async () => {
62+
process.env.SF_MOCK_DIR = join('test', 'mocks', 'createAgent');
6363
const agentType = 'customer';
6464
const companyName = 'Coral Cloud Enterprises';
65-
const output = await Agent.createAfScript(connection, {
65+
const output = await Agent.createAgent(connection, {
6666
agentType,
6767
role: 'answer questions about vacation_rentals',
6868
companyName,
@@ -83,7 +83,7 @@ describe('Agents', () => {
8383

8484
it('createAgentJson (mock behavior) should return full agent json', async () => {
8585
process.env.SF_MOCK_DIR = join('test', 'mocks');
86-
const output = await Agent.compileAfScript(connection, 'AF Script string');
86+
const output = await Agent.compileAgent(connection, 'Agent string');
8787
expect(output).to.have.property('schemaVersion', '2.0');
8888
expect(output).to.have.property('globalConfiguration').and.be.an('object');
8989
expect(output).to.have.property('agentVersion').and.be.an('object');
Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,133 @@
11
{
22
"isSuccess": true,
3-
"afScript": "system:\n @prompt:\n You are a helpful AI assistant.\n\nconfig:\n @agent_id: \"test_agent_001\"\n @agent_name: \"Test_Agent\"\n user_locale: en_US\n\ntrigger default:\n initial_node: greeting\n\nvariables:\n user_name: string = \"Guest\"\n counter: int = 0\n\nblock greeting:\n @prompt:\n Hello! How can I help you today?\n\nblock help:\n @prompt:\n I'm here to assist you with any questions.\n\nfunctions:\n test_function:\n description: \"A simple test function\"\n"
3+
"agentJson": {
4+
"schemaVersion": "1.0",
5+
"globalConfiguration": {
6+
"developerName": "simple_response_agentV1",
7+
"label": "Simple Response Agent",
8+
"description": "A simple agent that responds to user queries.",
9+
"enableEnhancedEventLogs": false,
10+
"agentType": "AgentforceServiceAgent",
11+
"templateName": null,
12+
"defaultAgentUser": null,
13+
"defaultOutboundRouting": null,
14+
"contextVariables": [
15+
{
16+
"developerName": "some_id",
17+
"label": "Some ID",
18+
"description": "The some id",
19+
"dataType": "string",
20+
"fieldMapping": null
21+
}
22+
]
23+
},
24+
"agentVersion": {
25+
"developerName": "simple_response_agentV1",
26+
"plannerType": "Atlas__ConcurrentMultiAgentOrchestration",
27+
"systemMessages": [
28+
{
29+
"message": "Hello! I'm your SimpleResponseAgent. How can I help you today?",
30+
"messageType": "Welcome"
31+
},
32+
{
33+
"message": "I'm sorry, I'm having trouble processing your request. Please try again later.",
34+
"messageType": "Error"
35+
}
36+
],
37+
"modalityParameters": {
38+
"voice": null,
39+
"language": {
40+
"defaultLocale": "en-US",
41+
"additionalLocales": null,
42+
"allAdditionalLocales": false
43+
}
44+
},
45+
"additional_parameters": null,
46+
"company": "A simple company that responds to user queries.",
47+
"role": "A simple agent that responds to user queries.",
48+
"stateVariables": [
49+
{
50+
"developerName": "user_query",
51+
"label": "User Query",
52+
"description": "The user's query",
53+
"dataType": "string",
54+
"isList": false,
55+
"default": "",
56+
"visibility": "Internal"
57+
},
58+
{
59+
"developerName": "response",
60+
"label": "Response",
61+
"description": "The response to the user",
62+
"dataType": "string",
63+
"isList": false,
64+
"default": "",
65+
"visibility": "Internal"
66+
},
67+
{
68+
"developerName": "processing_complete",
69+
"label": "Processing Complete",
70+
"description": "Whether processing is complete",
71+
"dataType": "boolean",
72+
"isList": false,
73+
"default": false,
74+
"visibility": "Internal"
75+
}
76+
],
77+
"initialNode": "process_query",
78+
"nodes": [
79+
{
80+
"type": "subagent",
81+
"reasoningType": "salesforce.default",
82+
"description": "Process the user's query",
83+
"beforeReasoning": null,
84+
"instructions": "\n # CONTEXT\n Name: {agentName:-\"Simple Agent\"}\n Description: {agent_description:-\"You are an AI assistant developed by Salesforce\"}\n Role: {agentLabel:-\"You are an AI assistant developed by Salesforce\"}\n Tone: Maintain a {agent_plannerToneType:-\"NEUTRAL\"} tone while being clear and helpful.\n Company: {agent_company:-\"Salesforce\"}\n Locale: {agentLocale:-\"English (United States)\"}\n Location: {agent_userLocation:-\"United States\"}\n Current Date/Time: {current_dateTime:-\"\"}\n ",
85+
"focusPrompt": null,
86+
"tools": [
87+
{
88+
"type": "action",
89+
"target": "set_response_action",
90+
"boundInputs": {
91+
"some_id": "context.some_id"
92+
},
93+
"llmInputs": null,
94+
"enabled": null,
95+
"stateUpdates": [
96+
{
97+
"response": "result.response"
98+
},
99+
{
100+
"processingComplete": "true"
101+
}
102+
],
103+
"name": "set_response",
104+
"description": null,
105+
"inputParameters": null
106+
}
107+
],
108+
"preToolCall": null,
109+
"postToolCall": null,
110+
"afterReasoning": null,
111+
"developerName": "process_query",
112+
"label": "Process Query",
113+
"onInit": null,
114+
"transitions": [
115+
{
116+
"target": "exit",
117+
"condition": "state.processing_complete == true",
118+
"alias": null,
119+
"enabled": null,
120+
"instruction": null,
121+
"type": "handoff",
122+
"mode": "manual"
123+
}
124+
],
125+
"onExit": null,
126+
"actionDefinitions": [],
127+
"knowledgeDefinitions": null
128+
}
129+
],
130+
"knowledgeDefinitions": null
131+
}
132+
}
4133
}

0 commit comments

Comments
 (0)