@salesforce/afv-skills 1.6.8 → 1.7.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 (93) hide show
  1. package/package.json +3 -3
  2. package/skills/developing-agentforce/README.md +112 -0
  3. package/skills/{agentforce-development → developing-agentforce}/SKILL.md +109 -16
  4. package/skills/{agentforce-development → developing-agentforce}/assets/agents/README.md +2 -2
  5. package/skills/developing-agentforce/assets/agents/order-service.agent +272 -0
  6. package/skills/developing-agentforce/assets/agents/verification-gate.agent +280 -0
  7. package/skills/{agentforce-development → developing-agentforce}/assets/bundle-meta.xml +1 -1
  8. package/skills/{agentforce-development → developing-agentforce}/references/actions-reference.md +20 -0
  9. package/skills/{agentforce-development → developing-agentforce}/references/agent-design-and-spec-creation.md +1 -1
  10. package/skills/{agentforce-development → developing-agentforce}/references/agent-metadata-and-lifecycle.md +3 -3
  11. package/skills/{agentforce-development → developing-agentforce}/references/agent-script-core-language.md +40 -3
  12. package/skills/{agentforce-development → developing-agentforce}/references/agent-user-setup.md +60 -57
  13. package/skills/{agentforce-development → developing-agentforce}/references/agent-validation-and-debugging.md +22 -20
  14. package/skills/developing-agentforce/references/architecture-patterns.md +158 -0
  15. package/skills/developing-agentforce/references/complex-data-types.md +57 -0
  16. package/skills/developing-agentforce/references/deploy-reference.md +134 -0
  17. package/skills/developing-agentforce/references/discover-reference.md +102 -0
  18. package/skills/developing-agentforce/references/examples.md +350 -0
  19. package/skills/developing-agentforce/references/feature-validity.md +43 -0
  20. package/skills/developing-agentforce/references/instruction-resolution.md +545 -0
  21. package/skills/{agentforce-development → developing-agentforce}/references/known-issues.md +18 -18
  22. package/skills/{agentforce-development → developing-agentforce}/references/production-gotchas.md +24 -3
  23. package/skills/developing-agentforce/references/safety-review-reference.md +145 -0
  24. package/skills/{agentforce-development → developing-agentforce}/references/salesforce-cli-for-agents.md +9 -7
  25. package/skills/developing-agentforce/references/scaffold-reference.md +153 -0
  26. package/skills/developing-agentforce/references/scoring-rubric.md +24 -0
  27. package/skills/{agentforce-development → developing-agentforce}/references/version-history.md +2 -2
  28. package/skills/generating-ui-bundle-site/SKILL.md +3 -3
  29. package/skills/observing-agentforce/SKILL.md +368 -0
  30. package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls +1262 -0
  31. package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls-meta.xml +5 -0
  32. package/skills/observing-agentforce/references/improve-reference.md +359 -0
  33. package/skills/observing-agentforce/references/issue-classification.md +220 -0
  34. package/skills/observing-agentforce/references/reproduce-reference.md +131 -0
  35. package/skills/observing-agentforce/references/stdm-queries.md +381 -0
  36. package/skills/observing-agentforce/references/stdm-schema.md +189 -0
  37. package/skills/testing-agentforce/SKILL.md +335 -0
  38. package/skills/testing-agentforce/assets/basic-test-spec.yaml +59 -0
  39. package/skills/testing-agentforce/assets/guardrail-test-spec.yaml +101 -0
  40. package/skills/testing-agentforce/assets/standard-test-spec.yaml +123 -0
  41. package/skills/testing-agentforce/references/action-execution.md +241 -0
  42. package/skills/testing-agentforce/references/batch-testing.md +274 -0
  43. package/skills/testing-agentforce/references/preview-testing.md +353 -0
  44. package/skills/testing-agentforce/references/test-report-format.md +160 -0
  45. package/skills/testing-agentforce/references/troubleshooting.md +73 -0
  46. /package/skills/{agentforce-development → developing-agentforce}/assets/README-legacy.md +0 -0
  47. /package/skills/{agentforce-development → developing-agentforce}/assets/agent-spec-template.md +0 -0
  48. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/hello-world.agent +0 -0
  49. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/multi-topic.agent +0 -0
  50. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/production-faq.agent +0 -0
  51. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/production-faq.bundle-meta.xml +0 -0
  52. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/simple-qa.agent +0 -0
  53. /package/skills/{agentforce-development → developing-agentforce}/assets/apex/models-api-queueable.cls +0 -0
  54. /package/skills/{agentforce-development → developing-agentforce}/assets/components/apex-action.agent +0 -0
  55. /package/skills/{agentforce-development → developing-agentforce}/assets/components/error-handling.agent +0 -0
  56. /package/skills/{agentforce-development → developing-agentforce}/assets/components/escalation-setup.agent +0 -0
  57. /package/skills/{agentforce-development → developing-agentforce}/assets/components/flow-action.agent +0 -0
  58. /package/skills/{agentforce-development → developing-agentforce}/assets/components/n-ary-conditions.agent +0 -0
  59. /package/skills/{agentforce-development → developing-agentforce}/assets/components/topic-with-actions.agent +0 -0
  60. /package/skills/{agentforce-development → developing-agentforce}/assets/deterministic-routing.agent +0 -0
  61. /package/skills/{agentforce-development → developing-agentforce}/assets/escalation-pattern.agent +0 -0
  62. /package/skills/{agentforce-development → developing-agentforce}/assets/flow-action-lookup.agent +0 -0
  63. /package/skills/{agentforce-development → developing-agentforce}/assets/hub-and-spoke.agent +0 -0
  64. /package/skills/{agentforce-development → developing-agentforce}/assets/invocable-apex-template.cls +0 -0
  65. /package/skills/{agentforce-development → developing-agentforce}/assets/local-info-agent-annotated.agent +0 -0
  66. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +0 -0
  67. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-function-apex.xml +0 -0
  68. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-function-flow.xml +0 -0
  69. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-plugin.xml +0 -0
  70. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/http-callout-flow.flow-meta.xml +0 -0
  71. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +0 -0
  72. /package/skills/{agentforce-development → developing-agentforce}/assets/minimal-starter.agent +0 -0
  73. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/README.md +0 -0
  74. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/action-callbacks.agent +0 -0
  75. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/advanced-input-bindings.agent +0 -0
  76. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/bidirectional-routing.agent +0 -0
  77. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/critical-input-collection.agent +0 -0
  78. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/delegation-routing.agent +0 -0
  79. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/lifecycle-events.agent +0 -0
  80. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/llm-controlled-actions.agent +0 -0
  81. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/multi-step-workflow.agent +0 -0
  82. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/open-gate-routing.agent +0 -0
  83. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/procedural-instructions.agent +0 -0
  84. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/prompt-template-action.agent +0 -0
  85. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/system-instruction-overrides.agent +0 -0
  86. /package/skills/{agentforce-development → developing-agentforce}/assets/prompt-rag-search.agent +0 -0
  87. /package/skills/{agentforce-development → developing-agentforce}/assets/template-multi-topic.agent +0 -0
  88. /package/skills/{agentforce-development → developing-agentforce}/assets/template-single-topic.agent +0 -0
  89. /package/skills/{agentforce-development → developing-agentforce}/assets/verification-gate.agent +0 -0
  90. /package/skills/{agentforce-development → developing-agentforce}/references/action-prompt-templates.md +0 -0
  91. /package/skills/{agentforce-development → developing-agentforce}/references/agent-access-guide.md +0 -0
  92. /package/skills/{agentforce-development → developing-agentforce}/references/agent-topic-map-diagrams.md +0 -0
  93. /package/skills/{agentforce-development → developing-agentforce}/references/minimal-examples.md +0 -0
