Skip to content

Commit 41a8e40

Browse files
Merge pull request #217 from salesforcecli/wr/SF_DEMO_AGENT
Wr/sf demo agent @W-19759683@ @W-19757322@
2 parents 1e899f2 + d60433e commit 41a8e40

File tree

2 files changed

+82
-53
lines changed

2 files changed

+82
-53
lines changed

src/commands/agent/preview.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import { resolve, join } from 'node:path';
18-
import * as process from 'node:process';
1918
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
2019
import { AuthInfo, Connection, Messages, SfError } from '@salesforce/core';
2120
import React from 'react';
@@ -113,8 +112,14 @@ export default class AgentPreview extends SfCommand<AgentPreviewResult> {
113112
let selectedAgent;
114113

115114
if (flags['authoring-bundle']) {
115+
const envAgentName = env.getString('SF_DEMO_AGENT');
116+
const agent = agentsQuery.records.find((a) => a.DeveloperName === envAgentName);
116117
selectedAgent = {
117-
Id: process.env.SF_DEMO_AGENT_ID ?? 'SF_DEMO_AGENT_ID is unset',
118+
Id:
119+
agent?.Id ??
120+
`Couldn't find an agent in ${agentsQuery.records.map((a) => a.DeveloperName).join(', ')} matching ${
121+
envAgentName ?? '!SF_DEMO_AGENT is unset!'
122+
}`,
118123
DeveloperName: flags['authoring-bundle'],
119124
};
120125
} else if (apiNameFlag) {

src/components/agent-preview-react.tsx

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616

1717
import path from 'node:path';
1818
import fs from 'node:fs';
19+
import * as process from 'node:process';
1920
import React from 'react';
2021
import { Box, Text, useInput } from 'ink';
2122
import TextInput from 'ink-text-input';
22-
import { Connection } from '@salesforce/core';
23+
import { Connection, SfError } from '@salesforce/core';
2324
import { AgentPreview, AgentPreviewSendResponse, writeDebugLog } from '@salesforce/agents';
2425
import { sleep } from '@salesforce/kit';
2526

@@ -106,26 +107,39 @@ export function AgentPreviewReact(props: {
106107
React.useEffect(() => {
107108
const endSession = async (): Promise<void> => {
108109
if (sessionEnded) {
109-
// TODO: Support other end types (such as Escalate)
110-
await agent.end(sessionId, 'UserRequest');
111-
process.exit(0);
110+
try {
111+
// TODO: Support other end types (such as Escalate)
112+
await agent.end(sessionId, 'UserRequest');
113+
process.exit(0);
114+
} catch (e) {
115+
// in case the agent session never started, calling agent.end will throw an error, but we've already shown the error to the user
116+
process.exit(0);
117+
}
112118
}
113119
};
114120
void endSession();
115121
}, [sessionEnded]);
116122

117123
React.useEffect(() => {
118124
const startSession = async (): Promise<void> => {
119-
const session = await agent.start();
120-
setSessionId(session.sessionId);
121-
setHeader(`New session started with "${props.name}" (${session.sessionId})`);
122-
await sleep(500); // Add a short delay to make it feel more natural
123-
setIsTyping(false);
124-
if (outputDir) {
125-
const dateForDir = new Date().toISOString().replace(/:/g, '-').split('.')[0];
126-
setTempDir(path.join(outputDir, `${dateForDir}--${session.sessionId}`));
125+
try {
126+
const session = await agent.start();
127+
setSessionId(session.sessionId);
128+
setHeader(`New session started with "${props.name}" (${session.sessionId})`);
129+
await sleep(500); // Add a short delay to make it feel more natural
130+
setIsTyping(false);
131+
if (outputDir) {
132+
const dateForDir = new Date().toISOString().replace(/:/g, '-').split('.')[0];
133+
setTempDir(path.join(outputDir, `${dateForDir}--${session.sessionId}`));
134+
}
135+
setMessages([{ role: name, content: session.messages[0].message, timestamp: new Date() }]);
136+
} catch (e) {
137+
const sfError = SfError.wrap(e);
138+
setIsTyping(false);
139+
setHeader('Error starting session');
140+
setMessages([{ role: name, content: `${sfError.name} - ${sfError.message}`, timestamp: new Date() }]);
141+
setSessionEnded(true);
127142
}
128-
setMessages([{ role: name, content: session.messages[0].message, timestamp: new Date() }]);
129143
};
130144

131145
void startSession();
@@ -194,45 +208,55 @@ export function AgentPreviewReact(props: {
194208
<Text dimColor>{'─'.repeat(process.stdout.columns - 2)}</Text>
195209
</Box>
196210

197-
<Box marginBottom={1}>
198-
<Text>&gt; </Text>
199-
<TextInput
200-
showCursor
201-
value={query}
202-
placeholder="Start typing (press ESC to exit)"
203-
onChange={setQuery}
204-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
205-
onSubmit={async (content) => {
206-
if (!content) return;
207-
setQuery('');
208-
209-
// Add the most recent user message to the chat window
210-
setMessages((prev) => [...prev, { role: 'user', content, timestamp: new Date() }]);
211-
setIsTyping(true);
212-
const response = await agent.send(sessionId, content);
213-
setResponses((prev) => [...prev, response]);
214-
const message = response.messages[0].message;
215-
216-
if (!message) {
217-
throw new Error('Failed to send message');
218-
}
219-
setIsTyping(false);
220-
221-
// Add the agent's response to the chat
222-
setMessages((prev) => [...prev, { role: name, content: message, timestamp: new Date() }]);
223-
224-
// If there is an apex debug log entry, get the log and write it to the output dir
225-
if (response.apexDebugLog && tempDir) {
226-
// Write the apex debug to the output dir
227-
await writeDebugLog(connection, response.apexDebugLog, tempDir);
228-
const logId = response.apexDebugLog.Id;
229-
if (logId) {
230-
setApexDebugLogs((prev) => [...prev, path.join(tempDir, `${logId}.log`)]);
211+
{sessionEnded ? null : (
212+
<Box marginBottom={1}>
213+
<Text>&gt; </Text>
214+
<TextInput
215+
showCursor
216+
value={query}
217+
placeholder="Start typing (press ESC to exit)"
218+
onChange={setQuery}
219+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
220+
onSubmit={async (content) => {
221+
if (!content) return;
222+
setQuery('');
223+
224+
try {
225+
// Add the most recent user message to the chat window
226+
setMessages((prev) => [...prev, { role: 'user', content, timestamp: new Date() }]);
227+
setIsTyping(true);
228+
const response = await agent.send(sessionId, content);
229+
setResponses((prev) => [...prev, response]);
230+
const message = response.messages[0].message;
231+
232+
if (!message) {
233+
throw new Error('Failed to send message');
234+
}
235+
setIsTyping(false);
236+
237+
// Add the agent's response to the chat
238+
setMessages((prev) => [...prev, { role: name, content: message, timestamp: new Date() }]);
239+
240+
// If there is an apex debug log entry, get the log and write it to the output dir
241+
if (response.apexDebugLog && tempDir) {
242+
// Write the apex debug to the output dir
243+
await writeDebugLog(connection, response.apexDebugLog, tempDir);
244+
const logId = response.apexDebugLog.Id;
245+
if (logId) {
246+
setApexDebugLogs((prev) => [...prev, path.join(tempDir, `${logId}.log`)]);
247+
}
248+
}
249+
} catch (e) {
250+
const sfError = SfError.wrap(e);
251+
setIsTyping(false);
252+
setHeader(`Error: ${sfError.name}`);
253+
setMessages([{ role: name, content: `${sfError.name} - ${sfError.message}`, timestamp: new Date() }]);
254+
setSessionEnded(true);
231255
}
232-
}
233-
}}
234-
/>
235-
</Box>
256+
}}
257+
/>
258+
</Box>
259+
)}
236260

237261
{sessionEnded ? (
238262
<Box

0 commit comments

Comments
 (0)