@salesforce/afv-skills 1.1.0 → 1.2.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.
Files changed (103) hide show
  1. package/package.json +4 -4
  2. package/skills/agentforce-development/SKILL.md +427 -0
  3. package/skills/agentforce-development/assets/README-legacy.md +89 -0
  4. package/skills/agentforce-development/assets/agent-spec-template.md +90 -0
  5. package/skills/agentforce-development/assets/agents/README.md +45 -0
  6. package/skills/agentforce-development/assets/agents/hello-world.agent +60 -0
  7. package/skills/agentforce-development/assets/agents/multi-topic.agent +105 -0
  8. package/skills/agentforce-development/assets/agents/production-faq.agent +101 -0
  9. package/skills/agentforce-development/assets/agents/production-faq.bundle-meta.xml +4 -0
  10. package/skills/agentforce-development/assets/agents/simple-qa.agent +72 -0
  11. package/skills/agentforce-development/assets/apex/models-api-queueable.cls +225 -0
  12. package/skills/agentforce-development/assets/bundle-meta.xml +23 -0
  13. package/skills/agentforce-development/assets/components/apex-action.agent +52 -0
  14. package/skills/agentforce-development/assets/components/error-handling.agent +58 -0
  15. package/skills/agentforce-development/assets/components/escalation-setup.agent +169 -0
  16. package/skills/agentforce-development/assets/components/flow-action.agent +66 -0
  17. package/skills/agentforce-development/assets/components/n-ary-conditions.agent +110 -0
  18. package/skills/agentforce-development/assets/components/topic-with-actions.agent +40 -0
  19. package/skills/agentforce-development/assets/deterministic-routing.agent +166 -0
  20. package/skills/agentforce-development/assets/escalation-pattern.agent +209 -0
  21. package/skills/agentforce-development/assets/flow-action-lookup.agent +115 -0
  22. package/skills/agentforce-development/assets/hub-and-spoke.agent +104 -0
  23. package/skills/agentforce-development/assets/invocable-apex-template.cls +187 -0
  24. package/skills/agentforce-development/assets/local-info-agent-annotated.agent +355 -0
  25. package/skills/agentforce-development/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +109 -0
  26. package/skills/agentforce-development/assets/metadata/genai-function-apex.xml +92 -0
  27. package/skills/agentforce-development/assets/metadata/genai-function-flow.xml +57 -0
  28. package/skills/agentforce-development/assets/metadata/genai-plugin.xml +72 -0
  29. package/skills/agentforce-development/assets/metadata/http-callout-flow.flow-meta.xml +348 -0
  30. package/skills/agentforce-development/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +136 -0
  31. package/skills/agentforce-development/assets/minimal-starter.agent +42 -0
  32. package/skills/agentforce-development/assets/patterns/README.md +254 -0
  33. package/skills/agentforce-development/assets/patterns/action-callbacks.agent +178 -0
  34. package/skills/agentforce-development/assets/patterns/advanced-input-bindings.agent +141 -0
  35. package/skills/agentforce-development/assets/patterns/bidirectional-routing.agent +156 -0
  36. package/skills/agentforce-development/assets/patterns/critical-input-collection.agent +244 -0
  37. package/skills/agentforce-development/assets/patterns/delegation-routing.agent +89 -0
  38. package/skills/agentforce-development/assets/patterns/lifecycle-events.agent +127 -0
  39. package/skills/agentforce-development/assets/patterns/llm-controlled-actions.agent +184 -0
  40. package/skills/agentforce-development/assets/patterns/multi-step-workflow.agent +282 -0
  41. package/skills/agentforce-development/assets/patterns/open-gate-routing.agent +286 -0
  42. package/skills/agentforce-development/assets/patterns/procedural-instructions.agent +273 -0
  43. package/skills/agentforce-development/assets/patterns/prompt-template-action.agent +188 -0
  44. package/skills/agentforce-development/assets/patterns/system-instruction-overrides.agent +293 -0
  45. package/skills/agentforce-development/assets/prompt-rag-search.agent +131 -0
  46. package/skills/agentforce-development/assets/template-multi-topic.agent +160 -0
  47. package/skills/agentforce-development/assets/template-single-topic.agent +81 -0
  48. package/skills/agentforce-development/assets/verification-gate.agent +208 -0
  49. package/skills/agentforce-development/references/action-prompt-templates.md +164 -0
  50. package/skills/agentforce-development/references/actions-reference.md +592 -0
  51. package/skills/agentforce-development/references/agent-access-guide.md +72 -0
  52. package/skills/agentforce-development/references/agent-design-and-spec-creation.md +1010 -0
  53. package/skills/agentforce-development/references/agent-metadata-and-lifecycle.md +575 -0
  54. package/skills/agentforce-development/references/agent-script-core-language.md +1218 -0
  55. package/skills/agentforce-development/references/agent-topic-map-diagrams.md +323 -0
  56. package/skills/agentforce-development/references/agent-user-setup.md +526 -0
  57. package/skills/agentforce-development/references/agent-validation-and-debugging.md +803 -0
  58. package/skills/agentforce-development/references/known-issues.md +353 -0
  59. package/skills/agentforce-development/references/minimal-examples.md +67 -0
  60. package/skills/agentforce-development/references/production-gotchas.md +279 -0
  61. package/skills/agentforce-development/references/salesforce-cli-for-agents.md +393 -0
  62. package/skills/agentforce-development/references/version-history.md +23 -0
  63. package/skills/generate-permission-set/SKILL.md +174 -0
  64. package/skills/salesforce-custom-application/SKILL.md +1 -2
  65. package/skills/salesforce-custom-field/SKILL.md +0 -4
  66. package/skills/salesforce-custom-tab/SKILL.md +84 -8
  67. package/skills/salesforce-experience-lwr-site/SKILL.md +196 -0
  68. package/skills/salesforce-experience-lwr-site/docs/bootstrap-template-byo-lwr.md +224 -0
  69. package/skills/salesforce-experience-lwr-site/docs/configure-content-brandingSet.md +131 -0
  70. package/skills/salesforce-experience-lwr-site/docs/configure-content-route.md +232 -0
  71. package/skills/salesforce-experience-lwr-site/docs/configure-content-themeLayout.md +141 -0
  72. package/skills/salesforce-experience-lwr-site/docs/configure-content-view.md +233 -0
  73. package/skills/salesforce-experience-lwr-site/docs/configure-guest-sharing-rules.md +42 -0
  74. package/skills/salesforce-experience-lwr-site/docs/handle-component-and-region-ids.md +27 -0
  75. package/skills/salesforce-experience-lwr-site/docs/handle-ui-components.md +215 -0
  76. package/skills/salesforce-flow/SKILL.md +2 -2
  77. package/skills/salesforce-fragment/SKILL.md +85 -10
  78. package/skills/salesforce-lightning-app-build/SKILL.md +102 -10
  79. package/skills/apex-class/SKILL.md +0 -253
  80. package/skills/apex-class/examples/AccountDeduplicationBatch.cls +0 -148
  81. package/skills/apex-class/examples/AccountSelector.cls +0 -193
  82. package/skills/apex-class/examples/AccountService.cls +0 -201
  83. package/skills/apex-class/templates/abstract.cls +0 -128
  84. package/skills/apex-class/templates/batch.cls +0 -125
  85. package/skills/apex-class/templates/domain.cls +0 -102
  86. package/skills/apex-class/templates/dto.cls +0 -108
  87. package/skills/apex-class/templates/exception.cls +0 -51
  88. package/skills/apex-class/templates/interface.cls +0 -25
  89. package/skills/apex-class/templates/queueable.cls +0 -92
  90. package/skills/apex-class/templates/schedulable.cls +0 -75
  91. package/skills/apex-class/templates/selector.cls +0 -92
  92. package/skills/apex-class/templates/service.cls +0 -69
  93. package/skills/apex-class/templates/utility.cls +0 -97
  94. package/skills/apex-test-class/SKILL.md +0 -101
  95. package/skills/apex-test-class/references/assertion-patterns.md +0 -209
  96. package/skills/apex-test-class/references/async-testing.md +0 -276
  97. package/skills/apex-test-class/references/mocking-patterns.md +0 -219
  98. package/skills/apex-test-class/references/test-data-factory.md +0 -176
  99. package/skills/deployment-readiness-check/SKILL.md +0 -257
  100. package/skills/deployment-readiness-check/assets/deployment_checklist.md +0 -286
  101. package/skills/deployment-readiness-check/references/rollback_procedures.md +0 -308
  102. package/skills/deployment-readiness-check/scripts/check_metadata.sh +0 -207
  103. package/skills/salesforce-experience-site/SKILL.md +0 -178