@@ -18,7 +18,7 @@ PID_DigitalAgent (typically included with Agentforce licenses)
18
18
  | **`default_agent_user` in config** | Required | Omit entirely |
19
19
  | **Respects Sharing Rules** | No (consistent permissions) | Yes (user's data access) |
20
20
 
21
- **How to check agent type**: Look at the `agent_type` field in the `config:` block of your `.agent` file, or query: `sf data query --query "SELECT DeveloperName, Type FROM BotDefinition WHERE DeveloperName = 'AgentName'" -o TARGET_ORG --json`
21
+ **How to check agent type**: Look at the `agent_type` field in the `config:` block of your `.agent` file, or query: `sf data query --json --query "SELECT DeveloperName, Type FROM BotDefinition WHERE DeveloperName = 'AgentName'" -o TARGET_ORG`
22
22
 
23
23
  ---
24
24
 
@@ -28,18 +28,19 @@ For CLI-first workflow (tested: ~8 minutes total):
28
28
 
29
29
  ```bash
30
30
  # Step 1: Query existing Einstein Agent Users (30 seconds)
31
- sf data query \
31
+ sf data query --json \
32
32
  --query "SELECT Id, Username, IsActive FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true" \
33
- -o TARGET_ORG --json
33
+ -o TARGET_ORG
34
34
 
35
35
  # Step 2: Create Einstein Agent User (2 minutes)
36
- # Get Profile ID
37
- PROFILE_ID=$(sf data query \
36
+ # Get Profile ID (read result.records[0].Id from JSON response)
37
+ sf data query --json \
38
38
  --query "SELECT Id FROM Profile WHERE Name = 'Einstein Agent User'" \
39
- -o TARGET_ORG --json | jq -r '.result.records[0].Id')
39
+ -o TARGET_ORG
40
40
 
41
41
  # For Production/Sandbox (non-scratch org):
42
- sf data create record --sobject User --values \
42
+ # Use the ProfileId from the query above
43
+ sf data create record --json --sobject User --values \
43
44
  "Username=<agent_name>_user@<orgId>.ext \
44
45
  LastName=<AgentName> \
45
46
  Email=admin@example.com \
@@ -47,55 +48,55 @@ sf data create record --sobject User --values \
47
48
  TimeZoneSidKey=America/Los_Angeles \
48
49
  LocaleSidKey=en_US \
49
50
  EmailEncodingKey=UTF-8 \
50
- ProfileId=${PROFILE_ID} \
51
+ ProfileId=<PROFILE_ID> \
51
52
  LanguageLocaleKey=en_US" \
52
- -o TARGET_ORG --json
53
+ -o TARGET_ORG
53
54
 
54
55
  # For Scratch Orgs (use user definition file):
55
56
  # sf org create user --definition-file config/einstein-agent-user.json -o TARGET_ORG
56
57
 
57
58
  # Step 3: Assign System Permission Set (1 minute)
58
- sf org assign permset \
59
+ sf org assign permset --json \
59
60
  --name AgentforceServiceAgentUser \
60
61
  --on-behalf-of <agent_name>_user@<orgId>.ext \
61
- -o TARGET_ORG --json
62
+ -o TARGET_ORG
62
63
 
63
64
  # Step 4: Deploy Custom Permission Set (3 minutes)
64
65
  # (Create the .permissionset-meta.xml file first - see Section 3.2 template)
65
- sf project deploy start \
66
+ sf project deploy start --json \
66
67
  --metadata PermissionSet:<AgentName>_Access \
67
- -o TARGET_ORG --json
68
+ -o TARGET_ORG
68
69
 
69
70
  # Assign custom PS
70
- sf org assign permset \
71
+ sf org assign permset --json \
71
72
  --name <AgentName>_Access \
72
73
  --on-behalf-of <agent_name>_user@<orgId>.ext \
73
- -o TARGET_ORG --json
74
+ -o TARGET_ORG
74
75
 
75
76
  # Step 5: Verify All Permissions (1 minute)
76
- sf data query \
77
+ sf data query --json \
77
78
  --query "SELECT PermissionSet.Name, PermissionSet.Label FROM PermissionSetAssignment WHERE Assignee.Username = '<agent_name>_user@<orgId>.ext' ORDER BY PermissionSet.Name" \
78
- -o TARGET_ORG --json
79
+ -o TARGET_ORG
79
80
 
80
81
  # Expected: AgentforceServiceAgentUser + <AgentName>_Access
81
82
 
82
83
  # Step 6: Deploy Agent Bundle (unpublished metadata)
83
- sf project deploy start \
84
+ sf project deploy start --json \
84
85
  --source-dir force-app/main/default/aiAuthoringBundles/<AgentName> \
85
- -o TARGET_ORG --json
86
+ -o TARGET_ORG
86
87
 
87
88
  # Step 7: Test BEFORE Publishing (recommended)
88
- sf agent preview start \
89
+ sf agent preview start --json \
89
90
  --api-name <AgentName> \
90
- -o TARGET_ORG --json
91
+ -o TARGET_ORG
91
92
  # Test all topics and actions to verify permissions
92
93
 
93
94
  # Step 8: Publish & Activate (only after testing passes)
94
- sf agent publish authoring-bundle \
95
+ sf agent publish authoring-bundle --json \
95
96
  --api-name <AgentName> \
96
- -o TARGET_ORG --json
97
+ -o TARGET_ORG
97
98
 
98
- sf agent activate \
99
+ sf agent activate --json \
99
100
  --api-name <AgentName> \
100
101
  -o TARGET_ORG
101
102
  ```
@@ -118,19 +119,20 @@ Service agents need a dedicated service account with consistent permissions.
118
119
 
119
120
  **Get Org ID first** (needed for username format):
120
121
  ```bash
121
- sf org display -o TARGET_ORG --json | jq -r '.result.id'
122
+ sf org display --json -o TARGET_ORG
123
+ # Read result.id from the JSON response
122
124
  ```
123
125
 
124
126
  **Query existing Einstein Agent Users** (skip creation if one exists):
125
127
  ```bash
126
- sf data query --query "SELECT Id, Username, IsActive FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true" -o TARGET_ORG --json
128
+ sf data query --json --query "SELECT Id, Username, IsActive FROM User WHERE Profile.Name = 'Einstein Agent User' AND IsActive = true" -o TARGET_ORG
127
129
  ```
128
130
 
129
131
  **Create the user** (if none exists):
130
132
 
131
133
  1. Get the Einstein Agent User profile ID:
132
134
  ```bash
133
- sf data query --query "SELECT Id FROM Profile WHERE Name = 'Einstein Agent User'" -o TARGET_ORG --json
135
+ sf data query --json --query "SELECT Id FROM Profile WHERE Name = 'Einstein Agent User'" -o TARGET_ORG
134
136
  ```
135
137
 
136
138
  2. Create a user definition file (`config/einstein-agent-user.json`):
@@ -153,7 +155,7 @@ sf data query --query "SELECT Id, Username, IsActive FROM User WHERE Profile.Nam
153
155
 
154
156
  **Option A: Scratch Org (Definition File)**
155
157
  ```bash
156
- sf org create user \
158
+ sf org create user --json \
157
159
  --definition-file config/einstein-agent-user.json \
158
160
  -o TARGET_ORG
159
161
  ```
@@ -161,21 +163,22 @@ sf data query --query "SELECT Id, Username, IsActive FROM User WHERE Profile.Nam
161
163
  **Option B: Production/Sandbox (Direct Record Creation)**
162
164
  ```bash
163
165
  # Get Profile ID first
164
- PROFILE_ID=$(sf data query \
166
+ # Get Profile ID (read result.records[0].Id from JSON response)
167
+ sf data query --json \
165
168
  --query "SELECT Id FROM Profile WHERE Name = 'Einstein Agent User'" \
166
- -o TARGET_ORG --json | jq -r '.result.records[0].Id')
169
+ -o TARGET_ORG
167
170
 
168
- # Create user directly
169
- sf data create record --sobject User --values \
170
- "Username='{agent_name}_agent@{orgId}.ext' LastName='{AgentName} Agent' Email='placeholder@example.com' Alias='agntuser' ProfileId='${PROFILE_ID}' TimeZoneSidKey='America/Los_Angeles' LocaleSidKey='en_US' EmailEncodingKey='UTF-8' LanguageLocaleKey='en_US'" \
171
- -o TARGET_ORG --json
171
+ # Create user directly (use ProfileId from query above)
172
+ sf data create record --json --sobject User --values \
173
+ "Username='{agent_name}_agent@{orgId}.ext' LastName='{AgentName} Agent' Email='placeholder@example.com' Alias='agntuser' ProfileId='<PROFILE_ID>' TimeZoneSidKey='America/Los_Angeles' LocaleSidKey='en_US' EmailEncodingKey='UTF-8' LanguageLocaleKey='en_US'" \
174
+ -o TARGET_ORG
172
175
  ```
173
176
 
174
177
  **Note**: `sf org create user` only works in scratch orgs. For production/sandbox, use `sf data create record`. Attempting `sf org create user` in a non-scratch org fails with an authorization error.
175
178
 
176
179
  4. Verify creation:
177
180
  ```bash
178
- sf data query --query "SELECT Id, Username, IsActive FROM User WHERE Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG --json
181
+ sf data query --json --query "SELECT Id, Username, IsActive FROM User WHERE Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG
179
182
  ```
180
183
 
181
184
  **Username format**: `{agent_name}_agent@{orgId}.ext` (production) or `{agent_name}.{suffix}@{orgfarm}.salesforce.com` (dev/scratch). Always query the target org to confirm the exact format.
@@ -192,12 +195,12 @@ Via Setup UI:
192
195
 
193
196
  Via CLI:
194
197
  ```bash
195
- sf org assign permset --name AgentforceServiceAgentUser --on-behalf-of "{agent_name}_agent@{orgId}.ext" -o TARGET_ORG --json
198
+ sf org assign permset --json --name AgentforceServiceAgentUser --on-behalf-of "{agent_name}_agent@{orgId}.ext" -o TARGET_ORG
196
199
  ```
197
200
 
198
201
  Verify assignment:
199
202
  ```bash
200
- sf data query --query "SELECT Id, PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext' AND PermissionSet.Name = 'AgentforceServiceAgentUser'" -o TARGET_ORG --json
203
+ sf data query --json --query "SELECT Id, PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext' AND PermissionSet.Name = 'AgentforceServiceAgentUser'" -o TARGET_ORG
201
204
  ```
202
205
 
203
206
  ---
@@ -230,7 +233,7 @@ Key rule: Include EVERY Apex class referenced via `apex://` in your agent script
230
233
 
231
234
  Deploy the permission set:
232
235
  ```bash
233
- sf project deploy start --source-dir force-app/main/default/permissionsets/{AgentName}_Access.permissionset-meta.xml -o TARGET_ORG --json
236
+ sf project deploy start --json --source-dir force-app/main/default/permissionsets/{AgentName}_Access.permissionset-meta.xml -o TARGET_ORG
234
237
  ```
235
238
 
236
239
  ---
@@ -239,12 +242,12 @@ sf project deploy start --source-dir force-app/main/default/permissionsets/{Agen
239
242
 
240
243
  Via CLI:
241
244
  ```bash
242
- sf org assign permset --name {AgentName}_Access --on-behalf-of "{agent_name}_agent@{orgId}.ext" -o TARGET_ORG --json
245
+ sf org assign permset --json --name {AgentName}_Access --on-behalf-of "{agent_name}_agent@{orgId}.ext" -o TARGET_ORG
243
246
  ```
244
247
 
245
248
  Verify both permission sets are assigned:
246
249
  ```bash
247
- sf data query --query "SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG --json
250
+ sf data query --json --query "SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG
248
251
  ```
249
252
 
250
253
  Expected output includes both:
@@ -273,9 +276,9 @@ config:
273
276
  #### 6.1: Deploy Agent Bundle (Unpublished)
274
277
 
275
278
  ```bash
276
- sf project deploy start \
279
+ sf project deploy start --json \
277
280
  --source-dir force-app/main/default/aiAuthoringBundles/<AgentName> \
278
- -o TARGET_ORG --json
281
+ -o TARGET_ORG
279
282
  ```
280
283
 
281
284
  This deploys the agent as **unpublished metadata** — you can edit freely without version management.
@@ -283,9 +286,9 @@ This deploys the agent as **unpublished metadata** — you can edit freely witho
283
286
  #### 6.2: Test with Preview (Before Publishing)
284
287
 
285
288
  ```bash
286
- sf agent preview start \
289
+ sf agent preview start --json \
287
290
  --api-name <AgentName> \
288
- -o TARGET_ORG --json
291
+ -o TARGET_ORG
289
292
  ```
290
293
 
291
294
  What to test:
@@ -312,9 +315,9 @@ See [preview-test-loop.md](preview-test-loop.md) for the complete smoke test wor
312
315
  Only publish after all tests pass.
313
316
 
314
317
  ```bash
315
- sf agent publish authoring-bundle \
318
+ sf agent publish authoring-bundle --json \
316
319
  --api-name <AgentName> \
317
- -o TARGET_ORG --json
320
+ -o TARGET_ORG
318
321
  ```
319
322
 
320
323
  **Publishing does NOT activate.** The new BotVersion is created as `Inactive`. You must explicitly activate.
@@ -322,19 +325,19 @@ sf agent publish authoring-bundle \
322
325
  #### 6.4: Activate Agent
323
326
 
324
327
  ```bash
325
- sf agent activate \
328
+ sf agent activate --json \
326
329
  --api-name <AgentName> \
327
330
  -o TARGET_ORG
328
331
  ```
329
332
 
330
- `sf agent activate` does NOT support `--json`. It prints a plain-text confirmation.
333
+ Note: `sf agent activate` may not support `--json` in all CLI versions. It prints a plain-text confirmation.
331
334
 
332
335
  #### 6.5: Verify Activation
333
336
 
334
337
  ```bash
335
- sf data query \
338
+ sf data query --json \
336
339
  --query "SELECT Id, DeveloperName, Status FROM BotVersion WHERE BotDefinition.DeveloperName = '<AgentName>' ORDER BY CreatedDate DESC LIMIT 1" \
337
- -o TARGET_ORG --json
340
+ -o TARGET_ORG
338
341
  ```
339
342
 
340
343
  Expected: `Status = 'Active'`
@@ -366,7 +369,7 @@ Same XML template as Step 3 above. Include `<classAccesses>` for all Apex classe
366
369
  Assign the custom PS to employees (not to a service account):
367
370
 
368
371
  ```bash
369
- sf org assign permset --name {AgentName}_Access --on-behalf-of "employee@company.com" -o TARGET_ORG --json
372
+ sf org assign permset --json --name {AgentName}_Access --on-behalf-of "employee@company.com" -o TARGET_ORG
370
373
  ```
371
374
 
372
375
  Or use Permission Set Groups for role-based access.
@@ -384,7 +387,7 @@ config:
384
387
  ### Step 4: Publish
385
388
 
386
389
  ```bash
387
- sf agent publish authoring-bundle --api-name Employee_Agent -o TARGET_ORG --json
390
+ sf agent publish authoring-bundle --json --api-name Employee_Agent -o TARGET_ORG
388
391
  ```
389
392
 
390
393
  ---
@@ -409,22 +412,22 @@ Run this combined query to verify all setup steps for a Service Agent:
409
412
 
410
413
  ```bash
411
414
  # 1. Einstein Agent User exists and is active
412
- sf data query --query "SELECT Id, Username, IsActive, Profile.Name FROM User WHERE Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG --json
415
+ sf data query --json --query "SELECT Id, Username, IsActive, Profile.Name FROM User WHERE Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG
413
416
 
414
417
  # 2. System PS assigned
415
- sf data query --query "SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext' AND PermissionSet.Name = 'AgentforceServiceAgentUser'" -o TARGET_ORG --json
418
+ sf data query --json --query "SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext' AND PermissionSet.Name = 'AgentforceServiceAgentUser'" -o TARGET_ORG
416
419
 
417
420
  # 3. Custom PS assigned
418
- sf data query --query "SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext' AND PermissionSet.Name = '{AgentName}_Access'" -o TARGET_ORG --json
421
+ sf data query --json --query "SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext' AND PermissionSet.Name = '{AgentName}_Access'" -o TARGET_ORG
419
422
 
420
423
  # 4. All permission sets for user (combined view)
421
- sf data query --query "SELECT PermissionSet.Name, PermissionSet.Label FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG --json
424
+ sf data query --json --query "SELECT PermissionSet.Name, PermissionSet.Label FROM PermissionSetAssignment WHERE Assignee.Username = '{agent_name}_agent@{orgId}.ext'" -o TARGET_ORG
422
425
 
423
426
  # 5. Agent config has default_agent_user
424
427
  # Check your .agent file's config: block
425
428
 
426
429
  # 6. Agent publishes successfully
427
- sf agent publish authoring-bundle --api-name AgentName -o TARGET_ORG --json
430
+ sf agent publish authoring-bundle --json --api-name AgentName -o TARGET_ORG
428
431
  ```
429
432
 
430
433
  Checklist:
@@ -20,7 +20,7 @@ The `sf agent validate` command checks Agent Script files for syntax errors, str
20
20
  After modifying any `.agent` file, always run this command:
21
21
 
22
22
  ```bash
23
- sf agent validate authoring-bundle --api-name <AGENT_NAME> --json
23
+ sf agent validate authoring-bundle --json --api-name <AGENT_NAME>
24
24
  ```
25
25
 
26
26
  Replace `<AGENT_NAME>` with the directory name under `aiAuthoringBundles/` (without the `.agent` extension). Always include `--json` so the output is machine-readable.
@@ -28,7 +28,7 @@ Replace `<AGENT_NAME>` with the directory name under `aiAuthoringBundles/` (with
28
28
  Example:
29
29
 
30
30
  ```bash
31
- sf agent validate authoring-bundle --api-name Local_Info_Agent --json
31
+ sf agent validate authoring-bundle --json --api-name Local_Info_Agent
32
32
  ```
33
33
 
34
34
  ### Interpreting Output
@@ -183,21 +183,21 @@ ALWAYS use `--json` when calling from a script or AI assistant (not interactive
183
183
  #### Step 1: Start a Session
184
184
 
185
185
  ```bash
186
- sf agent preview start --authoring-bundle <BUNDLE_NAME> --json
186
+ sf agent preview start --json --authoring-bundle <BUNDLE_NAME> --use-live-actions
187
187
  ```
188
188
 
189
- This command returns a session ID. Capture it immediately — you need it for every subsequent command.
189
+ This command returns a session ID. Capture it immediately — you need it for every subsequent command. Use `--use-live-actions` to execute real backing logic (recommended). Omit it only when backing logic doesn't exist yet and you want simulated preview.
190
190
 
191
191
  Example:
192
192
 
193
193
  ```bash
194
- sf agent preview start --authoring-bundle Local_Info_Agent --json
194
+ sf agent preview start --json --authoring-bundle Local_Info_Agent --use-live-actions
195
195
  ```
196
196
 
197
197
  #### Step 2: Send Utterances
198
198
 
199
199
  ```bash
200
- sf agent preview send --authoring-bundle <BUNDLE_NAME> --session-id <SESSION_ID> -u "<MESSAGE>" --json
200
+ sf agent preview send --json --authoring-bundle <BUNDLE_NAME> --session-id <SESSION_ID> -u "<MESSAGE>"
201
201
  ```
202
202
 
203
203
  Include the same `--authoring-bundle` name and the session ID from Step 1. You can send multiple utterances in the same session — do not end and restart between turns.
@@ -205,13 +205,13 @@ Include the same `--authoring-bundle` name and the session ID from Step 1. You c
205
205
  Example:
206
206
 
207
207
  ```bash
208
- sf agent preview send --authoring-bundle Local_Info_Agent --session-id abc123def456 -u "What's the weather?" --json
208
+ sf agent preview send --json --authoring-bundle Local_Info_Agent --session-id abc123def456 -u "What's the weather?"
209
209
  ```
210
210
 
211
211
  #### Step 3: End a Session (Optional)
212
212
 
213
213
  ```bash
214
- sf agent preview end --authoring-bundle <BUNDLE_NAME> --session-id <SESSION_ID> --json
214
+ sf agent preview end --json --authoring-bundle <BUNDLE_NAME> --session-id <SESSION_ID>
215
215
  ```
216
216
 
217
217
  This command returns the path to session trace files. Call it when the conversation is complete. Do not end prematurely — if the user may ask follow-up questions, keep the session open.
@@ -229,7 +229,7 @@ Simulated preview mode speeds up inner-loop development but cannot validate real
229
229
  **Live Preview Mode.** Real backing code executes and returns real outputs. Pass `--use-live-actions`:
230
230
 
231
231
  ```bash
232
- sf agent preview start --authoring-bundle <BUNDLE_NAME> --use-live-actions --json
232
+ sf agent preview start --json --authoring-bundle <BUNDLE_NAME> --use-live-actions
233
233
  ```
234
234
 
235
235
  Use live preview mode when:
@@ -240,6 +240,8 @@ Live preview mode is required for reliable grounding testing. The grounding chec
240
240
 
241
241
  CRITICAL: `--use-live-actions` is ONLY valid with `--authoring-bundle`. Published agents (`--api-name`) always execute real actions — do NOT pass `--use-live-actions` with `--api-name`.
242
242
 
243
+ CRITICAL: `--use-live-actions` is a flag on `preview start` ONLY. Do NOT pass it to `preview send` or `preview end` — those commands do not accept it and will error.
244
+
243
245
  ### Agent Identification
244
246
 
245
247
  Use exactly one of these mutually exclusive flags:
@@ -264,7 +266,7 @@ The CLI automatically uses the project's default target org. Always omit `--targ
264
266
  sf agent preview --authoring-bundle My_Bundle
265
267
 
266
268
  # CORRECT — programmatic API
267
- sf agent preview start --authoring-bundle My_Bundle --json
269
+ sf agent preview start --json --authoring-bundle My_Bundle
268
270
  ```
269
271
 
270
272
  The bare `sf agent preview` command is an interactive REPL for humans. Automation cannot provide terminal input (ESC), so it hangs. Use `start`/`send`/`end` with `--json`.
@@ -273,10 +275,10 @@ The bare `sf agent preview` command is an interactive REPL for humans. Automatio
273
275
 
274
276
  ```bash
275
277
  # WRONG — mutually exclusive flags
276
- sf agent preview start --authoring-bundle My_Bundle --api-name My_Agent --json
278
+ sf agent preview start --json --authoring-bundle My_Bundle --api-name My_Agent
277
279
 
278
280
  # CORRECT — choose one
279
- sf agent preview start --authoring-bundle My_Bundle --json
281
+ sf agent preview start --json --authoring-bundle My_Bundle
280
282
  ```
281
283
 
282
284
  These flags are mutually exclusive. Use the one matching your agent type.
@@ -299,11 +301,11 @@ Use `agent preview` commands with `--api-name` to preview published agents.
299
301
 
300
302
  ```bash
301
303
  # WRONG — no session exists
302
- sf agent preview send --authoring-bundle My_Bundle -u "Hello" --json
304
+ sf agent preview send --json --authoring-bundle My_Bundle -u "Hello"
303
305
 
304
306
  # CORRECT — start first, capture session ID
305
- sf agent preview start --authoring-bundle My_Bundle --json
306
- sf agent preview send --authoring-bundle My_Bundle --session-id <ID> -u "Hello" --json
307
+ sf agent preview start --json --authoring-bundle My_Bundle
308
+ sf agent preview send --json --authoring-bundle My_Bundle --session-id <ID> -u "Hello"
307
309
  ```
308
310
 
309
311
  Each session has a unique ID. You must start before sending.
@@ -312,10 +314,10 @@ Each session has a unique ID. You must start before sending.
312
314
 
313
315
  ```bash
314
316
  # WRONG — missing --authoring-bundle
315
- sf agent preview send --session-id <ID> -u "Hello" --json
317
+ sf agent preview send --json --session-id <ID> -u "Hello"
316
318
 
317
319
  # CORRECT
318
- sf agent preview send --authoring-bundle My_Bundle --session-id <ID> -u "Hello" --json
320
+ sf agent preview send --json --authoring-bundle My_Bundle --session-id <ID> -u "Hello"
319
321
  ```
320
322
 
321
323
  Every command after `start` must include the same `--authoring-bundle` or `--api-name` flag.
@@ -324,10 +326,10 @@ Every command after `start` must include the same `--authoring-bundle` or `--api
324
326
 
325
327
  ```bash
326
328
  # WRONG — concurrent sessions collide
327
- sf agent preview send --authoring-bundle My_Bundle -u "Hello" --json
329
+ sf agent preview send --json --authoring-bundle My_Bundle -u "Hello"
328
330
 
329
331
  # CORRECT — always include session ID
330
- sf agent preview send --authoring-bundle My_Bundle --session-id <ID> -u "Hello" --json
332
+ sf agent preview send --json --authoring-bundle My_Bundle --session-id <ID> -u "Hello"
331
333
  ```
332
334
 
333
335
  If multiple agents have concurrent sessions against the same agent, omitting the session ID causes them to interfere. Always pass the session ID from `start`.
@@ -699,7 +701,7 @@ Use this systematic 8-step approach when diagnosing any agent behavior issue.
699
701
 
700
702
  6. **Fix** — Update Agent Script instructions, variable logic, or action definitions based on what you found.
701
703
 
702
- 7. **Validate** — Run `sf agent validate authoring-bundle --api-name <AGENT_NAME> --json` to ensure the fix doesn't introduce syntax errors.
704
+ 7. **Validate** — Run `sf agent validate authoring-bundle --json --api-name <AGENT_NAME>` to ensure the fix doesn't introduce syntax errors.
703
705
 
704
706
  8. **Re-Test** — Run a new preview session with the same input and compare traces. Verify the fix resolved the issue.
705
707
 
@@ -0,0 +1,158 @@
1
+ # Architecture Patterns
2
+
3
+ > Extracted from SKILL.md Section 8. This file is loaded on demand when architecture pattern guidance is needed.
4
+
5
+ > All architecture patterns below work for both `AgentforceServiceAgent` and `AgentforceEmployeeAgent`. The only difference is that employee agents cannot use `@utils.escalate` or `connection messaging:` — replace escalation with a `@utils.transition` to a help topic or an action that creates a case/ticket.
6
+
7
+ ## When to Use Each Pattern
8
+
9
+ | Pattern | Use When |
10
+ |---------|----------|
11
+ | Hub-and-Spoke | Agent has 2+ distinct topics with different intents (most common) |
12
+ | Verification Gate | Sensitive data, payments, or PII require identity verification first |
13
+ | Post-Action Loop | Actions produce state that drives follow-up logic (e.g., risk scoring) |
14
+ | Single Topic | Agent serves one focused purpose with no routing needed |
15
+
16
+ ## Hub-and-Spoke (Most Common)
17
+
18
+ A central `topic_selector` routes to specialized spoke topics. Each spoke has a "back to hub" transition. Use when users may have multiple distinct intents.
19
+
20
+ ```
21
+ start_agent topic_selector:
22
+ description: "Route user requests to the appropriate topic"
23
+ reasoning:
24
+ instructions: |
25
+ You are a router only. Do NOT answer questions directly.
26
+ Always use a transition action to route immediately.
27
+ actions:
28
+ to_orders: @utils.transition to @topic.order_support
29
+ description: "Order questions"
30
+ to_returns: @utils.transition to @topic.return_support
31
+ description: "Return or refund requests"
32
+ to_general: @utils.transition to @topic.general_support
33
+ description: "General questions"
34
+
35
+ topic order_support:
36
+ description: "Handle order inquiries"
37
+ reasoning:
38
+ instructions: ->
39
+ | Help the customer with their order.
40
+ actions:
41
+ lookup: @actions.get_order
42
+ description: "Look up order"
43
+ back: @utils.transition to @topic.topic_selector
44
+ description: "Route to a different topic"
45
+ ```
46
+
47
+ > **Routing lives in `start_agent`** -- put all transition actions directly in `start_agent topic_selector:`. Do NOT create a separate routing-only topic (e.g. `main_menu`, `central_hub`) -- that duplicates the router, adds an extra LLM hop (~3-5s latency), and confuses the platform. Topics that need "go back" should transition to `@topic.topic_selector`.
48
+
49
+ ## Verification Gate
50
+
51
+ Users must pass through identity verification before accessing protected topics. Use when handling sensitive data, payments, or PII.
52
+
53
+ ```
54
+ start_agent topic_selector:
55
+ description: "Route through identity verification"
56
+ reasoning:
57
+ instructions: |
58
+ You are a router only. Do NOT answer questions directly.
59
+ Route all users to identity verification first.
60
+ actions:
61
+ verify: @utils.transition to @topic.identity_verification
62
+ description: "Begin verification"
63
+
64
+ topic identity_verification:
65
+ description: "Verify customer identity"
66
+ reasoning:
67
+ instructions: ->
68
+ if @variables.failed_attempts >= 3:
69
+ | Too many failed attempts. Transferring to human agent.
70
+ transition to @topic.escalation
71
+
72
+ if @variables.is_verified == True:
73
+ | Identity verified! How can I help?
74
+
75
+ if @variables.is_verified == False:
76
+ | Please verify your identity.
77
+
78
+ actions:
79
+ verify_email: @actions.verify_identity
80
+ description: "Verify customer email"
81
+ set @variables.is_verified = @outputs.verified
82
+
83
+ to_account: @utils.transition to @topic.account_mgmt
84
+ description: "Account management"
85
+ available when @variables.is_verified == True
86
+
87
+ escalate_now: @utils.escalate
88
+ description: "Transfer to human"
89
+ ```
90
+
91
+ ## Post-Action Loop
92
+
93
+ The topic re-resolves after an action completes. Place post-action checks at the TOP of `instructions: ->` so they trigger on the loop:
94
+
95
+ ```
96
+ reasoning:
97
+ instructions: ->
98
+ # POST-ACTION CHECK (at TOP - triggers on re-resolution)
99
+ if @variables.refund_status == "Approved":
100
+ run @actions.create_crm_case
101
+ with customer_id = @variables.customer_id
102
+ transition to @topic.confirmation
103
+
104
+ # PRE-LLM: Load data
105
+ run @actions.load_risk_score
106
+ with customer_id = @variables.customer_id
107
+ set @variables.risk_score = @outputs.score
108
+
109
+ # DYNAMIC INSTRUCTIONS
110
+ | Risk score: {!@variables.risk_score}
111
+ if @variables.risk_score >= 80:
112
+ | HIGH RISK - Offer retention package.
113
+ else:
114
+ | STANDARD - Follow normal process.
115
+ ```
116
+
117
+ ## Migrating to Hub-and-Spoke
118
+
119
+ When refactoring a flat agent (all logic in one topic) into hub-and-spoke:
120
+
121
+ 1. **Identify distinct intents** — each becomes a spoke topic
122
+ 2. **Move instructions and actions** from the monolithic topic into spoke topics. Each spoke needs BOTH its Level 1 action definitions (under `topic > actions`) AND Level 2 action invocations (under `topic > reasoning > actions`).
123
+ 3. **Create `start_agent topic_selector:`** with transition actions pointing to each spoke
124
+ 4. **Add "back to hub" transitions** in each spoke: `@utils.transition to @topic.topic_selector`
125
+ 5. **Re-preview immediately** — verify topic routing works before making further changes
126
+
127
+ **Common migration mistakes:**
128
+ - Creating a separate `main_menu` topic instead of using `start_agent topic_selector:` as the hub — adds an unnecessary LLM hop
129
+ - Leaving action definitions in `start_agent` instead of moving them to spoke topics — all actions visible in all topics, confusing the planner
130
+ - Forgetting to add "back to hub" transitions — users get stuck in a spoke topic
131
+ - If trace shows `topic: "DefaultTopic"`, check that topic descriptions contain keywords matching test utterances
132
+
133
+ ## Multi-Intent Handling
134
+
135
+ When a user sends multiple intents in one message, the start_agent router should handle the first intent and queue the second:
136
+
137
+ ```
138
+ instructions: |
139
+ You are a router only. Do NOT answer questions directly.
140
+ If the user asks about multiple topics in one message, route to the first
141
+ topic. After that task is complete, remind the user about the other request.
142
+ ```
143
+
144
+ ## Handling Incomplete Action Inputs
145
+
146
+ - Use `with param = ...` (slot-fill) for inputs the LLM should extract from conversation
147
+ - Add instructions that tell the LLM to invoke the action with whatever data is available
148
+ - Anti-pattern: Making the LLM ask for ALL inputs before invoking
149
+
150
+ ## Controlling Opportunistic Action Chains
151
+
152
+ In long action chains (A->B->C->D), the LLM may invoke downstream actions as soon as prerequisites are met. To control this:
153
+
154
+ - Add explicit gating in instructions: "Only invoke generate_resolution if the user explicitly asks"
155
+ - Use `available when` guards on downstream actions
156
+ - Distinguish between "analyze only" and "full resolution" workflows in instructions
157
+
158
+ Anti-pattern: Leaving action chains ungated so the LLM runs the entire pipeline for every query.