@salesforce/afv-skills 1.1.0 → 1.3.0
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/package.json +6 -5
- package/skills/accessing-webapp-data/SKILL.md +178 -0
- package/skills/agentforce-development/SKILL.md +427 -0
- package/skills/agentforce-development/assets/README-legacy.md +89 -0
- package/skills/agentforce-development/assets/agent-spec-template.md +90 -0
- package/skills/agentforce-development/assets/agents/README.md +45 -0
- package/skills/agentforce-development/assets/agents/hello-world.agent +60 -0
- package/skills/agentforce-development/assets/agents/multi-topic.agent +105 -0
- package/skills/agentforce-development/assets/agents/production-faq.agent +101 -0
- package/skills/agentforce-development/assets/agents/production-faq.bundle-meta.xml +4 -0
- package/skills/agentforce-development/assets/agents/simple-qa.agent +72 -0
- package/skills/agentforce-development/assets/apex/models-api-queueable.cls +225 -0
- package/skills/agentforce-development/assets/bundle-meta.xml +23 -0
- package/skills/agentforce-development/assets/components/apex-action.agent +52 -0
- package/skills/agentforce-development/assets/components/error-handling.agent +58 -0
- package/skills/agentforce-development/assets/components/escalation-setup.agent +169 -0
- package/skills/agentforce-development/assets/components/flow-action.agent +66 -0
- package/skills/agentforce-development/assets/components/n-ary-conditions.agent +110 -0
- package/skills/agentforce-development/assets/components/topic-with-actions.agent +40 -0
- package/skills/agentforce-development/assets/deterministic-routing.agent +166 -0
- package/skills/agentforce-development/assets/escalation-pattern.agent +209 -0
- package/skills/agentforce-development/assets/flow-action-lookup.agent +115 -0
- package/skills/agentforce-development/assets/hub-and-spoke.agent +104 -0
- package/skills/agentforce-development/assets/invocable-apex-template.cls +187 -0
- package/skills/agentforce-development/assets/local-info-agent-annotated.agent +355 -0
- package/skills/agentforce-development/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +109 -0
- package/skills/agentforce-development/assets/metadata/genai-function-apex.xml +92 -0
- package/skills/agentforce-development/assets/metadata/genai-function-flow.xml +57 -0
- package/skills/agentforce-development/assets/metadata/genai-plugin.xml +72 -0
- package/skills/agentforce-development/assets/metadata/http-callout-flow.flow-meta.xml +348 -0
- package/skills/agentforce-development/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +136 -0
- package/skills/agentforce-development/assets/minimal-starter.agent +42 -0
- package/skills/agentforce-development/assets/patterns/README.md +254 -0
- package/skills/agentforce-development/assets/patterns/action-callbacks.agent +178 -0
- package/skills/agentforce-development/assets/patterns/advanced-input-bindings.agent +141 -0
- package/skills/agentforce-development/assets/patterns/bidirectional-routing.agent +156 -0
- package/skills/agentforce-development/assets/patterns/critical-input-collection.agent +244 -0
- package/skills/agentforce-development/assets/patterns/delegation-routing.agent +89 -0
- package/skills/agentforce-development/assets/patterns/lifecycle-events.agent +127 -0
- package/skills/agentforce-development/assets/patterns/llm-controlled-actions.agent +184 -0
- package/skills/agentforce-development/assets/patterns/multi-step-workflow.agent +282 -0
- package/skills/agentforce-development/assets/patterns/open-gate-routing.agent +286 -0
- package/skills/agentforce-development/assets/patterns/procedural-instructions.agent +273 -0
- package/skills/agentforce-development/assets/patterns/prompt-template-action.agent +188 -0
- package/skills/agentforce-development/assets/patterns/system-instruction-overrides.agent +293 -0
- package/skills/agentforce-development/assets/prompt-rag-search.agent +131 -0
- package/skills/agentforce-development/assets/template-multi-topic.agent +160 -0
- package/skills/agentforce-development/assets/template-single-topic.agent +81 -0
- package/skills/agentforce-development/assets/verification-gate.agent +208 -0
- package/skills/agentforce-development/references/action-prompt-templates.md +164 -0
- package/skills/agentforce-development/references/actions-reference.md +592 -0
- package/skills/agentforce-development/references/agent-access-guide.md +72 -0
- package/skills/agentforce-development/references/agent-design-and-spec-creation.md +1010 -0
- package/skills/agentforce-development/references/agent-metadata-and-lifecycle.md +575 -0
- package/skills/agentforce-development/references/agent-script-core-language.md +1218 -0
- package/skills/agentforce-development/references/agent-topic-map-diagrams.md +323 -0
- package/skills/agentforce-development/references/agent-user-setup.md +526 -0
- package/skills/agentforce-development/references/agent-validation-and-debugging.md +803 -0
- package/skills/agentforce-development/references/known-issues.md +353 -0
- package/skills/agentforce-development/references/minimal-examples.md +67 -0
- package/skills/agentforce-development/references/production-gotchas.md +279 -0
- package/skills/agentforce-development/references/salesforce-cli-for-agents.md +393 -0
- package/skills/agentforce-development/references/version-history.md +23 -0
- package/skills/building-webapp-data-visualization/SKILL.md +72 -0
- package/skills/building-webapp-data-visualization/implementation/bar-line-chart.md +316 -0
- package/skills/building-webapp-data-visualization/implementation/dashboard-layout.md +189 -0
- package/skills/building-webapp-data-visualization/implementation/donut-chart.md +181 -0
- package/skills/building-webapp-data-visualization/implementation/stat-card.md +150 -0
- package/skills/building-webapp-react-components/SKILL.md +96 -0
- package/skills/building-webapp-react-components/implementation/component.md +78 -0
- package/skills/building-webapp-react-components/implementation/header-footer.md +132 -0
- package/skills/building-webapp-react-components/implementation/page.md +93 -0
- package/skills/configuring-webapp-csp-trusted-sites/SKILL.md +90 -0
- package/skills/configuring-webapp-csp-trusted-sites/implementation/metadata-format.md +281 -0
- package/skills/configuring-webapp-metadata/SKILL.md +158 -0
- package/skills/creating-webapp/SKILL.md +141 -0
- package/skills/deploying-webapp-to-salesforce/SKILL.md +229 -0
- package/skills/exploring-webapp-graphql-schema/SKILL.md +149 -0
- package/skills/fetching-webapp-rest-api/SKILL.md +167 -0
- package/skills/{salesforce-custom-application → generating-custom-application}/SKILL.md +2 -4
- package/skills/{salesforce-custom-field → generating-custom-field}/SKILL.md +1 -5
- package/skills/{salesforce-custom-lightning-type → generating-custom-lightning-type}/SKILL.md +36 -2
- package/skills/{salesforce-custom-object → generating-custom-object}/SKILL.md +1 -1
- package/skills/generating-custom-tab/SKILL.md +154 -0
- package/skills/generating-experience-lwr-site/SKILL.md +196 -0
- package/skills/generating-experience-lwr-site/docs/bootstrap-template-byo-lwr.md +224 -0
- package/skills/generating-experience-lwr-site/docs/configure-content-brandingSet.md +131 -0
- package/skills/generating-experience-lwr-site/docs/configure-content-route.md +232 -0
- package/skills/generating-experience-lwr-site/docs/configure-content-themeLayout.md +141 -0
- package/skills/generating-experience-lwr-site/docs/configure-content-view.md +233 -0
- package/skills/generating-experience-lwr-site/docs/configure-guest-sharing-rules.md +42 -0
- package/skills/generating-experience-lwr-site/docs/handle-component-and-region-ids.md +27 -0
- package/skills/generating-experience-lwr-site/docs/handle-ui-components.md +215 -0
- package/skills/generating-experience-react-site/SKILL.md +67 -0
- package/skills/generating-experience-react-site/docs/configure-metadata-custom-site.md +41 -0
- package/skills/generating-experience-react-site/docs/configure-metadata-digital-experience-bundle.md +17 -0
- package/skills/generating-experience-react-site/docs/configure-metadata-digital-experience-config.md +21 -0
- package/skills/generating-experience-react-site/docs/configure-metadata-digital-experience.md +38 -0
- package/skills/generating-experience-react-site/docs/configure-metadata-network.md +72 -0
- package/skills/{salesforce-flexipage → generating-flexipage}/SKILL.md +86 -9
- package/skills/{salesforce-flow → generating-flow}/SKILL.md +3 -3
- package/skills/generating-fragment/SKILL.md +117 -0
- package/skills/generating-lightning-app/SKILL.md +423 -0
- package/skills/{salesforce-list-view → generating-list-view}/SKILL.md +1 -1
- package/skills/generating-permission-set/SKILL.md +174 -0
- package/skills/{salesforce-validation-rule → generating-validation-rule}/SKILL.md +1 -1
- package/skills/generating-webapp-graphql-mutation-query/SKILL.md +258 -0
- package/skills/generating-webapp-graphql-read-query/SKILL.md +253 -0
- package/skills/implementing-webapp-file-upload/SKILL.md +396 -0
- package/skills/installing-webapp-features/SKILL.md +210 -0
- package/skills/managing-webapp-agentforce-conversation-client/SKILL.md +186 -0
- package/skills/managing-webapp-agentforce-conversation-client/references/constraints.md +134 -0
- package/skills/managing-webapp-agentforce-conversation-client/references/examples.md +132 -0
- package/skills/managing-webapp-agentforce-conversation-client/references/style-tokens.md +101 -0
- package/skills/managing-webapp-agentforce-conversation-client/references/troubleshooting.md +57 -0
- package/skills/switching-org/SKILL.md +28 -0
- package/skills/using-webapp-graphql/SKILL.md +324 -0
- package/skills/using-webapp-graphql/shared-schema.graphqls +1150 -0
- package/skills/apex-class/SKILL.md +0 -253
- package/skills/apex-class/examples/AccountDeduplicationBatch.cls +0 -148
- package/skills/apex-class/examples/AccountSelector.cls +0 -193
- package/skills/apex-class/examples/AccountService.cls +0 -201
- package/skills/apex-class/templates/abstract.cls +0 -128
- package/skills/apex-class/templates/batch.cls +0 -125
- package/skills/apex-class/templates/domain.cls +0 -102
- package/skills/apex-class/templates/dto.cls +0 -108
- package/skills/apex-class/templates/exception.cls +0 -51
- package/skills/apex-class/templates/interface.cls +0 -25
- package/skills/apex-class/templates/queueable.cls +0 -92
- package/skills/apex-class/templates/schedulable.cls +0 -75
- package/skills/apex-class/templates/selector.cls +0 -92
- package/skills/apex-class/templates/service.cls +0 -69
- package/skills/apex-class/templates/utility.cls +0 -97
- package/skills/apex-test-class/SKILL.md +0 -101
- package/skills/apex-test-class/references/assertion-patterns.md +0 -209
- package/skills/apex-test-class/references/async-testing.md +0 -276
- package/skills/apex-test-class/references/mocking-patterns.md +0 -219
- package/skills/apex-test-class/references/test-data-factory.md +0 -176
- package/skills/deployment-readiness-check/SKILL.md +0 -257
- package/skills/deployment-readiness-check/assets/deployment_checklist.md +0 -286
- package/skills/deployment-readiness-check/references/rollback_procedures.md +0 -308
- package/skills/deployment-readiness-check/scripts/check_metadata.sh +0 -207
- package/skills/salesforce-custom-tab/SKILL.md +0 -78
- package/skills/salesforce-experience-site/SKILL.md +0 -178
- package/skills/salesforce-fragment/SKILL.md +0 -42
- package/skills/salesforce-lightning-app-build/SKILL.md +0 -254
- package/skills/salesforce-web-app-creating-records/SKILL.md +0 -84
- package/skills/salesforce-web-app-feature/SKILL.md +0 -70
- package/skills/salesforce-web-app-list-and-create-records/SKILL.md +0 -36
- package/skills/salesforce-web-application/SKILL.md +0 -34
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Queueable job for AI generation using Agentforce Models API
|
|
3
|
+
* Generates {{Description}} for {{ObjectName}} records
|
|
4
|
+
* @author {{Author}}
|
|
5
|
+
* @date {{Date}}
|
|
6
|
+
*
|
|
7
|
+
* @requires API v61.0+ (Spring '24)
|
|
8
|
+
* @requires Einstein Generative AI enabled
|
|
9
|
+
* @requires Einstein Generative AI User permission set
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Invoke from trigger or other context:
|
|
13
|
+
* List<Id> recordIds = new List<Id>{ '001xx000003DGXXX' };
|
|
14
|
+
* System.enqueueJob(new {{ClassName}}_AI_Queueable(recordIds));
|
|
15
|
+
*/
|
|
16
|
+
public with sharing class {{ClassName}}_AI_Queueable implements Queueable, Database.AllowsCallouts {
|
|
17
|
+
|
|
18
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
19
|
+
// CONFIGURATION
|
|
20
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Available Models:
|
|
24
|
+
* - sfdc_ai__DefaultOpenAIGPT4OmniMini (Cost-effective, faster)
|
|
25
|
+
* - sfdc_ai__DefaultOpenAIGPT4Omni (More capable, slower)
|
|
26
|
+
* - sfdc_ai__DefaultAnthropic (Claude - nuanced)
|
|
27
|
+
* - sfdc_ai__DefaultGoogleGemini (Multimodal capable)
|
|
28
|
+
*/
|
|
29
|
+
private static final String AI_MODEL = 'sfdc_ai__DefaultOpenAIGPT4OmniMini';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Maximum records to process in a single job.
|
|
33
|
+
* Recommended: 10-20 for AI processing to avoid timeouts.
|
|
34
|
+
*/
|
|
35
|
+
private static final Integer MAX_RECORDS_PER_JOB = 20;
|
|
36
|
+
|
|
37
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
38
|
+
// INSTANCE VARIABLES
|
|
39
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
40
|
+
|
|
41
|
+
private List<Id> recordIds;
|
|
42
|
+
|
|
43
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
44
|
+
// CONSTRUCTOR
|
|
45
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @description Constructor
|
|
49
|
+
* @param recordIds List of {{ObjectName}} record IDs to process
|
|
50
|
+
*/
|
|
51
|
+
public {{ClassName}}_AI_Queueable(List<Id> recordIds) {
|
|
52
|
+
this.recordIds = recordIds;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
56
|
+
// QUEUEABLE EXECUTION
|
|
57
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @description Execute the queueable job
|
|
61
|
+
* @param context QueueableContext
|
|
62
|
+
*/
|
|
63
|
+
public void execute(QueueableContext context) {
|
|
64
|
+
if (recordIds == null || recordIds.isEmpty()) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Split into current batch and remaining
|
|
69
|
+
List<Id> currentBatch = new List<Id>();
|
|
70
|
+
List<Id> remainingIds = new List<Id>();
|
|
71
|
+
|
|
72
|
+
for (Integer i = 0; i < recordIds.size(); i++) {
|
|
73
|
+
if (i < MAX_RECORDS_PER_JOB) {
|
|
74
|
+
currentBatch.add(recordIds[i]);
|
|
75
|
+
} else {
|
|
76
|
+
remainingIds.add(recordIds[i]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Process current batch
|
|
81
|
+
processRecords(currentBatch);
|
|
82
|
+
|
|
83
|
+
// Chain next job if more records remain
|
|
84
|
+
if (!remainingIds.isEmpty() && !Test.isRunningTest()) {
|
|
85
|
+
System.enqueueJob(new {{ClassName}}_AI_Queueable(remainingIds));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
90
|
+
// PROCESSING LOGIC
|
|
91
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @description Process a batch of records
|
|
95
|
+
* @param batchIds Record IDs to process in this batch
|
|
96
|
+
*/
|
|
97
|
+
private void processRecords(List<Id> batchIds) {
|
|
98
|
+
// Query records with fields needed for AI prompt
|
|
99
|
+
List<{{ObjectName}}> records = [
|
|
100
|
+
SELECT Id, Name
|
|
101
|
+
// TODO: Add fields needed for AI context
|
|
102
|
+
// , Description, Subject, Type
|
|
103
|
+
FROM {{ObjectName}}
|
|
104
|
+
WHERE Id IN :batchIds
|
|
105
|
+
WITH USER_MODE
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
List<{{ObjectName}}> toUpdate = new List<{{ObjectName}}>();
|
|
109
|
+
|
|
110
|
+
for ({{ObjectName}} record : records) {
|
|
111
|
+
try {
|
|
112
|
+
// Generate AI content
|
|
113
|
+
String aiContent = generateAIContent(record);
|
|
114
|
+
|
|
115
|
+
if (String.isNotBlank(aiContent)) {
|
|
116
|
+
// TODO: Update the target field with AI-generated content
|
|
117
|
+
// record.AI_Summary__c = aiContent;
|
|
118
|
+
toUpdate.add(record);
|
|
119
|
+
}
|
|
120
|
+
} catch (Exception e) {
|
|
121
|
+
// Log error but continue processing other records
|
|
122
|
+
logError(record.Id, e);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Batch update
|
|
127
|
+
if (!toUpdate.isEmpty()) {
|
|
128
|
+
try {
|
|
129
|
+
update toUpdate;
|
|
130
|
+
} catch (DmlException e) {
|
|
131
|
+
System.debug(LoggingLevel.ERROR, 'DML Error: ' + e.getMessage());
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
137
|
+
// AI GENERATION
|
|
138
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @description Generate AI content for a single record
|
|
142
|
+
* @param record The record to generate content for
|
|
143
|
+
* @return Generated text content
|
|
144
|
+
*/
|
|
145
|
+
private String generateAIContent({{ObjectName}} record) {
|
|
146
|
+
// Build the prompt with record context
|
|
147
|
+
String prompt = buildPrompt(record);
|
|
148
|
+
|
|
149
|
+
// Create Models API request
|
|
150
|
+
aiplatform.ModelsAPI.createGenerations_Request request =
|
|
151
|
+
new aiplatform.ModelsAPI.createGenerations_Request();
|
|
152
|
+
request.modelName = AI_MODEL;
|
|
153
|
+
|
|
154
|
+
aiplatform.ModelsAPI_GenerationRequest genRequest =
|
|
155
|
+
new aiplatform.ModelsAPI_GenerationRequest();
|
|
156
|
+
genRequest.prompt = prompt;
|
|
157
|
+
request.body = genRequest;
|
|
158
|
+
|
|
159
|
+
// Call the API
|
|
160
|
+
aiplatform.ModelsAPI.createGenerations_Response response =
|
|
161
|
+
aiplatform.ModelsAPI.createGenerations(request);
|
|
162
|
+
|
|
163
|
+
// Extract and return generated text
|
|
164
|
+
if (response.Code200 != null &&
|
|
165
|
+
response.Code200.generations != null &&
|
|
166
|
+
!response.Code200.generations.isEmpty()) {
|
|
167
|
+
return response.Code200.generations[0].text;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @description Build the AI prompt for a record
|
|
175
|
+
* @param record The record to build prompt for
|
|
176
|
+
* @return Formatted prompt string
|
|
177
|
+
*/
|
|
178
|
+
private String buildPrompt({{ObjectName}} record) {
|
|
179
|
+
// TODO: Customize this prompt for your use case
|
|
180
|
+
String prompt =
|
|
181
|
+
'{{PromptInstructions}}\n\n' +
|
|
182
|
+
'Record Information:\n' +
|
|
183
|
+
'- Name: ' + record.Name + '\n';
|
|
184
|
+
// TODO: Add more fields as needed
|
|
185
|
+
// '- Description: ' + record.Description + '\n' +
|
|
186
|
+
// '- Type: ' + record.Type + '\n';
|
|
187
|
+
|
|
188
|
+
return prompt;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
192
|
+
// ERROR HANDLING
|
|
193
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @description Log processing errors
|
|
197
|
+
* @param recordId The record that failed
|
|
198
|
+
* @param e The exception that occurred
|
|
199
|
+
*/
|
|
200
|
+
private void logError(Id recordId, Exception e) {
|
|
201
|
+
System.debug(LoggingLevel.ERROR,
|
|
202
|
+
'{{ClassName}}_AI_Queueable Error for ' + recordId + ': ' + e.getMessage());
|
|
203
|
+
System.debug(LoggingLevel.ERROR, 'Stack Trace: ' + e.getStackTraceString());
|
|
204
|
+
|
|
205
|
+
// TODO: Implement custom error logging
|
|
206
|
+
// Options:
|
|
207
|
+
// 1. Create Error_Log__c record
|
|
208
|
+
// 2. Publish Platform Event for monitoring
|
|
209
|
+
// 3. Send email notification
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
213
|
+
// TEST SUPPORT
|
|
214
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* @description Test-visible method to verify prompt generation
|
|
218
|
+
* @param record Test record
|
|
219
|
+
* @return Generated prompt
|
|
220
|
+
*/
|
|
221
|
+
@TestVisible
|
|
222
|
+
private String testBuildPrompt({{ObjectName}} record) {
|
|
223
|
+
return buildPrompt(record);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
AUTHORING BUNDLE METADATA FILE
|
|
4
|
+
==============================
|
|
5
|
+
|
|
6
|
+
CRITICAL NAMING CONVENTION:
|
|
7
|
+
- File MUST be named: AgentName.bundle-meta.xml
|
|
8
|
+
- NOT: AgentName.aiAuthoringBundle-meta.xml
|
|
9
|
+
|
|
10
|
+
DIRECTORY STRUCTURE:
|
|
11
|
+
force-app/main/default/aiAuthoringBundles/
|
|
12
|
+
└── MyAgent/
|
|
13
|
+
├── MyAgent.agent <- Agent Script file
|
|
14
|
+
└── MyAgent.bundle-meta.xml <- This file (rename to match agent)
|
|
15
|
+
|
|
16
|
+
DEPLOYMENT COMMAND:
|
|
17
|
+
sf agent publish authoring-bundle --api-name MyAgent --target-org TARGET_ORG
|
|
18
|
+
|
|
19
|
+
DO NOT USE: sf project deploy start (will fail with "Required fields are missing: [BundleType]")
|
|
20
|
+
-->
|
|
21
|
+
<AiAuthoringBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
22
|
+
<bundleType>AGENT</bundleType>
|
|
23
|
+
</AiAuthoringBundle>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Apex-Based Action Template
|
|
2
|
+
# Define an action that calls a Salesforce Apex @InvocableMethod
|
|
3
|
+
# This is a PARTIAL template - define actions inside a topic block
|
|
4
|
+
#
|
|
5
|
+
# Usage: Replace {{placeholders}} with your values
|
|
6
|
+
# Place this inside a topic's actions: block
|
|
7
|
+
#
|
|
8
|
+
# ⚠️ The target format is apex://ClassName (NOT ClassName.MethodName)
|
|
9
|
+
# The runtime auto-discovers the @InvocableMethod on the class.
|
|
10
|
+
# ⚠️ NO GenAiFunction metadata needed for AiAuthoringBundle (Agent Script).
|
|
11
|
+
|
|
12
|
+
# Action Definition (place inside topic's actions: block)
|
|
13
|
+
{{action_name}}:
|
|
14
|
+
description: "{{ActionDescription}}"
|
|
15
|
+
inputs:
|
|
16
|
+
{{input_1_name}}: {{input_1_type}}
|
|
17
|
+
description: "{{Input1Description}}"
|
|
18
|
+
{{input_2_name}}: {{input_2_type}}
|
|
19
|
+
description: "{{Input2Description}}"
|
|
20
|
+
outputs:
|
|
21
|
+
{{output_1_name}}: {{output_1_type}}
|
|
22
|
+
description: "{{Output1Description}}"
|
|
23
|
+
success: boolean
|
|
24
|
+
description: "Whether the operation succeeded"
|
|
25
|
+
error_message: string
|
|
26
|
+
description: "Error message if operation failed"
|
|
27
|
+
target: "apex://{{ApexClassName}}"
|
|
28
|
+
|
|
29
|
+
# Usage in reasoning block:
|
|
30
|
+
#
|
|
31
|
+
# reasoning:
|
|
32
|
+
# instructions: ->
|
|
33
|
+
# | Help the user with their request.
|
|
34
|
+
# actions:
|
|
35
|
+
# invoke_{{action_name}}: @actions.{{action_name}}
|
|
36
|
+
# with {{input_1_name}}=... # LLM fills from conversation
|
|
37
|
+
# with {{input_2_name}}=@variables.some_var # From variable
|
|
38
|
+
# set @variables.result = @outputs.{{output_1_name}}
|
|
39
|
+
# set @variables.success = @outputs.success
|
|
40
|
+
|
|
41
|
+
# Common Apex Target Patterns:
|
|
42
|
+
# - apex://AccountService
|
|
43
|
+
# - apex://CaseService
|
|
44
|
+
# - apex://OrderService
|
|
45
|
+
# - apex://IntegrationService
|
|
46
|
+
# - apex://CalculationService
|
|
47
|
+
|
|
48
|
+
# Apex Class Requirements:
|
|
49
|
+
# - Must be global or public with sharing
|
|
50
|
+
# - Must have exactly ONE @InvocableMethod annotation
|
|
51
|
+
# - Use @InvocableVariable annotations on input/output wrapper class fields
|
|
52
|
+
# - No GenAiFunction metadata needed for AiAuthoringBundle (Agent Script)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Error Handling Topic Template
|
|
2
|
+
# A topic with validation and guard clauses for critical operations
|
|
3
|
+
# This is a PARTIAL template - use within a complete agent file
|
|
4
|
+
#
|
|
5
|
+
# Usage: Replace {{placeholders}} with your values
|
|
6
|
+
# Note: Includes validation patterns and error handling
|
|
7
|
+
|
|
8
|
+
topic {{topic_name}}:
|
|
9
|
+
label: "{{TopicLabel}}"
|
|
10
|
+
description: "{{TopicDescription}} - includes validation and error handling"
|
|
11
|
+
|
|
12
|
+
actions:
|
|
13
|
+
{{action_name}}:
|
|
14
|
+
description: "{{ActionDescription}}"
|
|
15
|
+
inputs:
|
|
16
|
+
{{input_name}}: {{input_type}}
|
|
17
|
+
description: "{{InputDescription}}"
|
|
18
|
+
outputs:
|
|
19
|
+
success: boolean
|
|
20
|
+
description: "Whether the operation succeeded"
|
|
21
|
+
error_message: string
|
|
22
|
+
description: "Error message if operation failed"
|
|
23
|
+
{{output_name}}: {{output_type}}
|
|
24
|
+
description: "{{OutputDescription}}"
|
|
25
|
+
target: "{{ActionTarget}}"
|
|
26
|
+
|
|
27
|
+
reasoning:
|
|
28
|
+
instructions: ->
|
|
29
|
+
# Validation guard clauses
|
|
30
|
+
if @variables.{{required_field}} is None:
|
|
31
|
+
set @variables.validation_passed = False
|
|
32
|
+
| I need {{RequiredFieldDescription}} before I can proceed.
|
|
33
|
+
| Please provide this information.
|
|
34
|
+
|
|
35
|
+
if @variables.{{amount_field}} > {{MaxAmount}}:
|
|
36
|
+
set @variables.validation_passed = False
|
|
37
|
+
| The {{AmountFieldDescription}} exceeds the maximum of {{MaxAmount}}.
|
|
38
|
+
| Would you like to:
|
|
39
|
+
| - Use the maximum allowed amount
|
|
40
|
+
| - Split into multiple operations
|
|
41
|
+
| - Contact support for a higher limit
|
|
42
|
+
|
|
43
|
+
if @variables.validation_passed == True:
|
|
44
|
+
| All validations passed. Proceeding with the operation.
|
|
45
|
+
|
|
46
|
+
actions:
|
|
47
|
+
# Only available when validation passes
|
|
48
|
+
execute_action: @actions.{{action_name}}
|
|
49
|
+
with {{input_name}}=@variables.{{input_variable}}
|
|
50
|
+
set @variables.operation_success = @outputs.success
|
|
51
|
+
set @variables.result = @outputs.{{output_name}}
|
|
52
|
+
available when @variables.validation_passed == True
|
|
53
|
+
|
|
54
|
+
# Handle errors
|
|
55
|
+
retry_operation: @utils.transition to @topic.{{topic_name}}
|
|
56
|
+
available when @variables.operation_success == False
|
|
57
|
+
|
|
58
|
+
back_to_menu: @utils.transition to @topic.topic_selector
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Escalation Setup Pattern
|
|
2
|
+
# Complete agent template with connection block for human escalation
|
|
3
|
+
#
|
|
4
|
+
# ★ When To Use This Pattern:
|
|
5
|
+
# - Agent needs to transfer conversations to human agents
|
|
6
|
+
# - Using Omni-Channel for routing
|
|
7
|
+
# - Enhanced Chat or other messaging channels
|
|
8
|
+
#
|
|
9
|
+
# ★ Key Components:
|
|
10
|
+
# 1. connection messaging: block - defines routing destination
|
|
11
|
+
# 2. @utils.escalate action - triggers the transfer
|
|
12
|
+
# 3. escalation topic - handles the handoff flow
|
|
13
|
+
#
|
|
14
|
+
# ★ Prerequisites:
|
|
15
|
+
# - Omni-Channel configured in Salesforce
|
|
16
|
+
# - Queue/Skill created for routing
|
|
17
|
+
# - Messaging channel active (Enhanced Chat, etc.)
|
|
18
|
+
#
|
|
19
|
+
# This is a COMPLETE template - customize for your use case
|
|
20
|
+
|
|
21
|
+
system:
|
|
22
|
+
instructions: "You are a helpful customer service agent. Be professional, friendly, and helpful. If you cannot resolve an issue or the customer requests a human, transfer them to a live agent."
|
|
23
|
+
messages:
|
|
24
|
+
welcome: "Hello! I'm here to help you today. What can I assist you with?"
|
|
25
|
+
error: "I apologize, but I encountered an issue. Let me connect you with a human agent."
|
|
26
|
+
|
|
27
|
+
config:
|
|
28
|
+
agent_name: "{{AGENT_NAME}}"
|
|
29
|
+
default_agent_user: "{{AGENT_USER_EMAIL}}"
|
|
30
|
+
agent_label: "{{AGENT_LABEL}}"
|
|
31
|
+
description: "Customer service agent with human escalation capability"
|
|
32
|
+
|
|
33
|
+
variables:
|
|
34
|
+
# Required linked variables for messaging context
|
|
35
|
+
EndUserId: linked string
|
|
36
|
+
source: @MessagingSession.MessagingEndUserId
|
|
37
|
+
description: "Messaging End User ID"
|
|
38
|
+
RoutableId: linked string
|
|
39
|
+
source: @MessagingSession.Id
|
|
40
|
+
description: "Messaging Session ID"
|
|
41
|
+
ContactId: linked string
|
|
42
|
+
source: @MessagingEndUser.ContactId
|
|
43
|
+
description: "Contact ID"
|
|
44
|
+
|
|
45
|
+
# Escalation tracking variables
|
|
46
|
+
escalation_requested: mutable boolean = False
|
|
47
|
+
description: "Whether customer requested human agent"
|
|
48
|
+
escalation_reason: mutable string
|
|
49
|
+
description: "Reason for escalation"
|
|
50
|
+
# ⚠️ Use 'number' not 'integer' - integer type is NOT supported in AiAuthoringBundle
|
|
51
|
+
attempts_before_escalation: mutable number = 0
|
|
52
|
+
description: "Number of attempts before escalating"
|
|
53
|
+
|
|
54
|
+
language:
|
|
55
|
+
default_locale: "en_US"
|
|
56
|
+
additional_locales: ""
|
|
57
|
+
all_additional_locales: False
|
|
58
|
+
|
|
59
|
+
# ★ CONNECTION BLOCK - Required for @utils.escalate to work
|
|
60
|
+
# This defines where escalated conversations are routed
|
|
61
|
+
# Use singular 'connection' for one channel, plural 'connections' for multiple
|
|
62
|
+
connection messaging:
|
|
63
|
+
# ⚠️ IMPORTANT: Only "OmniChannelFlow" is supported (not "queue", "skill", or "agent")
|
|
64
|
+
outbound_route_type: "OmniChannelFlow"
|
|
65
|
+
# API name of your Omni-Channel Flow
|
|
66
|
+
outbound_route_name: "{{OMNI_CHANNEL_FLOW_NAME}}"
|
|
67
|
+
# ⚠️ REQUIRED: escalation_message must be included when connection block is present
|
|
68
|
+
escalation_message: "Transferring you to a human agent now..."
|
|
69
|
+
# Optional: Allow agent to adapt responses during escalation
|
|
70
|
+
adaptive_response_allowed: True
|
|
71
|
+
|
|
72
|
+
# ★ MULTI-CHANNEL EXAMPLE (use 'connections' plural for multiple channels)
|
|
73
|
+
# connections:
|
|
74
|
+
# messaging:
|
|
75
|
+
# outbound_route_type: "OmniChannelFlow"
|
|
76
|
+
# outbound_route_name: "Chat_Support_Flow"
|
|
77
|
+
# escalation_message: "Connecting you to chat support..."
|
|
78
|
+
# adaptive_response_allowed: True
|
|
79
|
+
# telephony:
|
|
80
|
+
# outbound_route_type: "OmniChannelFlow"
|
|
81
|
+
# outbound_route_name: "Phone_Support_Flow"
|
|
82
|
+
# escalation_message: "Transferring to phone support..."
|
|
83
|
+
# adaptive_response_allowed: False
|
|
84
|
+
|
|
85
|
+
# Entry point
|
|
86
|
+
start_agent topic_selector:
|
|
87
|
+
label: "Topic Selector"
|
|
88
|
+
description: "Routes users to appropriate topics based on intent"
|
|
89
|
+
|
|
90
|
+
reasoning:
|
|
91
|
+
instructions: ->
|
|
92
|
+
| Greet the customer and determine their needs.
|
|
93
|
+
| If they ask for a human or live agent, route to escalation.
|
|
94
|
+
| Otherwise, try to help them directly.
|
|
95
|
+
actions:
|
|
96
|
+
go_help: @utils.transition to @topic.help
|
|
97
|
+
go_escalation: @utils.transition to @topic.escalation
|
|
98
|
+
available when @variables.escalation_requested == True
|
|
99
|
+
|
|
100
|
+
topic help:
|
|
101
|
+
label: "Help"
|
|
102
|
+
description: "Provides assistance to customers"
|
|
103
|
+
|
|
104
|
+
reasoning:
|
|
105
|
+
instructions: ->
|
|
106
|
+
| Help the customer with their question.
|
|
107
|
+
| If you cannot resolve their issue after 2-3 attempts, offer to connect them with a human.
|
|
108
|
+
| If they explicitly ask for a human agent at any time, transfer immediately.
|
|
109
|
+
|
|
|
110
|
+
| Phrases that indicate escalation request:
|
|
111
|
+
| - "talk to a human"
|
|
112
|
+
| - "speak to someone"
|
|
113
|
+
| - "real person"
|
|
114
|
+
| - "live agent"
|
|
115
|
+
| - "customer service representative"
|
|
116
|
+
|
|
|
117
|
+
| Track escalation reason if provided:
|
|
118
|
+
set @variables.escalation_reason = ...
|
|
119
|
+
actions:
|
|
120
|
+
offer_escalation: @utils.transition to @topic.escalation
|
|
121
|
+
|
|
122
|
+
immediate_escalation: @utils.transition to @topic.escalation
|
|
123
|
+
|
|
124
|
+
topic escalation:
|
|
125
|
+
label: "Escalation"
|
|
126
|
+
description: "Transfers conversation to human agent"
|
|
127
|
+
|
|
128
|
+
reasoning:
|
|
129
|
+
instructions: ->
|
|
130
|
+
| The customer is being transferred to a human agent.
|
|
131
|
+
| Acknowledge their request and apologize for any inconvenience.
|
|
132
|
+
| Let them know a human will be with them shortly.
|
|
133
|
+
|
|
|
134
|
+
| Say something like:
|
|
135
|
+
| "I understand you'd like to speak with a human agent. I'm connecting you now.
|
|
136
|
+
| A customer service representative will be with you shortly. Thank you for your patience."
|
|
137
|
+
actions:
|
|
138
|
+
# ★ ESCALATION ACTION
|
|
139
|
+
# This transfers the conversation to the queue defined in connection block
|
|
140
|
+
transfer_to_human: @utils.escalate
|
|
141
|
+
description: "Transfer to human agent when customer requests or issue cannot be resolved"
|
|
142
|
+
|
|
143
|
+
# ★ NOTE: Skill-Based and Queue-Based Routing
|
|
144
|
+
# ⚠️ As of Dec 2025, only "OmniChannelFlow" is supported for outbound_route_type
|
|
145
|
+
# "queue", "skill", and "agent" cause validation errors
|
|
146
|
+
# You must create an Omni-Channel Flow that routes to your desired queue/skill
|
|
147
|
+
|
|
148
|
+
# ★ Alternative: GenAiPlannerBundle Escalation with Reason
|
|
149
|
+
# If using GenAiPlannerBundle (not visible in Studio), you can use:
|
|
150
|
+
#
|
|
151
|
+
# actions:
|
|
152
|
+
# escalate_with_reason: @utils.escalate with reason="Customer requested human assistance"
|
|
153
|
+
#
|
|
154
|
+
# NOTE: The "with reason" syntax only works in GenAiPlannerBundle!
|
|
155
|
+
# AiAuthoringBundle will fail with SyntaxError if you use it.
|
|
156
|
+
|
|
157
|
+
# ★ Troubleshooting Escalation:
|
|
158
|
+
#
|
|
159
|
+
# Issue: "escalate" action not recognized
|
|
160
|
+
# Fix: Add the connection messaging: block
|
|
161
|
+
#
|
|
162
|
+
# Issue: Transfer fails silently
|
|
163
|
+
# Fix: Verify Omni-Channel queue exists and has available agents
|
|
164
|
+
#
|
|
165
|
+
# Issue: SyntaxError: Unexpected 'with'
|
|
166
|
+
# Fix: You're using AiAuthoringBundle - remove "with reason" syntax
|
|
167
|
+
#
|
|
168
|
+
# Issue: Agent user lacks permissions
|
|
169
|
+
# Fix: Grant Omni-Channel permissions to the default_agent_user
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Flow-Based Action Template
|
|
2
|
+
# Define an action that calls a Salesforce Flow
|
|
3
|
+
# This is a PARTIAL template - define actions inside a topic block
|
|
4
|
+
#
|
|
5
|
+
# ⚠️ NOTE ON DEPLOYMENT METHODS:
|
|
6
|
+
# - AiAuthoringBundle: `with`/`set` clauses ARE supported (TDD validated v1.7.0+)
|
|
7
|
+
# - GenAiPlannerBundle: Full syntax including `with`/`set` also supported
|
|
8
|
+
#
|
|
9
|
+
# Both deployment methods support the Two-Level Action System:
|
|
10
|
+
# Level 1: Action definition in topic `actions:` block (with target/inputs/outputs)
|
|
11
|
+
# Level 2: Action invocation in `reasoning.actions:` block (with `with`/`set` clauses)
|
|
12
|
+
#
|
|
13
|
+
# Usage: Replace {{placeholders}} with your values
|
|
14
|
+
# Place this inside a topic's actions: block
|
|
15
|
+
|
|
16
|
+
# Action Definition (place inside topic's actions: block)
|
|
17
|
+
{{action_name}}:
|
|
18
|
+
description: "{{ActionDescription}}"
|
|
19
|
+
inputs:
|
|
20
|
+
{{input_1_name}}: {{input_1_type}}
|
|
21
|
+
description: "{{Input1Description}}"
|
|
22
|
+
{{input_2_name}}: {{input_2_type}}
|
|
23
|
+
description: "{{Input2Description}}"
|
|
24
|
+
outputs:
|
|
25
|
+
{{output_1_name}}: {{output_1_type}}
|
|
26
|
+
description: "{{Output1Description}}"
|
|
27
|
+
{{output_2_name}}: {{output_2_type}}
|
|
28
|
+
description: "{{Output2Description}}"
|
|
29
|
+
target: "flow://{{FlowApiName}}"
|
|
30
|
+
|
|
31
|
+
# Usage in reasoning block:
|
|
32
|
+
#
|
|
33
|
+
# ═══════════════════════════════════════════════════════════════════════════════
|
|
34
|
+
# ✅ Recommended Pattern — Level 2 invocation with `with`/`set` (works in both
|
|
35
|
+
# AiAuthoringBundle and GenAiPlannerBundle, TDD validated v1.7.0+)
|
|
36
|
+
# ═══════════════════════════════════════════════════════════════════════════════
|
|
37
|
+
#
|
|
38
|
+
# reasoning:
|
|
39
|
+
# instructions: ->
|
|
40
|
+
# | Help the user with their request.
|
|
41
|
+
# actions:
|
|
42
|
+
# invoke_{{action_name}}: @actions.{{action_name}}
|
|
43
|
+
# with {{input_1_name}}=... # LLM fills from conversation
|
|
44
|
+
# with {{input_2_name}}=@variables.some_var # From variable
|
|
45
|
+
# set @variables.result1 = @outputs.{{output_1_name}}
|
|
46
|
+
# set @variables.result2 = @outputs.{{output_2_name}}
|
|
47
|
+
#
|
|
48
|
+
# ═══════════════════════════════════════════════════════════════════════════════
|
|
49
|
+
# Alternative: LLM auto-invoke based on action description (no explicit binding)
|
|
50
|
+
# ═══════════════════════════════════════════════════════════════════════════════
|
|
51
|
+
#
|
|
52
|
+
# reasoning:
|
|
53
|
+
# instructions: ->
|
|
54
|
+
# | Help the user with their request.
|
|
55
|
+
# | Use the available actions when needed.
|
|
56
|
+
# actions:
|
|
57
|
+
# back_to_menu: @utils.transition to @topic.topic_selector
|
|
58
|
+
|
|
59
|
+
# Common Flow Target Patterns:
|
|
60
|
+
# - flow://Get_Account_Details
|
|
61
|
+
# - flow://Create_Case
|
|
62
|
+
# - flow://Update_Opportunity
|
|
63
|
+
# - flow://Send_Email_Notification
|
|
64
|
+
# - flow://Calculate_Discount
|
|
65
|
+
|
|
66
|
+
# Input/Output Types: string, number, boolean, list[string], object
|