scc-universal 1.1.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/.claude-plugin/plugin.json +44 -0
- package/.cursor/agents/deep-researcher.md +142 -0
- package/.cursor/agents/doc-updater.md +219 -0
- package/.cursor/agents/eval-runner.md +335 -0
- package/.cursor/agents/learning-engine.md +210 -0
- package/.cursor/agents/loop-operator.md +245 -0
- package/.cursor/agents/refactor-cleaner.md +119 -0
- package/.cursor/agents/sf-admin-agent.md +127 -0
- package/.cursor/agents/sf-agentforce-agent.md +126 -0
- package/.cursor/agents/sf-apex-agent.md +117 -0
- package/.cursor/agents/sf-architect.md +426 -0
- package/.cursor/agents/sf-aura-reviewer.md +369 -0
- package/.cursor/agents/sf-bugfix-agent.md +101 -0
- package/.cursor/agents/sf-flow-agent.md +155 -0
- package/.cursor/agents/sf-integration-agent.md +141 -0
- package/.cursor/agents/sf-lwc-agent.md +123 -0
- package/.cursor/agents/sf-review-agent.md +357 -0
- package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
- package/.cursor/hooks/adapter.js +81 -0
- package/.cursor/hooks/after-file-edit.js +26 -0
- package/.cursor/hooks/after-mcp-execution.js +12 -0
- package/.cursor/hooks/after-shell-execution.js +30 -0
- package/.cursor/hooks/after-tab-file-edit.js +12 -0
- package/.cursor/hooks/before-mcp-execution.js +11 -0
- package/.cursor/hooks/before-read-file.js +13 -0
- package/.cursor/hooks/before-shell-execution.js +29 -0
- package/.cursor/hooks/before-submit-prompt.js +23 -0
- package/.cursor/hooks/pre-compact.js +7 -0
- package/.cursor/hooks/session-end.js +10 -0
- package/.cursor/hooks/session-start.js +10 -0
- package/.cursor/hooks/stop.js +18 -0
- package/.cursor/hooks/subagent-start.js +10 -0
- package/.cursor/hooks/subagent-stop.js +10 -0
- package/.cursor/hooks.json +107 -0
- package/.cursor/skills/aside/SKILL.md +115 -0
- package/.cursor/skills/checkpoint/SKILL.md +50 -0
- package/.cursor/skills/configure-scc/SKILL.md +160 -0
- package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
- package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
- package/.cursor/skills/model-route/SKILL.md +81 -0
- package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
- package/.cursor/skills/refactor-clean/SKILL.md +133 -0
- package/.cursor/skills/resume-session/SKILL.md +111 -0
- package/.cursor/skills/save-session/SKILL.md +183 -0
- package/.cursor/skills/search-first/SKILL.md +140 -0
- package/.cursor/skills/security-scan/SKILL.md +142 -0
- package/.cursor/skills/sessions/SKILL.md +124 -0
- package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
- package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
- package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
- package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
- package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
- package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
- package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
- package/.cursor/skills/sf-api-design/SKILL.md +237 -0
- package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
- package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
- package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
- package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
- package/.cursor/skills/sf-debugging/SKILL.md +362 -0
- package/.cursor/skills/sf-deployment/SKILL.md +291 -0
- package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
- package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
- package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
- package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
- package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
- package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
- package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
- package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
- package/.cursor/skills/sf-help/SKILL.md +156 -0
- package/.cursor/skills/sf-integration/SKILL.md +479 -0
- package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
- package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
- package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
- package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
- package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
- package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
- package/.cursor/skills/sf-security/SKILL.md +330 -0
- package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
- package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
- package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
- package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
- package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
- package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
- package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
- package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
- package/.cursor/skills/strategic-compact/SKILL.md +205 -0
- package/.cursor/skills/update-docs/SKILL.md +162 -0
- package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
- package/.cursor-plugin/plugin.json +26 -0
- package/LICENSE +21 -0
- package/README.md +522 -0
- package/agents/deep-researcher.md +145 -0
- package/agents/doc-updater.md +222 -0
- package/agents/eval-runner.md +340 -0
- package/agents/learning-engine.md +211 -0
- package/agents/loop-operator.md +247 -0
- package/agents/refactor-cleaner.md +122 -0
- package/agents/sf-admin-agent.md +131 -0
- package/agents/sf-agentforce-agent.md +132 -0
- package/agents/sf-apex-agent.md +124 -0
- package/agents/sf-architect.md +435 -0
- package/agents/sf-aura-reviewer.md +372 -0
- package/agents/sf-bugfix-agent.md +105 -0
- package/agents/sf-flow-agent.md +159 -0
- package/agents/sf-integration-agent.md +146 -0
- package/agents/sf-lwc-agent.md +127 -0
- package/agents/sf-review-agent.md +366 -0
- package/agents/sf-visualforce-reviewer.md +468 -0
- package/assets/logo.svg +18 -0
- package/docs/ARCHITECTURE.md +133 -0
- package/docs/authoring-guide.md +373 -0
- package/docs/hook-development.md +578 -0
- package/docs/token-optimization.md +139 -0
- package/docs/workflow-examples.md +645 -0
- package/examples/agentforce-action/README.md +227 -0
- package/examples/apex-trigger-handler/README.md +114 -0
- package/examples/devops-pipeline/README.md +325 -0
- package/examples/flow-automation/README.md +188 -0
- package/examples/integration-pattern/README.md +416 -0
- package/examples/lwc-component/README.md +180 -0
- package/examples/platform-events/README.md +492 -0
- package/examples/scratch-org-setup/README.md +138 -0
- package/examples/security-audit/README.md +244 -0
- package/examples/visualforce-migration/README.md +314 -0
- package/hooks/hooks.json +338 -0
- package/hooks/memory-persistence/README.md +73 -0
- package/manifests/install-modules.json +217 -0
- package/manifests/install-profiles.json +17 -0
- package/mcp-configs/mcp-servers.json +19 -0
- package/package.json +89 -0
- package/schemas/hooks.schema.json +123 -0
- package/schemas/install-modules.schema.json +76 -0
- package/schemas/install-profiles.schema.json +28 -0
- package/schemas/install-state.schema.json +73 -0
- package/schemas/package-manager.schema.json +18 -0
- package/schemas/plugin.schema.json +112 -0
- package/schemas/scc-install-config.schema.json +29 -0
- package/schemas/state-store.schema.json +111 -0
- package/scripts/cli/install-apply.js +170 -0
- package/scripts/cli/uninstall.js +193 -0
- package/scripts/hooks/check-console-log.js +101 -0
- package/scripts/hooks/check-hook-enabled.js +17 -0
- package/scripts/hooks/check-platform-docs-age.js +48 -0
- package/scripts/hooks/cost-tracker.js +78 -0
- package/scripts/hooks/doc-file-warning.js +63 -0
- package/scripts/hooks/evaluate-session.js +98 -0
- package/scripts/hooks/governor-check.js +220 -0
- package/scripts/hooks/learning-observe.sh +206 -0
- package/scripts/hooks/mcp-health-check.js +588 -0
- package/scripts/hooks/post-bash-build-complete.js +34 -0
- package/scripts/hooks/post-bash-pr-created.js +43 -0
- package/scripts/hooks/post-edit-console-warn.js +61 -0
- package/scripts/hooks/post-edit-format.js +79 -0
- package/scripts/hooks/post-edit-typecheck.js +98 -0
- package/scripts/hooks/post-write.js +168 -0
- package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
- package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
- package/scripts/hooks/pre-compact.js +51 -0
- package/scripts/hooks/pre-tool-use.js +163 -0
- package/scripts/hooks/pre-write-doc-warn.js +9 -0
- package/scripts/hooks/quality-gate.js +251 -0
- package/scripts/hooks/run-with-flags-shell.sh +32 -0
- package/scripts/hooks/run-with-flags.js +135 -0
- package/scripts/hooks/session-end-marker.js +29 -0
- package/scripts/hooks/session-end.js +311 -0
- package/scripts/hooks/session-start.js +202 -0
- package/scripts/hooks/sfdx-scanner-check.js +142 -0
- package/scripts/hooks/sfdx-validate.js +119 -0
- package/scripts/hooks/stop-hook.js +170 -0
- package/scripts/hooks/suggest-compact.js +67 -0
- package/scripts/lib/agent-adapter.js +82 -0
- package/scripts/lib/apex-analysis.js +194 -0
- package/scripts/lib/hook-flags.js +74 -0
- package/scripts/lib/install-config.js +73 -0
- package/scripts/lib/install-executor.js +363 -0
- package/scripts/lib/install-state.js +121 -0
- package/scripts/lib/orchestration-session.js +299 -0
- package/scripts/lib/package-manager.js +124 -0
- package/scripts/lib/project-detect.js +228 -0
- package/scripts/lib/schema-validator.js +190 -0
- package/scripts/lib/skill-adapter.js +100 -0
- package/scripts/lib/state-store.js +376 -0
- package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
- package/scripts/lib/utils.js +313 -0
- package/scripts/scc.js +164 -0
- package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
- package/skills/_reference/APEX_CURSOR.md +159 -0
- package/skills/_reference/API_VERSIONS.md +78 -0
- package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
- package/skills/_reference/ASYNC_PATTERNS.md +163 -0
- package/skills/_reference/AURA_COMPONENTS.md +146 -0
- package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
- package/skills/_reference/DATA_MODELING.md +124 -0
- package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
- package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
- package/skills/_reference/DEPRECATIONS.md +79 -0
- package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
- package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
- package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
- package/skills/_reference/FLOW_PATTERNS.md +113 -0
- package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
- package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
- package/skills/_reference/LWC_PATTERNS.md +79 -0
- package/skills/_reference/METADATA_TYPES.md +115 -0
- package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
- package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
- package/skills/_reference/PLATFORM_EVENTS.md +121 -0
- package/skills/_reference/REPORTING_API.md +143 -0
- package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
- package/skills/_reference/SECURITY_PATTERNS.md +127 -0
- package/skills/_reference/SHARING_MODEL.md +120 -0
- package/skills/_reference/SOQL_PATTERNS.md +119 -0
- package/skills/_reference/TESTING_STANDARDS.md +96 -0
- package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
- package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
- package/skills/aside/SKILL.md +118 -0
- package/skills/checkpoint/SKILL.md +53 -0
- package/skills/configure-scc/SKILL.md +163 -0
- package/skills/continuous-agent-loop/SKILL.md +264 -0
- package/skills/mcp-server-patterns/SKILL.md +146 -0
- package/skills/model-route/SKILL.md +84 -0
- package/skills/prompt-optimizer/SKILL.md +369 -0
- package/skills/refactor-clean/SKILL.md +136 -0
- package/skills/resume-session/SKILL.md +114 -0
- package/skills/save-session/SKILL.md +186 -0
- package/skills/search-first/SKILL.md +144 -0
- package/skills/security-scan/SKILL.md +146 -0
- package/skills/sessions/SKILL.md +127 -0
- package/skills/sf-agentforce-development/SKILL.md +450 -0
- package/skills/sf-apex-async-patterns/SKILL.md +326 -0
- package/skills/sf-apex-best-practices/SKILL.md +425 -0
- package/skills/sf-apex-constraints/SKILL.md +81 -0
- package/skills/sf-apex-cursor/SKILL.md +338 -0
- package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
- package/skills/sf-apex-testing/SKILL.md +409 -0
- package/skills/sf-api-design/SKILL.md +238 -0
- package/skills/sf-approval-processes/SKILL.md +315 -0
- package/skills/sf-aura-development/SKILL.md +263 -0
- package/skills/sf-build-fix/SKILL.md +121 -0
- package/skills/sf-data-modeling/SKILL.md +278 -0
- package/skills/sf-debugging/SKILL.md +363 -0
- package/skills/sf-deployment/SKILL.md +295 -0
- package/skills/sf-deployment-constraints/SKILL.md +155 -0
- package/skills/sf-devops-ci-cd/SKILL.md +325 -0
- package/skills/sf-docs-lookup/SKILL.md +103 -0
- package/skills/sf-e2e-testing/SKILL.md +324 -0
- package/skills/sf-experience-cloud/SKILL.md +249 -0
- package/skills/sf-flow-development/SKILL.md +377 -0
- package/skills/sf-governor-limits/SKILL.md +323 -0
- package/skills/sf-harness-audit/SKILL.md +142 -0
- package/skills/sf-help/SKILL.md +159 -0
- package/skills/sf-integration/SKILL.md +483 -0
- package/skills/sf-lwc-constraints/SKILL.md +130 -0
- package/skills/sf-lwc-development/SKILL.md +303 -0
- package/skills/sf-lwc-testing/SKILL.md +388 -0
- package/skills/sf-metadata-management/SKILL.md +288 -0
- package/skills/sf-platform-events-cdc/SKILL.md +375 -0
- package/skills/sf-quickstart/SKILL.md +173 -0
- package/skills/sf-security/SKILL.md +334 -0
- package/skills/sf-security-constraints/SKILL.md +127 -0
- package/skills/sf-soql-constraints/SKILL.md +131 -0
- package/skills/sf-soql-optimization/SKILL.md +354 -0
- package/skills/sf-tdd-workflow/SKILL.md +336 -0
- package/skills/sf-testing-constraints/SKILL.md +200 -0
- package/skills/sf-trigger-constraints/SKILL.md +90 -0
- package/skills/sf-trigger-frameworks/SKILL.md +347 -0
- package/skills/sf-visualforce-development/SKILL.md +260 -0
- package/skills/strategic-compact/SKILL.md +208 -0
- package/skills/update-docs/SKILL.md +165 -0
- package/skills/update-platform-docs/SKILL.md +90 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-agentforce-development
|
|
3
|
+
description: >-
|
|
4
|
+
Agentforce AI agent development — topics, actions, Prompt Templates, testing. Use when building or testing Agentforce agents. Do NOT use for non-Agentforce Apex or Flow-only automation.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Agentforce Development
|
|
8
|
+
|
|
9
|
+
Procedures for building Agentforce AI agents on the Salesforce platform. Architecture details, action type reference, instruction guidelines, and context engineering principles live in the reference file.
|
|
10
|
+
|
|
11
|
+
@../_reference/AGENTFORCE_PATTERNS.md
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
- Building Agentforce AI agents from scratch
|
|
16
|
+
- Configuring agent topics, actions, or conversation instructions
|
|
17
|
+
- Creating custom Apex actions or Flow actions for Agentforce
|
|
18
|
+
- Authoring or reviewing prompt templates for agent responses
|
|
19
|
+
- Testing, debugging, or evaluating agent behavior in Agent Builder
|
|
20
|
+
- Reviewing Agentforce limits or security requirements
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Agent Types
|
|
25
|
+
|
|
26
|
+
| Type | Audience | Channel | Use Case |
|
|
27
|
+
|------|----------|---------|----------|
|
|
28
|
+
| Einstein Copilot | Internal users | Salesforce UI sidebar | Sales/service rep productivity |
|
|
29
|
+
| Experience Cloud Agent | External users | Messaging, web chat | Customer self-service |
|
|
30
|
+
| Custom Agent | Any | API, custom channel | Bespoke workflows, backend automation |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Topics: Defining Scope and Instructions
|
|
35
|
+
|
|
36
|
+
Topics are the primary organisational unit for agent capabilities.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
Topic Name: Case Management
|
|
40
|
+
Description: Handles customer service case creation, updating, and
|
|
41
|
+
status inquiries. Covers support tickets and complaints.
|
|
42
|
+
|
|
43
|
+
Instructions:
|
|
44
|
+
- Verify customer identity before accessing case details
|
|
45
|
+
- Create a new case if no existing open case matches the issue
|
|
46
|
+
- Escalate to a human agent if the customer is frustrated or issue is technical
|
|
47
|
+
- Summarise the resolution when closing a case
|
|
48
|
+
|
|
49
|
+
Guardrails:
|
|
50
|
+
- Do not discuss competitor products
|
|
51
|
+
- Do not make promises about resolution timelines
|
|
52
|
+
- Recommend contacting billing for billing disputes (out of scope)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Custom Apex Actions -- @InvocableMethod
|
|
58
|
+
|
|
59
|
+
### Complete Example
|
|
60
|
+
|
|
61
|
+
```apex
|
|
62
|
+
public with sharing class CaseManagementAction {
|
|
63
|
+
|
|
64
|
+
@InvocableMethod(
|
|
65
|
+
label='Create Support Case'
|
|
66
|
+
description='Creates a new support case for a customer.
|
|
67
|
+
Requires accountId and subject.'
|
|
68
|
+
category='Case Management'
|
|
69
|
+
)
|
|
70
|
+
public static List<CreateCaseResult> createSupportCase(
|
|
71
|
+
List<CreateCaseRequest> requests) {
|
|
72
|
+
List<CreateCaseResult> results = new List<CreateCaseResult>();
|
|
73
|
+
List<Case> casesToInsert = new List<Case>();
|
|
74
|
+
|
|
75
|
+
for (CreateCaseRequest req : requests) {
|
|
76
|
+
casesToInsert.add(new Case(
|
|
77
|
+
AccountId = req.accountId,
|
|
78
|
+
ContactId = req.contactId,
|
|
79
|
+
Subject = req.subject,
|
|
80
|
+
Description = req.description,
|
|
81
|
+
Priority = req.priority != null ? req.priority : 'Medium',
|
|
82
|
+
Status = 'New',
|
|
83
|
+
Origin = 'Agentforce'
|
|
84
|
+
));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
List<Database.SaveResult> saveResults =
|
|
88
|
+
Database.insert(casesToInsert, false, AccessLevel.USER_MODE);
|
|
89
|
+
|
|
90
|
+
Set<Id> successIds = new Set<Id>();
|
|
91
|
+
for (Database.SaveResult sr : saveResults) {
|
|
92
|
+
if (sr.isSuccess()) successIds.add(sr.getId());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Map<Id, Case> caseMap = new Map<Id, Case>(
|
|
96
|
+
[SELECT Id, CaseNumber FROM Case WHERE Id IN :successIds]
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
for (Database.SaveResult sr : saveResults) {
|
|
100
|
+
CreateCaseResult result = new CreateCaseResult();
|
|
101
|
+
if (sr.isSuccess()) {
|
|
102
|
+
result.caseId = sr.getId();
|
|
103
|
+
result.caseNumber = caseMap.get(sr.getId())?.CaseNumber;
|
|
104
|
+
result.success = true;
|
|
105
|
+
result.message = 'Case created: ' + result.caseNumber;
|
|
106
|
+
} else {
|
|
107
|
+
result.success = false;
|
|
108
|
+
result.message = 'Failed: ' + sr.getErrors()[0].getMessage();
|
|
109
|
+
}
|
|
110
|
+
results.add(result);
|
|
111
|
+
}
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public class CreateCaseRequest {
|
|
116
|
+
@InvocableVariable(label='Account ID'
|
|
117
|
+
description='Salesforce Account ID of the customer'
|
|
118
|
+
required=true)
|
|
119
|
+
public Id accountId;
|
|
120
|
+
|
|
121
|
+
@InvocableVariable(label='Contact ID'
|
|
122
|
+
description='Contact ID raising the case' required=false)
|
|
123
|
+
public Id contactId;
|
|
124
|
+
|
|
125
|
+
@InvocableVariable(label='Subject'
|
|
126
|
+
description='Brief issue description (max 255 chars)'
|
|
127
|
+
required=true)
|
|
128
|
+
public String subject;
|
|
129
|
+
|
|
130
|
+
@InvocableVariable(label='Description'
|
|
131
|
+
description='Detailed issue description' required=false)
|
|
132
|
+
public String description;
|
|
133
|
+
|
|
134
|
+
@InvocableVariable(label='Priority'
|
|
135
|
+
description='Low, Medium, High, Critical' required=false)
|
|
136
|
+
public String priority;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public class CreateCaseResult {
|
|
140
|
+
@InvocableVariable(label='Case ID')
|
|
141
|
+
public Id caseId;
|
|
142
|
+
|
|
143
|
+
@InvocableVariable(label='Case Number')
|
|
144
|
+
public String caseNumber;
|
|
145
|
+
|
|
146
|
+
@InvocableVariable(label='Success')
|
|
147
|
+
public Boolean success;
|
|
148
|
+
|
|
149
|
+
@InvocableVariable(label='Message')
|
|
150
|
+
public String message;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### @InvocableMethod Best Practices
|
|
156
|
+
|
|
157
|
+
```apex
|
|
158
|
+
// Good label and description — LLM uses these to decide when to call
|
|
159
|
+
@InvocableMethod(
|
|
160
|
+
label='Get Account Recent Cases'
|
|
161
|
+
description='Retrieves the 5 most recent open cases for an account.
|
|
162
|
+
Use when customer asks about open tickets or case status.'
|
|
163
|
+
category='Case Management'
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
// Return a result object (agent needs confirmation), not void
|
|
167
|
+
// Bulkify — agent runtime may batch calls
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Flow Actions for Agentforce
|
|
173
|
+
|
|
174
|
+
Use Flow actions when logic involves declarative orchestration, screen interactions, or non-developer maintenance.
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
Flow: Update_Account_Segment (Autolaunched Flow)
|
|
178
|
+
Variables:
|
|
179
|
+
- accountId (Input, Text, Required)
|
|
180
|
+
- newSegment (Input, Text, Required)
|
|
181
|
+
- result (Output, Text)
|
|
182
|
+
|
|
183
|
+
Steps:
|
|
184
|
+
1. Get Records: Account WHERE Id = {accountId}
|
|
185
|
+
2. Decision: Is segment different from current?
|
|
186
|
+
3. Update Records: Account.Segment__c = {newSegment}
|
|
187
|
+
4. Assignment: result = "Segment updated to " + {newSegment}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Add the Flow to an Agentforce topic as an action in Setup.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Prompt Templates
|
|
195
|
+
|
|
196
|
+
### Creating a Flex Prompt Template
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
Template Name: Case Summary for Agent
|
|
200
|
+
Template Type: Flex (general purpose)
|
|
201
|
+
Grounding: Case record
|
|
202
|
+
|
|
203
|
+
Template Body:
|
|
204
|
+
You are a helpful customer service assistant.
|
|
205
|
+
Summarise the following case for a support representative.
|
|
206
|
+
|
|
207
|
+
Case Details:
|
|
208
|
+
- Case Number: {!$Input:Case.CaseNumber}
|
|
209
|
+
- Subject: {!$Input:Case.Subject}
|
|
210
|
+
- Status: {!$Input:Case.Status}
|
|
211
|
+
- Priority: {!$Input:Case.Priority}
|
|
212
|
+
- Customer: {!$Input:Case.Account.Name}
|
|
213
|
+
- Description: {!$Input:Case.Description}
|
|
214
|
+
|
|
215
|
+
Provide:
|
|
216
|
+
1. A 2-sentence summary of the issue
|
|
217
|
+
2. Recommended next action
|
|
218
|
+
3. Estimated complexity: Low/Medium/High
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Using Prompt Templates in Apex
|
|
222
|
+
|
|
223
|
+
> Note: The ConnectApi surface for Einstein/Agentforce changes rapidly. Verify exact class/method names against the ConnectApi Apex Reference for your target API version (v66.0 Spring '26).
|
|
224
|
+
|
|
225
|
+
```apex
|
|
226
|
+
public with sharing class PromptTemplateAction {
|
|
227
|
+
|
|
228
|
+
@InvocableMethod(
|
|
229
|
+
label='Generate Case Summary'
|
|
230
|
+
description='Generates an AI summary using Einstein Prompt Template'
|
|
231
|
+
)
|
|
232
|
+
public static List<SummaryResult> generateCaseSummary(
|
|
233
|
+
List<SummaryRequest> requests) {
|
|
234
|
+
List<SummaryResult> results = new List<SummaryResult>();
|
|
235
|
+
|
|
236
|
+
for (SummaryRequest req : requests) {
|
|
237
|
+
try {
|
|
238
|
+
ConnectApi.EinsteinPromptTemplateGenerationsRepresentation
|
|
239
|
+
response = ConnectApi.EinsteinLLM
|
|
240
|
+
.generateMessagesForPromptTemplate(
|
|
241
|
+
'Case_Summary_for_Agent',
|
|
242
|
+
new Map<String, String>{
|
|
243
|
+
'Input:Case' => req.caseId
|
|
244
|
+
},
|
|
245
|
+
new Map<String, ConnectApi
|
|
246
|
+
.EinsteinPromptTemplateGenerationsInput>()
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
SummaryResult result = new SummaryResult();
|
|
250
|
+
result.summary = response.generations[0].text;
|
|
251
|
+
result.success = true;
|
|
252
|
+
results.add(result);
|
|
253
|
+
} catch (Exception e) {
|
|
254
|
+
SummaryResult result = new SummaryResult();
|
|
255
|
+
result.success = false;
|
|
256
|
+
result.errorMessage = e.getMessage();
|
|
257
|
+
results.add(result);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return results;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
public class SummaryRequest {
|
|
264
|
+
@InvocableVariable(label='Case ID' required=true)
|
|
265
|
+
public Id caseId;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
public class SummaryResult {
|
|
269
|
+
@InvocableVariable(label='Summary')
|
|
270
|
+
public String summary;
|
|
271
|
+
@InvocableVariable(label='Success')
|
|
272
|
+
public Boolean success;
|
|
273
|
+
@InvocableVariable(label='Error Message')
|
|
274
|
+
public String errorMessage;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Mixing Deterministic Logic with LLM Actions (Spring '26)
|
|
282
|
+
|
|
283
|
+
Agentforce supports mixing deterministic actions (Apex, Flow) with LLM-driven prompt actions within a single topic.
|
|
284
|
+
|
|
285
|
+
> Configuration is done in the Agentforce Builder UI. The pseudo-code below illustrates the architectural pattern.
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Topic: CaseTriage
|
|
289
|
+
|
|
290
|
+
Step 1 (Deterministic — Apex):
|
|
291
|
+
Call: EscalateCaseAction
|
|
292
|
+
Condition: case.Priority == 'Critical'
|
|
293
|
+
|
|
294
|
+
Step 2 (Deterministic — Apex):
|
|
295
|
+
Call: GetKnowledgeArticles
|
|
296
|
+
Input: case.Subject
|
|
297
|
+
-> Grounds the LLM with relevant articles
|
|
298
|
+
|
|
299
|
+
Step 3 (LLM — Prompt Template):
|
|
300
|
+
Template: Case_Resolution_Suggestion
|
|
301
|
+
Grounding: case record + articles from Step 2
|
|
302
|
+
|
|
303
|
+
Step 4 (Deterministic — Apex):
|
|
304
|
+
Call: LogAgentInteraction
|
|
305
|
+
-> Audit trail logged regardless of LLM output
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Use when: compliance rules need deterministic execution, multi-step processes mix AI judgment with guaranteed logic, or audit trails must separate deterministic decisions from AI content.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Testing Agentforce
|
|
313
|
+
|
|
314
|
+
### Unit Testing Apex Actions
|
|
315
|
+
|
|
316
|
+
```apex
|
|
317
|
+
@IsTest
|
|
318
|
+
public class CaseManagementActionTest {
|
|
319
|
+
|
|
320
|
+
@TestSetup
|
|
321
|
+
static void setup() {
|
|
322
|
+
Account acc = new Account(Name='Test Account');
|
|
323
|
+
insert acc;
|
|
324
|
+
Contact con = new Contact(LastName='Doe', AccountId=acc.Id);
|
|
325
|
+
insert con;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
@IsTest
|
|
329
|
+
static void testCreateCase_validInput_createsCase() {
|
|
330
|
+
Account acc = [SELECT Id FROM Account LIMIT 1];
|
|
331
|
+
Contact con = [SELECT Id FROM Contact LIMIT 1];
|
|
332
|
+
|
|
333
|
+
CaseManagementAction.CreateCaseRequest req =
|
|
334
|
+
new CaseManagementAction.CreateCaseRequest();
|
|
335
|
+
req.accountId = acc.Id;
|
|
336
|
+
req.contactId = con.Id;
|
|
337
|
+
req.subject = 'Cannot access portal';
|
|
338
|
+
req.priority = 'High';
|
|
339
|
+
|
|
340
|
+
Test.startTest();
|
|
341
|
+
List<CaseManagementAction.CreateCaseResult> results =
|
|
342
|
+
CaseManagementAction.createSupportCase(
|
|
343
|
+
new List<CaseManagementAction.CreateCaseRequest>{req});
|
|
344
|
+
Test.stopTest();
|
|
345
|
+
|
|
346
|
+
System.assert(results[0].success);
|
|
347
|
+
System.assertNotEquals(null, results[0].caseId);
|
|
348
|
+
|
|
349
|
+
Case created = [SELECT Status, Origin, Priority
|
|
350
|
+
FROM Case WHERE Id = :results[0].caseId];
|
|
351
|
+
System.assertEquals('Agentforce', created.Origin);
|
|
352
|
+
System.assertEquals('High', created.Priority);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
@IsTest
|
|
356
|
+
static void testCreateCase_bulk_createsMultipleCases() {
|
|
357
|
+
Account acc = [SELECT Id FROM Account LIMIT 1];
|
|
358
|
+
|
|
359
|
+
List<CaseManagementAction.CreateCaseRequest> requests =
|
|
360
|
+
new List<CaseManagementAction.CreateCaseRequest>();
|
|
361
|
+
for (Integer i = 0; i < 200; i++) {
|
|
362
|
+
CaseManagementAction.CreateCaseRequest req =
|
|
363
|
+
new CaseManagementAction.CreateCaseRequest();
|
|
364
|
+
req.accountId = acc.Id;
|
|
365
|
+
req.subject = 'Bulk test case ' + i;
|
|
366
|
+
requests.add(req);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
Test.startTest();
|
|
370
|
+
List<CaseManagementAction.CreateCaseResult> results =
|
|
371
|
+
CaseManagementAction.createSupportCase(requests);
|
|
372
|
+
Test.stopTest();
|
|
373
|
+
|
|
374
|
+
Integer successCount = 0;
|
|
375
|
+
for (CaseManagementAction.CreateCaseResult r : results) {
|
|
376
|
+
if (r.success) successCount++;
|
|
377
|
+
}
|
|
378
|
+
System.assertEquals(200, successCount);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## SF CLI Agent Commands (Spring '26)
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
# Activate an agent
|
|
389
|
+
sf agent activate --name "Sales Assistant" --target-org MySandbox
|
|
390
|
+
|
|
391
|
+
# Run automated agent tests
|
|
392
|
+
sf agent test run --target-org MySandbox --output-dir test-results/
|
|
393
|
+
|
|
394
|
+
# Resume a paused test job
|
|
395
|
+
sf agent test resume --job-id <jobId> --target-org MySandbox
|
|
396
|
+
|
|
397
|
+
# Get test results
|
|
398
|
+
sf agent test results --job-id <jobId> --result-format human
|
|
399
|
+
|
|
400
|
+
# Generate starter agent spec
|
|
401
|
+
sf agent generate agent-spec \
|
|
402
|
+
--agent-type custom \
|
|
403
|
+
--output-dir force-app/main/agents \
|
|
404
|
+
--target-org MySandbox
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Security: Data Access in AI Context
|
|
410
|
+
|
|
411
|
+
```apex
|
|
412
|
+
// Enforce sharing in Agentforce Apex actions
|
|
413
|
+
public with sharing class SecureAgentAction {
|
|
414
|
+
|
|
415
|
+
@InvocableMethod(label='Get Customer Orders')
|
|
416
|
+
public static List<OrderResult> getOrders(List<OrderRequest> requests) {
|
|
417
|
+
// Collect ALL accountIds — runtime may batch multiple requests
|
|
418
|
+
Set<Id> accountIds = new Set<Id>();
|
|
419
|
+
for (OrderRequest req : requests) {
|
|
420
|
+
accountIds.add(req.accountId);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// USER_MODE enforces CRUD/FLS and sharing rules
|
|
424
|
+
List<Order__c> orders = [
|
|
425
|
+
SELECT Id, Name, Status__c, Amount__c, AccountId
|
|
426
|
+
FROM Order__c
|
|
427
|
+
WHERE AccountId IN :accountIds
|
|
428
|
+
WITH USER_MODE
|
|
429
|
+
LIMIT 50
|
|
430
|
+
];
|
|
431
|
+
|
|
432
|
+
// Build results grouped by AccountId...
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### PII Considerations
|
|
438
|
+
|
|
439
|
+
- Use field-level security to control what the agent can access
|
|
440
|
+
- Ground Prompt Templates only with fields the user's profile can read
|
|
441
|
+
- Review agent conversations in Setup > Agent Conversations
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Related
|
|
446
|
+
|
|
447
|
+
- Agent: `sf-agentforce-agent` -- for interactive, in-depth guidance
|
|
448
|
+
- Constraints: sf-apex-constraints
|
|
449
|
+
- Reference: @../_reference/AGENTFORCE_PATTERNS.md
|