@salesforce/afv-skills 1.6.9 → 1.7.1
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/README.md +28 -23
- package/package.json +1 -1
- package/skills/developing-agentforce/README.md +112 -0
- package/skills/{agentforce-development → developing-agentforce}/SKILL.md +109 -16
- package/skills/{agentforce-development → developing-agentforce}/assets/agents/README.md +2 -2
- package/skills/developing-agentforce/assets/agents/order-service.agent +272 -0
- package/skills/developing-agentforce/assets/agents/verification-gate.agent +280 -0
- package/skills/{agentforce-development → developing-agentforce}/assets/bundle-meta.xml +1 -1
- package/skills/{agentforce-development → developing-agentforce}/references/actions-reference.md +20 -0
- package/skills/{agentforce-development → developing-agentforce}/references/agent-design-and-spec-creation.md +1 -1
- package/skills/{agentforce-development → developing-agentforce}/references/agent-metadata-and-lifecycle.md +3 -3
- package/skills/{agentforce-development → developing-agentforce}/references/agent-script-core-language.md +40 -3
- package/skills/{agentforce-development → developing-agentforce}/references/agent-user-setup.md +60 -57
- package/skills/{agentforce-development → developing-agentforce}/references/agent-validation-and-debugging.md +22 -20
- package/skills/developing-agentforce/references/architecture-patterns.md +158 -0
- package/skills/developing-agentforce/references/complex-data-types.md +57 -0
- package/skills/developing-agentforce/references/deploy-reference.md +134 -0
- package/skills/developing-agentforce/references/discover-reference.md +102 -0
- package/skills/developing-agentforce/references/examples.md +350 -0
- package/skills/developing-agentforce/references/feature-validity.md +43 -0
- package/skills/developing-agentforce/references/instruction-resolution.md +545 -0
- package/skills/{agentforce-development → developing-agentforce}/references/known-issues.md +18 -18
- package/skills/{agentforce-development → developing-agentforce}/references/production-gotchas.md +24 -3
- package/skills/developing-agentforce/references/safety-review-reference.md +145 -0
- package/skills/{agentforce-development → developing-agentforce}/references/salesforce-cli-for-agents.md +9 -7
- package/skills/developing-agentforce/references/scaffold-reference.md +153 -0
- package/skills/developing-agentforce/references/scoring-rubric.md +24 -0
- package/skills/{agentforce-development → developing-agentforce}/references/version-history.md +2 -2
- package/skills/generating-flow/SKILL.md +3 -1
- package/skills/observing-agentforce/SKILL.md +368 -0
- package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls +1262 -0
- package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls-meta.xml +5 -0
- package/skills/observing-agentforce/references/improve-reference.md +359 -0
- package/skills/observing-agentforce/references/issue-classification.md +220 -0
- package/skills/observing-agentforce/references/reproduce-reference.md +131 -0
- package/skills/observing-agentforce/references/stdm-queries.md +381 -0
- package/skills/observing-agentforce/references/stdm-schema.md +189 -0
- package/skills/testing-agentforce/SKILL.md +335 -0
- package/skills/testing-agentforce/assets/basic-test-spec.yaml +59 -0
- package/skills/testing-agentforce/assets/guardrail-test-spec.yaml +101 -0
- package/skills/testing-agentforce/assets/standard-test-spec.yaml +123 -0
- package/skills/testing-agentforce/references/action-execution.md +241 -0
- package/skills/testing-agentforce/references/batch-testing.md +274 -0
- package/skills/testing-agentforce/references/preview-testing.md +353 -0
- package/skills/testing-agentforce/references/test-report-format.md +160 -0
- package/skills/testing-agentforce/references/troubleshooting.md +73 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/README-legacy.md +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/agent-spec-template.md +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/agents/hello-world.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/agents/multi-topic.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/agents/production-faq.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/agents/production-faq.bundle-meta.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/agents/simple-qa.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/apex/models-api-queueable.cls +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/components/apex-action.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/components/error-handling.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/components/escalation-setup.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/components/flow-action.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/components/n-ary-conditions.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/components/topic-with-actions.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/deterministic-routing.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/escalation-pattern.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/flow-action-lookup.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/hub-and-spoke.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/invocable-apex-template.cls +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/local-info-agent-annotated.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-function-apex.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-function-flow.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-plugin.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/http-callout-flow.flow-meta.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/minimal-starter.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/README.md +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/action-callbacks.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/advanced-input-bindings.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/bidirectional-routing.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/critical-input-collection.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/delegation-routing.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/lifecycle-events.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/llm-controlled-actions.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/multi-step-workflow.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/open-gate-routing.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/procedural-instructions.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/prompt-template-action.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/system-instruction-overrides.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/prompt-rag-search.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/template-multi-topic.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/template-single-topic.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/assets/verification-gate.agent +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/references/action-prompt-templates.md +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/references/agent-access-guide.md +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/references/agent-topic-map-diagrams.md +0 -0
- /package/skills/{agentforce-development → developing-agentforce}/references/minimal-examples.md +0 -0
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
<!-- Parent: adlc-author/SKILL.md -->
|
|
2
|
+
# Instruction Resolution
|
|
3
|
+
|
|
4
|
+
> How Agent Script instructions are processed at runtime: from static text to dynamic LLM prompts.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Three Phases of Instruction Resolution
|
|
9
|
+
|
|
10
|
+
Agent Script instructions go through three distinct phases at runtime. Understanding these phases is critical for writing effective instructions and debugging unexpected behavior.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
Phase 1: Pre-LLM Setup
|
|
14
|
+
(deterministic -- runs before the LLM sees anything)
|
|
15
|
+
|
|
|
16
|
+
v
|
|
17
|
+
Phase 2: LLM Reasoning
|
|
18
|
+
(non-deterministic -- LLM processes the assembled prompt)
|
|
19
|
+
|
|
|
20
|
+
v
|
|
21
|
+
Phase 3: Post-Action Loop
|
|
22
|
+
(deterministic -- runs after an action completes, then loops back to Phase 1)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. Phase 1: Pre-LLM Resolution
|
|
28
|
+
|
|
29
|
+
During Phase 1, the Agent Script runtime evaluates deterministic constructs in `instructions: ->` blocks. This happens BEFORE the LLM sees any text.
|
|
30
|
+
|
|
31
|
+
### What Happens in Phase 1
|
|
32
|
+
|
|
33
|
+
1. **`if`/`else` evaluation**: Conditions are evaluated against current variable values. Only the matching branch is included in the prompt.
|
|
34
|
+
2. **Variable injection**: `{!@variables.X}` tokens are replaced with current values.
|
|
35
|
+
3. **`run` execution**: Deterministic `run @actions.X` calls execute and their outputs are captured.
|
|
36
|
+
4. **`set` execution**: Variable assignments execute immediately.
|
|
37
|
+
5. **`transition to`**: If reached, the topic switch happens immediately (LLM is never called).
|
|
38
|
+
|
|
39
|
+
### Phase 1 Example
|
|
40
|
+
|
|
41
|
+
Given this instruction block:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
reasoning:
|
|
45
|
+
instructions: ->
|
|
46
|
+
# 1. Post-action check (from previous loop)
|
|
47
|
+
if @variables.refund_approved == True:
|
|
48
|
+
| Your refund has been processed. Reference: {!@variables.refund_id}
|
|
49
|
+
transition to @topic.confirmation
|
|
50
|
+
|
|
51
|
+
# 2. Pre-LLM data loading
|
|
52
|
+
if @variables.data_loaded == False:
|
|
53
|
+
run @actions.load_customer_profile
|
|
54
|
+
with customer_id = @variables.customer_id
|
|
55
|
+
set @variables.risk_score = @outputs.risk_score
|
|
56
|
+
set @variables.tier = @outputs.tier
|
|
57
|
+
set @variables.data_loaded = True
|
|
58
|
+
|
|
59
|
+
# 3. Dynamic instructions
|
|
60
|
+
| Customer tier: {!@variables.tier}, Risk score: {!@variables.risk_score}
|
|
61
|
+
|
|
62
|
+
if @variables.risk_score >= 80:
|
|
63
|
+
| HIGH RISK -- Offer full cash refund to retain this customer.
|
|
64
|
+
| Do NOT offer store credit. Prioritize retention.
|
|
65
|
+
|
|
66
|
+
if @variables.risk_score < 80:
|
|
67
|
+
| STANDARD -- Offer $10 store credit as goodwill.
|
|
68
|
+
| Only escalate to cash refund if customer insists.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**First turn resolution** (variables at defaults):
|
|
72
|
+
|
|
73
|
+
- `refund_approved == True` -> False. Skip this block.
|
|
74
|
+
- `data_loaded == False` -> True. Execute `run @actions.load_customer_profile`. Variables now set.
|
|
75
|
+
- Set `data_loaded = True`.
|
|
76
|
+
- Inject `{!@variables.tier}` -> `"gold"`, `{!@variables.risk_score}` -> `85`.
|
|
77
|
+
- `risk_score >= 80` -> True. Include high-risk instructions.
|
|
78
|
+
- `risk_score < 80` -> False. Skip standard instructions.
|
|
79
|
+
|
|
80
|
+
**What the LLM actually sees**:
|
|
81
|
+
```
|
|
82
|
+
Customer tier: gold, Risk score: 85
|
|
83
|
+
HIGH RISK -- Offer full cash refund to retain this customer.
|
|
84
|
+
Do NOT offer store credit. Prioritize retention.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 3. Phase 2: LLM Processing
|
|
90
|
+
|
|
91
|
+
In Phase 2, the LLM receives the assembled prompt and produces a response. The LLM sees:
|
|
92
|
+
|
|
93
|
+
### The 4-Message Prompt Structure
|
|
94
|
+
|
|
95
|
+
The Agent Script runtime assembles a 4-message prompt for the LLM:
|
|
96
|
+
|
|
97
|
+
| # | Message Role | Content Source | Purpose |
|
|
98
|
+
|---|---|---|---|
|
|
99
|
+
| 1 | **System** | `system: instructions:` + agent metadata | Global persona, safety rules, capabilities |
|
|
100
|
+
| 2 | **System** | `topic: reasoning: instructions:` (resolved from Phase 1) | Topic-specific operating instructions |
|
|
101
|
+
| 3 | **User/Assistant** | Conversation history (all turns) | Context for the current request |
|
|
102
|
+
| 4 | **System** | Available actions + their descriptions | Tool palette the LLM can choose from |
|
|
103
|
+
|
|
104
|
+
### What the LLM Decides
|
|
105
|
+
|
|
106
|
+
Based on the assembled prompt, the LLM:
|
|
107
|
+
|
|
108
|
+
1. **Selects an action** (if applicable) from the available actions list
|
|
109
|
+
2. **Fills slot parameters** (`...` values) from conversation context
|
|
110
|
+
3. **Generates a text response** to send to the user
|
|
111
|
+
4. **Decides whether to transition** (if a transition action is available and appropriate)
|
|
112
|
+
|
|
113
|
+
### What the LLM Does NOT See
|
|
114
|
+
|
|
115
|
+
- Raw `if`/`else` blocks (already resolved in Phase 1)
|
|
116
|
+
- `run` statements (already executed in Phase 1)
|
|
117
|
+
- `set` statements (already executed)
|
|
118
|
+
- `available when` conditions (already evaluated -- hidden actions are simply absent)
|
|
119
|
+
- `after_reasoning` blocks (run after the LLM, not shown to it)
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 4. Phase 3: Post-Action Loop
|
|
124
|
+
|
|
125
|
+
After the LLM selects and executes an action, the system loops back to Phase 1 for **re-resolution**. This is the post-action loop pattern described in the SKILL.md architecture section.
|
|
126
|
+
|
|
127
|
+
### Loop Sequence
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
1. Phase 1 resolves instructions (first time)
|
|
131
|
+
2. Phase 2: LLM reasons and selects an action
|
|
132
|
+
3. Action executes -> outputs captured in variables
|
|
133
|
+
4. Phase 1 re-resolves instructions (with updated variables)
|
|
134
|
+
- Post-action checks at TOP of instructions fire
|
|
135
|
+
- New data is injected into the prompt
|
|
136
|
+
5. Phase 2: LLM reasons again with updated context
|
|
137
|
+
6. Repeat until: transition, escalation, or no action selected
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Why Post-Action Checks Go at the TOP
|
|
141
|
+
|
|
142
|
+
Place post-action checks at the TOP of `instructions: ->` so they fire immediately on re-resolution:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
reasoning:
|
|
146
|
+
instructions: ->
|
|
147
|
+
# POST-ACTION CHECK (at TOP -- fires on re-resolution)
|
|
148
|
+
if @variables.order_cancelled == True:
|
|
149
|
+
| Your order has been cancelled successfully.
|
|
150
|
+
transition to @topic.confirmation
|
|
151
|
+
|
|
152
|
+
# These instructions are for the FIRST entry (before action runs)
|
|
153
|
+
| I can help you cancel your order.
|
|
154
|
+
| What is your order number?
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If the check were at the BOTTOM, the LLM would see the "ask for order number" instructions again even after the cancellation succeeded, causing confusion.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 5. Recommended Instruction Order
|
|
162
|
+
|
|
163
|
+
Within a `instructions: ->` block, follow this order for maximum clarity:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
reasoning:
|
|
167
|
+
instructions: ->
|
|
168
|
+
# 1. POST-ACTION CHECKS (deterministic transitions)
|
|
169
|
+
if @variables.action_completed == True:
|
|
170
|
+
transition to @topic.next_step
|
|
171
|
+
|
|
172
|
+
# 2. PRE-LLM DATA LOADING (deterministic actions)
|
|
173
|
+
if @variables.data_needed == True:
|
|
174
|
+
run @actions.load_data
|
|
175
|
+
with id = @variables.record_id
|
|
176
|
+
set @variables.loaded_data = @outputs.result
|
|
177
|
+
|
|
178
|
+
# 3. CONDITIONAL INSTRUCTIONS (based on state)
|
|
179
|
+
if @variables.is_verified == True:
|
|
180
|
+
| Full access granted. You can:
|
|
181
|
+
| - View account details
|
|
182
|
+
| - Make changes
|
|
183
|
+
| - Request refunds
|
|
184
|
+
|
|
185
|
+
if @variables.is_verified == False:
|
|
186
|
+
| Please verify your identity first.
|
|
187
|
+
| I need your email address and order number.
|
|
188
|
+
|
|
189
|
+
# 4. STATIC INSTRUCTIONS (always included)
|
|
190
|
+
| Be concise and professional.
|
|
191
|
+
| Always confirm before making changes.
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 6. Common Instruction Patterns
|
|
197
|
+
|
|
198
|
+
### Pattern 1: Security Gate
|
|
199
|
+
|
|
200
|
+
Prevent access to sensitive actions until identity is verified:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
reasoning:
|
|
204
|
+
instructions: ->
|
|
205
|
+
if @variables.is_verified == False:
|
|
206
|
+
| You must verify your identity before I can help with account changes.
|
|
207
|
+
| Please provide your email address.
|
|
208
|
+
|
|
209
|
+
if @variables.is_verified == True:
|
|
210
|
+
| Identity verified. I can now help with account changes.
|
|
211
|
+
| What would you like to do?
|
|
212
|
+
|
|
213
|
+
actions:
|
|
214
|
+
update_account: @actions.update_account_info
|
|
215
|
+
description: "Update account information"
|
|
216
|
+
available when @variables.is_verified == True
|
|
217
|
+
with field = ...
|
|
218
|
+
with value = ...
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The `available when` guard hides the action from the LLM until verification passes. The conditional instructions tell the user what to do.
|
|
222
|
+
|
|
223
|
+
### Pattern 2: Data-Dependent Instructions
|
|
224
|
+
|
|
225
|
+
Load data first, then tailor instructions based on the result:
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
reasoning:
|
|
229
|
+
instructions: ->
|
|
230
|
+
run @actions.get_account_status
|
|
231
|
+
with account_id = @variables.account_id
|
|
232
|
+
set @variables.account_status = @outputs.status
|
|
233
|
+
set @variables.balance = @outputs.balance
|
|
234
|
+
|
|
235
|
+
| Account status: {!@variables.account_status}
|
|
236
|
+
| Current balance: {!@variables.balance}
|
|
237
|
+
|
|
238
|
+
if @variables.account_status == "delinquent":
|
|
239
|
+
| IMPORTANT: This account is delinquent.
|
|
240
|
+
| Collect payment before processing any other requests.
|
|
241
|
+
| Offer payment plan options if customer cannot pay in full.
|
|
242
|
+
|
|
243
|
+
if @variables.account_status == "active":
|
|
244
|
+
| This account is in good standing.
|
|
245
|
+
| Process requests normally.
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Pattern 3: Action Chaining
|
|
249
|
+
|
|
250
|
+
Execute one action, then use its output to drive the next:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
reasoning:
|
|
254
|
+
instructions: ->
|
|
255
|
+
# Post-action check: case was created in previous loop
|
|
256
|
+
if @variables.case_id != "":
|
|
257
|
+
| Case {!@variables.case_id} has been created.
|
|
258
|
+
run @actions.assign_case
|
|
259
|
+
with case_id = @variables.case_id
|
|
260
|
+
with priority = @variables.priority
|
|
261
|
+
transition to @topic.case_confirmation
|
|
262
|
+
|
|
263
|
+
| I need to collect some information to create a support case.
|
|
264
|
+
| What is the issue you're experiencing?
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Pattern 4: Multi-Condition Routing
|
|
268
|
+
|
|
269
|
+
Route based on multiple variable values:
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
reasoning:
|
|
273
|
+
instructions: ->
|
|
274
|
+
if @variables.intent == "billing" and @variables.is_verified == True:
|
|
275
|
+
| I can help with your billing question.
|
|
276
|
+
transition to @topic.billing_support
|
|
277
|
+
|
|
278
|
+
if @variables.intent == "billing" and @variables.is_verified == False:
|
|
279
|
+
| For billing questions, I need to verify your identity first.
|
|
280
|
+
transition to @topic.identity_verification
|
|
281
|
+
|
|
282
|
+
if @variables.intent == "general":
|
|
283
|
+
| How can I help you today?
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## 7. Anti-Patterns to Avoid
|
|
289
|
+
|
|
290
|
+
### Anti-Pattern 1: Nested If Blocks
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
# WRONG -- Agent Script does not support nested if or else if
|
|
294
|
+
if @variables.tier == "gold":
|
|
295
|
+
if @variables.is_verified == True:
|
|
296
|
+
| VIP treatment
|
|
297
|
+
else:
|
|
298
|
+
| Verify first
|
|
299
|
+
|
|
300
|
+
# CORRECT -- Use compound conditions
|
|
301
|
+
if @variables.tier == "gold" and @variables.is_verified == True:
|
|
302
|
+
| VIP treatment
|
|
303
|
+
|
|
304
|
+
if @variables.tier == "gold" and @variables.is_verified == False:
|
|
305
|
+
| Verify first
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Anti-Pattern 2: Post-Action Check at Bottom
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
# WRONG -- Check at bottom; LLM sees stale instructions on re-resolution
|
|
312
|
+
reasoning:
|
|
313
|
+
instructions: ->
|
|
314
|
+
| What is your order number?
|
|
315
|
+
|
|
316
|
+
if @variables.order_status != "":
|
|
317
|
+
transition to @topic.show_status
|
|
318
|
+
|
|
319
|
+
# CORRECT -- Check at TOP
|
|
320
|
+
reasoning:
|
|
321
|
+
instructions: ->
|
|
322
|
+
if @variables.order_status != "":
|
|
323
|
+
transition to @topic.show_status
|
|
324
|
+
|
|
325
|
+
| What is your order number?
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Anti-Pattern 3: Persona in Topic Instructions
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
# WRONG -- Persona text duplicated in every topic
|
|
332
|
+
reasoning:
|
|
333
|
+
instructions: |
|
|
334
|
+
You are a friendly, professional customer service agent.
|
|
335
|
+
Help the customer with their order.
|
|
336
|
+
|
|
337
|
+
# CORRECT -- Persona in system instructions, topic has operational instructions only
|
|
338
|
+
system:
|
|
339
|
+
instructions: |
|
|
340
|
+
You are a friendly, professional customer service agent.
|
|
341
|
+
|
|
342
|
+
topic order_support:
|
|
343
|
+
reasoning:
|
|
344
|
+
instructions: ->
|
|
345
|
+
| Help the customer check their order status.
|
|
346
|
+
| Ask for the order number if not provided.
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Anti-Pattern 4: Using `|` When `->` Is Needed
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
# WRONG -- Using literal mode when conditionals are needed
|
|
353
|
+
reasoning:
|
|
354
|
+
instructions: |
|
|
355
|
+
if @variables.is_verified == True:
|
|
356
|
+
Show account details.
|
|
357
|
+
|
|
358
|
+
# The above sends the literal text "if @variables.is_verified == True:" to the LLM!
|
|
359
|
+
|
|
360
|
+
# CORRECT -- Use procedural mode for conditionals
|
|
361
|
+
reasoning:
|
|
362
|
+
instructions: ->
|
|
363
|
+
if @variables.is_verified == True:
|
|
364
|
+
| Show account details.
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Anti-Pattern 5: Missing Variable Injection Syntax
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
# WRONG -- Variable name as literal text
|
|
371
|
+
reasoning:
|
|
372
|
+
instructions: ->
|
|
373
|
+
| Your order ID is @variables.order_id
|
|
374
|
+
|
|
375
|
+
# CORRECT -- Use injection syntax
|
|
376
|
+
reasoning:
|
|
377
|
+
instructions: ->
|
|
378
|
+
| Your order ID is {!@variables.order_id}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Anti-Pattern 6: `run` Inside `after_reasoning`
|
|
382
|
+
|
|
383
|
+
While `run` compiles inside `after_reasoning:`, its runtime behavior is inconsistent across bundle types. Prefer using `run` in `reasoning: instructions: ->` or `reasoning: actions:` instead.
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
# RISKY -- run in after_reasoning has inconsistent behavior
|
|
387
|
+
after_reasoning:
|
|
388
|
+
run @actions.log_event
|
|
389
|
+
with event = "turn_completed"
|
|
390
|
+
|
|
391
|
+
# SAFER -- Use instructions: -> for deterministic runs
|
|
392
|
+
reasoning:
|
|
393
|
+
instructions: ->
|
|
394
|
+
# Post-action logging
|
|
395
|
+
if @variables.last_action != "":
|
|
396
|
+
run @actions.log_event
|
|
397
|
+
with event = @variables.last_action
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## 8. Syntax Patterns Reference
|
|
403
|
+
|
|
404
|
+
### Literal Mode (`|`)
|
|
405
|
+
|
|
406
|
+
Static text passed directly to the LLM. No evaluation occurs:
|
|
407
|
+
|
|
408
|
+
```
|
|
409
|
+
instructions: |
|
|
410
|
+
Help the customer with their order.
|
|
411
|
+
Be professional and concise.
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Or with the `|` prefix on each line (inside procedural mode):
|
|
415
|
+
|
|
416
|
+
```
|
|
417
|
+
instructions: ->
|
|
418
|
+
| Help the customer with their order.
|
|
419
|
+
| Be professional and concise.
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Procedural Mode (`->`)
|
|
423
|
+
|
|
424
|
+
Enables conditionals, variable injection, and deterministic actions:
|
|
425
|
+
|
|
426
|
+
```
|
|
427
|
+
instructions: ->
|
|
428
|
+
if @variables.condition == True:
|
|
429
|
+
| Text shown when condition is true.
|
|
430
|
+
else:
|
|
431
|
+
| Text shown when condition is false.
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Variable Injection
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
| Your order {!@variables.order_id} is {!@variables.status}.
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Deterministic Run
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
run @actions.load_data
|
|
444
|
+
with param = @variables.value
|
|
445
|
+
set @variables.result = @outputs.field
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Deterministic Set
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
set @variables.counter = @variables.counter + 1
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Deterministic Transition
|
|
455
|
+
|
|
456
|
+
```
|
|
457
|
+
transition to @topic.next_topic
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Conditional Transition
|
|
461
|
+
|
|
462
|
+
```
|
|
463
|
+
if @variables.all_collected == True:
|
|
464
|
+
transition to @topic.confirmation
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 9. Programmatic Trace Access
|
|
470
|
+
|
|
471
|
+
To verify how instructions were resolved at runtime, use the trace files generated by `sf agent preview`.
|
|
472
|
+
|
|
473
|
+
### Trace File Location
|
|
474
|
+
|
|
475
|
+
```
|
|
476
|
+
.sfdx/agents/{BundleName}/sessions/{sessionId}/traces/{planId}.json
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Reading Instruction Resolution from Traces
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
# Extract the resolved instructions that the LLM received
|
|
483
|
+
jq -r '.planTrace.steps[] | select(.type == "LLM_STEP") | .input' \
|
|
484
|
+
~/.sf/sfdx/agents/MyAgent/sessions/*/traces/*.json
|
|
485
|
+
|
|
486
|
+
# Extract the LLM's response
|
|
487
|
+
jq -r '.planTrace.steps[] | select(.type == "LLM_STEP") | .output' \
|
|
488
|
+
~/.sf/sfdx/agents/MyAgent/sessions/*/traces/*.json
|
|
489
|
+
|
|
490
|
+
# Check which variables were set during resolution
|
|
491
|
+
jq -r '.planTrace.steps[] | select(.type == "ACTION_STEP") | {name: .name, pre: .preVars, post: .postVars}' \
|
|
492
|
+
~/.sf/sfdx/agents/MyAgent/sessions/*/traces/*.json
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Verifying Phase 1 Resolution
|
|
496
|
+
|
|
497
|
+
To confirm that `if`/`else` blocks resolved correctly, compare the trace's `LLM_STEP` input against your `instructions: ->` block. The LLM input should contain only the branches that matched, with all `{!@variables.X}` tokens replaced with actual values.
|
|
498
|
+
|
|
499
|
+
If the trace shows unexpected instruction text:
|
|
500
|
+
1. Check that you used `->` mode (not `|` mode) when conditionals are present
|
|
501
|
+
2. Verify variable values at the time of resolution (check `preVars` on preceding `ACTION_STEP`)
|
|
502
|
+
3. Confirm that `if` conditions use the correct comparison operators
|
|
503
|
+
|
|
504
|
+
### Using STDM for Production Trace Analysis
|
|
505
|
+
|
|
506
|
+
For production agents, use the Session Trace Data Model (STDM) in Data Cloud to access trace data programmatically. The STDM captures `LLM_STEP` records with `input` and `output` fields that contain the resolved prompt and LLM response. This is useful for auditing instruction resolution at scale across hundreds of live sessions.
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## 10. Resolution Across Topic Transitions
|
|
511
|
+
|
|
512
|
+
When a topic transition occurs (via `@utils.transition to @topic.X` or `transition to @topic.X`), instruction resolution starts fresh in the new topic:
|
|
513
|
+
|
|
514
|
+
1. The current topic's remaining instructions are NOT processed
|
|
515
|
+
2. The new topic's `before_reasoning:` runs (if present)
|
|
516
|
+
3. The new topic's `reasoning: instructions:` resolves from Phase 1
|
|
517
|
+
4. The LLM receives the new topic's assembled prompt
|
|
518
|
+
|
|
519
|
+
**Important**: Variables persist across transitions. A variable set in Topic A is available in Topic B. This is how you pass data between topics:
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
# Topic A: Collect data
|
|
523
|
+
topic collect_info:
|
|
524
|
+
reasoning:
|
|
525
|
+
instructions: ->
|
|
526
|
+
| Please provide your order number.
|
|
527
|
+
actions:
|
|
528
|
+
capture_order: @actions.get_order_id
|
|
529
|
+
with input = ...
|
|
530
|
+
set @variables.order_id = @outputs.order_id
|
|
531
|
+
|
|
532
|
+
after_reasoning:
|
|
533
|
+
if @variables.order_id != "":
|
|
534
|
+
transition to @topic.process_order
|
|
535
|
+
|
|
536
|
+
# Topic B: Use the data
|
|
537
|
+
topic process_order:
|
|
538
|
+
reasoning:
|
|
539
|
+
instructions: ->
|
|
540
|
+
# order_id is available from Topic A
|
|
541
|
+
| Processing order {!@variables.order_id}...
|
|
542
|
+
run @actions.get_order_details
|
|
543
|
+
with order_id = @variables.order_id
|
|
544
|
+
set @variables.order_status = @outputs.status
|
|
545
|
+
```
|
|
@@ -31,10 +31,10 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
|
|
|
31
31
|
- **Workaround**: Move test definitions to a separate directory outside the main deploy path, or use `--metadata` flag to deploy specific types instead of `--source-dir`.
|
|
32
32
|
```bash
|
|
33
33
|
# Instead of:
|
|
34
|
-
sf project deploy start --source-dir force-app -o TARGET_ORG
|
|
34
|
+
sf project deploy start --json --source-dir force-app -o TARGET_ORG
|
|
35
35
|
|
|
36
36
|
# Use targeted deployment:
|
|
37
|
-
sf project deploy start --metadata AiAuthoringBundle:MyAgent -o TARGET_ORG
|
|
37
|
+
sf project deploy start --json --metadata AiAuthoringBundle:MyAgent -o TARGET_ORG
|
|
38
38
|
```
|
|
39
39
|
- **Open Questions**: Will Salesforce optimize `AiEvaluationDefinition` deploy performance in a future release?
|
|
40
40
|
|
|
@@ -87,9 +87,9 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
|
|
|
87
87
|
sf bot version list
|
|
88
88
|
|
|
89
89
|
# ✅ New commands (for Agent Script):
|
|
90
|
-
sf project retrieve start --metadata Agent:MyAgent
|
|
91
|
-
sf agent validate authoring-bundle --api-name MyAgent
|
|
92
|
-
sf agent publish authoring-bundle --api-name MyAgent
|
|
90
|
+
sf project retrieve start --json --metadata Agent:MyAgent
|
|
91
|
+
sf agent validate authoring-bundle --json --api-name MyAgent
|
|
92
|
+
sf agent publish authoring-bundle --json --api-name MyAgent
|
|
93
93
|
```
|
|
94
94
|
- **Open Questions**: Will Salesforce unify the `sf bot` and `sf agent` command families?
|
|
95
95
|
|
|
@@ -102,14 +102,14 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
|
|
|
102
102
|
- **Symptom**: Tests created in the Agent Testing Center UI cannot be retrieved via `sf project retrieve start`. Old test XML format references `bot`/`version` fields that don't exist in Agent Script. No metadata type or CLI command exists for new-style agent tests.
|
|
103
103
|
- **Root Cause**: The Agent Testing Center was originally built for Einstein Bots. The test metadata schema hasn't been updated for Agent Script's `AiAuthoringBundle` structure. The `AiEvaluationDefinition` type exists but doesn't correspond to the Testing Center's UI-created tests.
|
|
104
104
|
- **Workaround**:
|
|
105
|
-
1. Use YAML test spec files managed in source control (see `/
|
|
105
|
+
1. Use YAML test spec files managed in source control (see `/testing-agentforce` skill)
|
|
106
106
|
2. Treat UI-created tests as ephemeral / org-specific
|
|
107
107
|
3. Use the Connect API directly to run tests programmatically
|
|
108
108
|
- **Open Questions**:
|
|
109
109
|
- Will a new metadata type be introduced for Agent Script tests?
|
|
110
110
|
- Can `AiEvaluationDefinition` be used with Agent Script agents?
|
|
111
111
|
- Is there a roadmap for test portability?
|
|
112
|
-
- **References**: See `references/custom-eval-investigation.md` in `
|
|
112
|
+
- **References**: See `references/custom-eval-investigation.md` in `testing-agentforce` for related findings on custom evaluation data structure issues.
|
|
113
113
|
|
|
114
114
|
---
|
|
115
115
|
|
|
@@ -246,12 +246,12 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
|
|
|
246
246
|
- **Root Cause**: The `connection messaging:` DSL block only generates a `Messaging` plannerSurface during compilation. There is no `connection customerwebclient:` DSL syntax — attempting it causes `ERROR_HTTP_404` on publish. The compiler has no mechanism to auto-generate `CustomerWebClient`.
|
|
247
247
|
- **Impact**: Every publish overwrites the GenAiPlannerBundle, dropping any manually-added `CustomerWebClient` surface. This requires a post-publish patch after EVERY publish.
|
|
248
248
|
- **Workaround — 6-Step Post-Publish Patch Workflow:**
|
|
249
|
-
1. `sf agent publish authoring-bundle --api-name AgentName -o TARGET_ORG
|
|
250
|
-
2. `sf project retrieve start --metadata "GenAiPlannerBundle:AgentName_vNN" -o TARGET_ORG
|
|
249
|
+
1. `sf agent publish authoring-bundle --json --api-name AgentName -o TARGET_ORG` → creates new version (e.g., v22)
|
|
250
|
+
2. `sf project retrieve start --json --metadata "GenAiPlannerBundle:AgentName_vNN" -o TARGET_ORG` → retrieve compiled bundle
|
|
251
251
|
3. Manually add second `<plannerSurfaces>` block to the XML with `<surfaceType>CustomerWebClient</surfaceType>` (copy the existing `Messaging` block, change surfaceType and surface fields)
|
|
252
|
-
4. `sf agent deactivate --api-name AgentName -o TARGET_ORG` → deactivate agent (deploy fails while active)
|
|
253
|
-
5. `sf project deploy start --metadata "GenAiPlannerBundle:AgentName_vNN" -o TARGET_ORG
|
|
254
|
-
6. `sf agent activate --api-name AgentName -o TARGET_ORG` → reactivate agent
|
|
252
|
+
4. `sf agent deactivate --json --api-name AgentName -o TARGET_ORG` → deactivate agent (deploy fails while active)
|
|
253
|
+
5. `sf project deploy start --json --metadata "GenAiPlannerBundle:AgentName_vNN" -o TARGET_ORG` → deploy patched bundle
|
|
254
|
+
6. `sf agent activate --json --api-name AgentName -o TARGET_ORG` → reactivate agent
|
|
255
255
|
- **Patch XML Example:**
|
|
256
256
|
```xml
|
|
257
257
|
<!-- Add this AFTER the existing Messaging plannerSurfaces block -->
|
|
@@ -301,16 +301,16 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
|
|
|
301
301
|
- **Workaround**: Use `sf project retrieve start --metadata "TypeName:ApiName"` instead of SOQL. For querying agent status/versions via SOQL, use `BotDefinition` and `BotVersion` sObjects.
|
|
302
302
|
```bash
|
|
303
303
|
# ❌ WRONG — these are NOT sObjects
|
|
304
|
-
sf data query --query "SELECT Id FROM GenAiPlannerBundle" -o ORG
|
|
305
|
-
sf data query --query "SELECT Id FROM AiAuthoringBundle" -o ORG
|
|
304
|
+
sf data query --json --query "SELECT Id FROM GenAiPlannerBundle" -o ORG
|
|
305
|
+
sf data query --json --query "SELECT Id FROM AiAuthoringBundle" -o ORG
|
|
306
306
|
|
|
307
307
|
# ✅ CORRECT — use Metadata API
|
|
308
|
-
sf project retrieve start --metadata "GenAiPlannerBundle:MyAgent_v1" -o ORG
|
|
309
|
-
sf project retrieve start --metadata "AiAuthoringBundle:MyAgent" -o ORG
|
|
308
|
+
sf project retrieve start --json --metadata "GenAiPlannerBundle:MyAgent_v1" -o ORG
|
|
309
|
+
sf project retrieve start --json --metadata "AiAuthoringBundle:MyAgent" -o ORG
|
|
310
310
|
|
|
311
311
|
# ✅ CORRECT — query sObjects for agent info
|
|
312
|
-
sf data query --query "SELECT Id, DeveloperName FROM BotDefinition WHERE DeveloperName = 'MyAgent'" -o ORG
|
|
313
|
-
sf data query --query "SELECT Id, VersionNumber, Status FROM BotVersion WHERE BotDefinition.DeveloperName = 'MyAgent'" -o ORG
|
|
312
|
+
sf data query --json --query "SELECT Id, DeveloperName FROM BotDefinition WHERE DeveloperName = 'MyAgent'" -o ORG
|
|
313
|
+
sf data query --json --query "SELECT Id, VersionNumber, Status FROM BotVersion WHERE BotDefinition.DeveloperName = 'MyAgent'" -o ORG
|
|
314
314
|
```
|
|
315
315
|
- **Open Questions**: None — this is by design.
|
|
316
316
|
|
package/skills/{agentforce-development → developing-agentforce}/references/production-gotchas.md
RENAMED
|
@@ -185,7 +185,7 @@ process_order: @actions.create_order
|
|
|
185
185
|
|
|
186
186
|
KNOWN BUG: Chained actions with Prompt Templates don't properly map inputs using `Input:Query` format.
|
|
187
187
|
|
|
188
|
-
For prompt template action definitions, input binding syntax, and grounded data patterns, see [
|
|
188
|
+
For prompt template action definitions, input binding syntax, and grounded data patterns, see [Action Prompt Templates](action-prompt-templates.md).
|
|
189
189
|
|
|
190
190
|
## Latch Variable Pattern for Topic Re-entry
|
|
191
191
|
|
|
@@ -250,10 +250,31 @@ Failed to retrieve components using source tracking:
|
|
|
250
250
|
[SfError [UnsupportedBundleTypeError]: Unsupported Bundle Type: AiAuthoringBundle
|
|
251
251
|
|
|
252
252
|
# ✅ WORKAROUND - Use CLI directly:
|
|
253
|
-
sf project retrieve start -m AiAuthoringBundle:MyAgent
|
|
254
|
-
sf agent publish authoring-bundle --api-name MyAgent -o TARGET_ORG
|
|
253
|
+
sf project retrieve start --json -m AiAuthoringBundle:MyAgent
|
|
254
|
+
sf agent publish authoring-bundle --json --api-name MyAgent -o TARGET_ORG
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
+
## `@inputs` Scope Lifecycle (Silent Failure)
|
|
258
|
+
|
|
259
|
+
`@inputs` is only available in `with` directives during action invocation. Using `@inputs` in a post-action `set` causes **silent runtime failure** — the action executes but the `set` silently drops, leaving the variable unchanged. No trace error; the FunctionStep shows no output capture.
|
|
260
|
+
|
|
261
|
+
```agentscript
|
|
262
|
+
# WRONG — silent failure, @inputs out of scope after action executes
|
|
263
|
+
run @actions.get_station_status
|
|
264
|
+
with station_name = ...
|
|
265
|
+
set @variables.station = @inputs.station_name # FAILS SILENTLY
|
|
266
|
+
|
|
267
|
+
# RIGHT — use @outputs (if action echoes the value) or capture input before the call
|
|
268
|
+
set @variables.station = @variables.selected_station # capture before
|
|
269
|
+
run @actions.get_station_status
|
|
270
|
+
with station_name = @variables.station
|
|
271
|
+
set @variables.status = @outputs.status # @outputs is valid here
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Diagnosis:** A FunctionStep that completes with no output capture (set directives dropped) indicates an `@inputs` scope violation. The action succeeds — only the assignment fails.
|
|
275
|
+
|
|
276
|
+
Similarly, `@outputs` is only available in `set` and `if` directives immediately following the action invocation — not in instructions, pipe lines, or later actions.
|
|
277
|
+
|
|
257
278
|
## Reserved `@InvocableVariable` Keywords
|
|
258
279
|
|
|
259
280
|
Certain common words cannot be used as `@InvocableVariable` names in Apex classes called by Agent Script. Using them causes "SyntaxError: Unexpected '{keyword}'" during agent script compilation. (Validated March 2026)
|