@@ -0,0 +1,209 @@
1
+ # Escalation Pattern Template
2
+ # ===========================
3
+ #
4
+ # This template demonstrates the complete escalation pattern with:
5
+ # - Multi-channel connection blocks (messaging, voice, web)
6
+ # - Graceful handoff with escalation messages
7
+ # - Pre-escalation data gathering
8
+ # - OmniChannel routing configuration
9
+ #
10
+ # Pattern: Multi-channel escalation with context preservation
11
+ # Use when: Any agent that needs human handoff capabilities
12
+
13
+ system:
14
+ messages:
15
+ welcome: "Hello! I'm here to help. If I can't assist you, I can connect you with a specialist."
16
+ error: "I apologize, something went wrong. Let me connect you with someone who can help."
17
+ instructions: "You are a helpful agent. When you cannot resolve an issue, escalate to a human agent with full context."
18
+
19
+ config:
20
+ agent_name: "EscalationPatternAgent"
21
+ agent_label: "Escalation Demo Agent"
22
+ description: "Agent demonstrating complete escalation patterns"
23
+ default_agent_user: "agent@yourorg.com" # REQUIRED: Change to valid Einstein Agent User
24
+
25
+ # ============================================================
26
+ # CONNECTION BLOCKS (Multi-Channel Escalation)
27
+ # ============================================================
28
+
29
+ connections:
30
+ # Messaging channel (SMS, WhatsApp, etc.)
31
+ connection messaging:
32
+ escalation_message: "One moment, I'm transferring our conversation to a specialist who can better assist you."
33
+ outbound_route_type: "OmniChannelFlow"
34
+ outbound_route_name: "<flow://Escalate_Messaging_To_Agent>"
35
+ adaptive_response_allowed: False
36
+
37
+ # Voice channel
38
+ connection voice:
39
+ escalation_message: "Please hold while I transfer you to a specialist. They will have full context of our conversation."
40
+ outbound_route_type: "Queue"
41
+ outbound_route_name: "Customer_Support_Queue"
42
+ adaptive_response_allowed: True
43
+
44
+ # Web chat channel
45
+ connection web:
46
+ escalation_message: "Connecting you with a live agent now. They'll be with you shortly."
47
+ outbound_route_type: "OmniChannelFlow"
48
+ outbound_route_name: "<flow://Web_Chat_Escalation_Flow>"
49
+ adaptive_response_allowed: False
50
+
51
+ variables:
52
+ # Customer context
53
+ customer_name: mutable string = ""
54
+ description: "Customer's name for personalization"
55
+ customer_issue: mutable string = ""
56
+ description: "Summary of customer's issue"
57
+ issue_category: mutable string = ""
58
+ description: "Category of issue for routing"
59
+
60
+ # Escalation state
61
+ escalation_reason: mutable string = ""
62
+ description: "Reason for escalation"
63
+ attempts_before_escalation: mutable number = 0
64
+ description: "Number of resolution attempts"
65
+ ready_to_escalate: mutable boolean = False
66
+ description: "Whether pre-escalation data is gathered"
67
+
68
+ start_agent entry:
69
+ description: "Entry point - greet and assess needs"
70
+ reasoning:
71
+ instructions: |
72
+ Greet the customer and understand their needs.
73
+ Try to help directly, escalate if needed.
74
+ actions:
75
+ go_support: @utils.transition to @topic.support
76
+ description: "Help with support issue"
77
+
78
+ # ============================================================
79
+ # SUPPORT TOPIC (With Escalation Triggers)
80
+ # ============================================================
81
+
82
+ topic support:
83
+ description: "Attempt to resolve issue, escalate if unable"
84
+ reasoning:
85
+ instructions: ->
86
+ # POST-ACTION: Check if escalation was triggered
87
+ if @variables.ready_to_escalate == True:
88
+ transition to @topic.pre_escalation
89
+
90
+ # Track attempts
91
+ | I'm here to help you with your issue.
92
+
93
+ if @variables.attempts_before_escalation >= 2:
94
+ | It seems like I'm having trouble resolving this.
95
+ | Would you like me to connect you with a specialist?
96
+
97
+ actions:
98
+ # Attempt resolution
99
+ try_resolve: @actions.Attempt_Resolution
100
+ description: "Try to resolve the issue"
101
+ with issue = ... # LLM extracts from conversation
102
+ set @variables.customer_issue = @outputs.issue_summary
103
+ set @variables.issue_category = @outputs.category
104
+ set @variables.attempts_before_escalation = @variables.attempts_before_escalation + 1
105
+
106
+ # User-initiated escalation
107
+ request_human: @utils.setVariables
108
+ description: "I'd like to speak with a human"
109
+ with escalation_reason = "Customer requested human agent"
110
+ with ready_to_escalate = True
111
+
112
+ # Agent-initiated escalation (after failed attempts)
113
+ escalate_complex: @utils.setVariables
114
+ description: "Connect me with a specialist"
115
+ available when @variables.attempts_before_escalation >= 2
116
+ with escalation_reason = "Unable to resolve after multiple attempts"
117
+ with ready_to_escalate = True
118
+
119
+ # ============================================================
120
+ # PRE-ESCALATION TOPIC (Gather Context)
121
+ # ============================================================
122
+
123
+ topic pre_escalation:
124
+ description: "Gather information before escalating"
125
+ reasoning:
126
+ instructions: ->
127
+ # Ensure we have customer name for personalization
128
+ if @variables.customer_name == "":
129
+ | Before I transfer you, may I have your name so the specialist can address you properly?
130
+ else:
131
+ | Thank you, {!@variables.customer_name}. Let me prepare the transfer.
132
+
133
+ # Display summary of what we'll share
134
+ if @variables.customer_name != "" and @variables.customer_issue != "":
135
+ | I'll share the following with the specialist:
136
+ | - Your issue: {!@variables.customer_issue}
137
+ | - Category: {!@variables.issue_category}
138
+ | - Reason for transfer: {!@variables.escalation_reason}
139
+ |
140
+ | Ready to connect you now.
141
+ transition to @topic.escalation
142
+
143
+ actions:
144
+ # Capture customer name
145
+ save_name: @utils.setVariables
146
+ description: "Save customer name"
147
+ available when @variables.customer_name == ""
148
+ with customer_name = ... # LLM extracts name from response
149
+
150
+ # Proceed to escalation
151
+ proceed: @utils.transition to @topic.escalation
152
+ description: "Proceed with transfer"
153
+ available when @variables.customer_name != ""
154
+
155
+ # Cancel escalation
156
+ cancel_escalation: @utils.setVariables
157
+ description: "Actually, let me try again with the bot"
158
+ with ready_to_escalate = False
159
+ with escalation_reason = ""
160
+ run @utils.transition to @topic.support
161
+
162
+ # ============================================================
163
+ # ESCALATION TOPIC (Handoff)
164
+ # ============================================================
165
+
166
+ topic escalation:
167
+ description: "Execute escalation to human agent"
168
+ reasoning:
169
+ instructions: ->
170
+ # Log escalation context (this gets passed to human agent)
171
+ run @actions.Log_Escalation_Context
172
+ with customer_name = @variables.customer_name
173
+ with issue_summary = @variables.customer_issue
174
+ with category = @variables.issue_category
175
+ with reason = @variables.escalation_reason
176
+ with attempt_count = @variables.attempts_before_escalation
177
+
178
+ | Transferring you now. Thank you for your patience!
179
+
180
+ actions:
181
+ # The actual escalation - uses connection block configuration
182
+ handoff: @utils.escalate
183
+ description: "Transfer to human agent"
184
+
185
+ # ============================================================
186
+ # OPTIONAL: SPECIALIZED ESCALATION QUEUES
187
+ # ============================================================
188
+
189
+ topic escalate_billing:
190
+ description: "Escalate specifically to billing team"
191
+ reasoning:
192
+ instructions: |
193
+ I'm connecting you with our billing specialists.
194
+ They'll be able to help with your account questions.
195
+ actions:
196
+ # Note: In production, you'd configure this action
197
+ # to route to a specific billing queue
198
+ billing_handoff: @utils.escalate
199
+ description: "Transfer to billing team"
200
+
201
+ topic escalate_technical:
202
+ description: "Escalate specifically to technical support"
203
+ reasoning:
204
+ instructions: |
205
+ I'm connecting you with our technical support team.
206
+ They specialize in resolving complex technical issues.
207
+ actions:
208
+ tech_handoff: @utils.escalate
209
+ description: "Transfer to technical support"
@@ -0,0 +1,115 @@
1
+ # Flow Action Lookup Template
2
+ # ============================
3
+ #
4
+ # This template demonstrates the pattern for calling Flow actions
5
+ # that return complex data types (SObjects, lists, custom types).
6
+ #
7
+ # Pattern: Data lookup and display using Flow actions
8
+ # Use when: Fetching records from Salesforce (Cases, Orders, Accounts)
9
+ #
10
+ # CRITICAL: When defining Flow action outputs in Agentforce Assets:
11
+ # - For SObject returns: complex_data_type_name = "lightning__recordInfoType"
12
+ # - For list[string]: complex_data_type_name = "lightning__textType"
13
+ # - For currency: complex_data_type_name = "lightning__currencyType"
14
+
15
+ system:
16
+ messages:
17
+ welcome: "Hello! I can help you look up order information."
18
+ error: "I apologize, something went wrong retrieving your data."
19
+ instructions: "You are a customer service agent helping users look up their orders."
20
+
21
+ config:
22
+ agent_name: "FlowActionLookupAgent"
23
+ agent_label: "Order Lookup Agent"
24
+ description: "Agent demonstrating Flow action patterns with complex data types"
25
+ default_agent_user: "agent@yourorg.com" # REQUIRED: Change to valid Einstein Agent User
26
+
27
+ variables:
28
+ # Customer context (from session)
29
+ customer_id: linked string
30
+ source: @session.customerId
31
+ description: "Customer ID from session context"
32
+
33
+ # Order data (populated by Flow action)
34
+ order_id: mutable string = ""
35
+ description: "Current order being viewed"
36
+ order_status: mutable string = ""
37
+ description: "Order status from lookup"
38
+ order_total: mutable string = ""
39
+ description: "Order total amount"
40
+ order_date: mutable string = ""
41
+ description: "Order date"
42
+
43
+ # Error handling
44
+ lookup_error: mutable boolean = False
45
+ description: "Whether lookup encountered an error"
46
+
47
+ start_agent entry:
48
+ description: "Entry point - welcome and route to order lookup"
49
+ reasoning:
50
+ instructions: |
51
+ Welcome the customer and offer to help with order lookups.
52
+ actions:
53
+ go_lookup: @utils.transition to @topic.order_lookup
54
+ description: "Start order lookup"
55
+
56
+ # ============================================================
57
+ # ORDER LOOKUP TOPIC (Flow Action Pattern)
58
+ # ============================================================
59
+
60
+ topic order_lookup:
61
+ description: "Look up order details using Flow action"
62
+ reasoning:
63
+ instructions: ->
64
+ # POST-ACTION CHECK: Display results if order was found
65
+ if @variables.order_status != "":
66
+ | **Order Details**
67
+ | - Order ID: {!@variables.order_id}
68
+ | - Status: {!@variables.order_status}
69
+ | - Total: {!@variables.order_total}
70
+ | - Date: {!@variables.order_date}
71
+ |
72
+ | Is there anything else you'd like to know about this order?
73
+
74
+ # ERROR CHECK: Handle lookup failures
75
+ if @variables.lookup_error == True:
76
+ | I couldn't find that order. Please check the order ID and try again.
77
+ set @variables.lookup_error = False
78
+
79
+ # INITIAL STATE: Ask for order ID
80
+ if @variables.order_id == "":
81
+ | What order would you like me to look up?
82
+ | Please provide your order ID.
83
+
84
+ actions:
85
+ # Flow action with SObject return type
86
+ # In Agentforce Assets, set outputs.order_record complex_data_type_name = "lightning__recordInfoType"
87
+ lookup_order: @actions.Get_Order_Details
88
+ description: "Look up order by ID"
89
+ with order_id = ... # LLM extracts from user message
90
+ include_in_progress_indicator: True
91
+ progress_indicator_message: "Looking up your order..."
92
+ set @variables.order_id = @outputs.order_id
93
+ set @variables.order_status = @outputs.status
94
+ set @variables.order_total = @outputs.total_amount
95
+ set @variables.order_date = @outputs.order_date
96
+ # Error handling: check if lookup failed
97
+ if @outputs.found == False:
98
+ set @variables.lookup_error = True
99
+
100
+ # Flow action returning a list of strings
101
+ # In Agentforce Assets, set outputs.product_names complex_data_type_name = "lightning__textType"
102
+ get_items: @actions.Get_Order_Line_Items
103
+ description: "Get list of items in the order"
104
+ available when @variables.order_id != ""
105
+ with order_id = @variables.order_id
106
+
107
+ clear_search: @utils.setVariables
108
+ description: "Search for a different order"
109
+ with order_id = ""
110
+ with order_status = ""
111
+ with order_total = ""
112
+ with order_date = ""
113
+
114
+ escalate_now: @utils.escalate
115
+ description: "Transfer to human agent"
@@ -0,0 +1,104 @@
1
+ # Hub-and-Spoke Architecture Template
2
+ # ====================================
3
+ #
4
+ # This template demonstrates the Hub-and-Spoke pattern where a central
5
+ # topic_selector (hub) routes conversations to specialized topics (spokes).
6
+ #
7
+ # Pattern: Multi-purpose agents handling distinct request types
8
+ # Use when: Users may have different intents (orders, support, returns)
9
+
10
+ system:
11
+ messages:
12
+ welcome: "Welcome! I can help with orders, returns, or general support."
13
+ error: "I apologize, something went wrong. Let me try again."
14
+ instructions: "You are a customer service agent for an e-commerce company."
15
+
16
+ config:
17
+ agent_name: "HubAndSpokeAgent"
18
+ agent_label: "Customer Service Agent"
19
+ description: "Multi-purpose agent with hub-and-spoke architecture"
20
+ default_agent_user: "agent@yourorg.com" # REQUIRED: Change to valid Einstein Agent User
21
+
22
+ variables:
23
+ customer_id: linked string
24
+ source: @session.customerId
25
+ description: "Customer ID from session"
26
+ order_id: mutable string = ""
27
+ description: "Current order being discussed"
28
+ issue_resolved: mutable boolean = False
29
+ description: "Whether the issue has been resolved"
30
+
31
+ # ============================================================
32
+ # HUB: Central Router
33
+ # ============================================================
34
+
35
+ start_agent topic_selector:
36
+ description: "Route to appropriate topic based on user intent"
37
+ reasoning:
38
+ instructions: |
39
+ Determine what the customer needs and route accordingly:
40
+ - Order questions → orders topic
41
+ - Return/refund requests → returns topic
42
+ - General questions → support topic
43
+ actions:
44
+ check_order: @utils.transition to @topic.orders
45
+ description: "Customer wants to check order status"
46
+ process_return: @utils.transition to @topic.returns
47
+ description: "Customer wants to return or refund"
48
+ general_help: @utils.transition to @topic.support
49
+ description: "General support questions"
50
+
51
+ # ============================================================
52
+ # SPOKE: Orders Topic
53
+ # ============================================================
54
+
55
+ topic orders:
56
+ description: "Handle order status and tracking inquiries"
57
+ reasoning:
58
+ instructions: ->
59
+ | Help the customer with their order inquiry.
60
+
61
+ if @variables.order_id != "":
62
+ | Current order: {!@variables.order_id}
63
+
64
+ actions:
65
+ lookup_order: @actions.get_order_status
66
+ description: "Look up order details"
67
+ with order_id = @variables.order_id
68
+ back_to_hub: @utils.transition to @topic.topic_selector
69
+ description: "Return to main menu"
70
+
71
+ # ============================================================
72
+ # SPOKE: Returns Topic
73
+ # ============================================================
74
+
75
+ topic returns:
76
+ description: "Handle return and refund requests"
77
+ reasoning:
78
+ instructions: ->
79
+ | Help the customer with their return or refund request.
80
+ | Verify the order details before processing.
81
+
82
+ actions:
83
+ start_return: @actions.initiate_return
84
+ description: "Start a return process"
85
+ process_refund: @actions.process_refund
86
+ description: "Process a refund"
87
+ back_to_hub: @utils.transition to @topic.topic_selector
88
+ description: "Return to main menu"
89
+
90
+ # ============================================================
91
+ # SPOKE: Support Topic
92
+ # ============================================================
93
+
94
+ topic support:
95
+ description: "Handle general support questions"
96
+ reasoning:
97
+ instructions: |
98
+ Help the customer with general questions.
99
+ If the question requires specialized help, route appropriately.
100
+ actions:
101
+ escalate: @utils.escalate
102
+ description: "Transfer to human agent"
103
+ back_to_hub: @utils.transition to @topic.topic_selector
104
+ description: "Return to main menu"
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Invocable Apex template for Agent Script action backing logic.
3
+ *
4
+ * Wire this class to an Agent Script action with:
5
+ * target: "apex://{{ClassName}}"
6
+ *
7
+ * The @InvocableVariable field names on Request and Result become the
8
+ * action's input and output names in the .agent file. They must match
9
+ * character-for-character — including case.
10
+ *
11
+ * STUB USAGE: To create a minimal stub for unblocking deployment,
12
+ * delete the business logic in execute() and return hardcoded values.
13
+ * Do not add mock data, conditional logic, or JSON serialization to
14
+ * stubs — keep them minimal.
15
+ *
16
+ * Replace all {{placeholders}} before use.
17
+ */
18
+ public with sharing class {{ClassName}} {
19
+
20
+ // ─── INVOCABLE METHOD ────────────────────────────────────────────
21
+ //
22
+ // Must be: static, accept List<Request>, return List<Result>.
23
+ // This signature supports bulkification when the action is called
24
+ // for multiple records in a single transaction.
25
+
26
+ @InvocableMethod(
27
+ label='{{ActionLabel}}'
28
+ description='{{ActionDescription}}'
29
+ )
30
+ public static List<Result> execute(List<Request> requests) {
31
+ List<Result> results = new List<Result>();
32
+
33
+ // ── Bulkification: collect IDs first, query once ──
34
+ // Avoids SOQL-in-loop governor limit issues.
35
+ Set<Id> recordIds = new Set<Id>();
36
+ for (Request req : requests) {
37
+ if (req.recordId != null) {
38
+ recordIds.add(req.recordId);
39
+ }
40
+ }
41
+
42
+ // ── USER_MODE ──
43
+ // `USER_MODE` enforces the running user's FLS/CRUD permissions.
44
+ // For service agents, the running user is the Einstein Agent User.
45
+ // If the user lacks read access to queried objects, queries return
46
+ // 0 rows with NO error — a silent failure. Verify object permissions
47
+ // before relying on `USER_MODE` queries.
48
+
49
+ // Static SOQL (Preferred): Use `WITH USER_MODE` clause:
50
+ Map<Id, {{SObjectName}}> recordsById = new Map<Id, {{SObjectName}}>();
51
+ if (!recordIds.isEmpty()) {
52
+ recordsById = new Map<Id, {{SObjectName}}>(
53
+ [SELECT Id, Name
54
+ FROM {{SObjectName}}
55
+ WHERE Id IN :recordIds
56
+ WITH USER_MODE]
57
+ );
58
+ }
59
+
60
+ // Dynamic SOQL (Optional): Use `AccessLevel.USER_MODE` parameter. DO NOT use `WITH USER_MODE` clause!
61
+ // WARNING! `WITH USER_MODE` inside a dynamic string causes:
62
+ // System.QueryException: unexpected token: 'WITH'
63
+ //
64
+ // WRONG:
65
+ // String q = 'SELECT Id, Name FROM {{SObjectName}} WHERE Id IN :recordIds WITH USER_MODE';
66
+ // recordsById = new Map<Id, {{SObjectName}}>(Database.query(q));
67
+ //
68
+ // RIGHT:
69
+ // String q = 'SELECT Id, Name FROM {{SObjectName}} WHERE Id IN :recordIds';
70
+ // recordsById = new Map<Id, {{SObjectName}}>(Database.query(q, AccessLevel.USER_MODE));
71
+
72
+ // ── Process each request ──
73
+ for (Request req : requests) {
74
+ Result r = new Result();
75
+ try {
76
+ {{SObjectName}} record = recordsById.get(req.recordId);
77
+ if (record == null) {
78
+ r = errorResult('Record not found: ' + req.recordId);
79
+ } else {
80
+ // TODO: Replace with actual business logic
81
+ r.isSuccess = true;
82
+ r.outputMessage = 'Processed: ' + record.Name;
83
+ r.outputRecordId = record.Id;
84
+ }
85
+ } catch (Exception e) {
86
+ r = errorResult(e.getMessage());
87
+ }
88
+ results.add(r);
89
+ }
90
+
91
+ return results;
92
+ }
93
+
94
+ // ─── REQUEST WRAPPER ─────────────────────────────────────────────
95
+ //
96
+ // Each @InvocableVariable becomes an action input in Agent Script.
97
+ // The field name here must exactly match the input name in the
98
+ // .agent file's action definition.
99
+ //
100
+ // Supported types: Boolean, Date, DateTime, Decimal, Double,
101
+ // Integer, Long, String, Id, Time, SObject types, List<T>
102
+
103
+ public class Request {
104
+ @InvocableVariable(
105
+ label='Record ID'
106
+ description='ID of the record to process'
107
+ required=true
108
+ )
109
+ public Id recordId;
110
+
111
+ @InvocableVariable(
112
+ label='Operation Type'
113
+ description='Type of operation to perform'
114
+ required=false
115
+ )
116
+ public String operationType;
117
+
118
+ @InvocableVariable(
119
+ label='Amount'
120
+ description='Numeric amount for calculations'
121
+ required=false
122
+ )
123
+ public Decimal amount;
124
+ }
125
+
126
+ // ─── RESULT WRAPPER ──────────────────────────────────────────────
127
+ //
128
+ // Each @InvocableVariable becomes an action output in Agent Script.
129
+ // The field name here must exactly match the output name in the
130
+ // .agent file's action definition.
131
+ //
132
+ // Always include isSuccess and errorMessage for consistent error
133
+ // handling. The agent can check isSuccess to decide what to tell
134
+ // the user.
135
+
136
+ public class Result {
137
+ @InvocableVariable(
138
+ label='Is Success'
139
+ description='Whether the operation completed successfully'
140
+ )
141
+ public Boolean isSuccess;
142
+
143
+ @InvocableVariable(
144
+ label='Error Message'
145
+ description='Error message if operation failed'
146
+ )
147
+ public String errorMessage;
148
+
149
+ @InvocableVariable(
150
+ label='Output Message'
151
+ description='Human-readable result for the agent to relay'
152
+ )
153
+ public String outputMessage;
154
+
155
+ @InvocableVariable(
156
+ label='Output Record ID'
157
+ description='ID of the processed or created record'
158
+ )
159
+ public Id outputRecordId;
160
+
161
+ @InvocableVariable(
162
+ label='Output Value'
163
+ description='Primary result value'
164
+ )
165
+ public String outputValue;
166
+
167
+ @InvocableVariable(
168
+ label='Output Amount'
169
+ description='Numeric result for calculations'
170
+ )
171
+ public Decimal outputAmount;
172
+
173
+ }
174
+
175
+ // ── Error factory ──────────────────────────────────────────────────
176
+ //
177
+ // Centralizes error construction so every failure path sets both
178
+ // isSuccess = false and errorMessage consistently. Defined on the
179
+ // outer class because Apex prohibits static methods in inner classes.
180
+
181
+ private static Result errorResult(String message) {
182
+ Result r = new Result();
183
+ r.isSuccess = false;
184
+ r.errorMessage = message;
185
+ return r;
186
+ }
187
+ }