@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,156 @@
1
+ # Bidirectional Routing Pattern
2
+ # Navigate to a specialist topic and return with results
3
+ #
4
+ # ★ When To Use This Pattern:
5
+ # - Main topic needs specialized processing then returns
6
+ # - "Consult a specialist" pattern (like asking an expert)
7
+ # - Complex workflows where you leave, do work, then come back
8
+ # - Alternative to cramming everything into one topic
9
+ #
10
+ # ★ Key Insight:
11
+ # Standard transitions (@utils.transition) are one-way.
12
+ # For round-trip routing, store the "return address" in a variable.
13
+ # The specialist topic transitions back when done.
14
+ #
15
+ # ★ Architecture Decision:
16
+ # Use this when you want separation of concerns:
17
+ # - Main topic: Orchestration and user interaction
18
+ # - Specialist topic: Focused, complex processing
19
+ #
20
+ # This is a PARTIAL template - integrate into a complete agent file
21
+
22
+ variables:
23
+ # ... standard linked variables ...
24
+ return_topic: mutable string = ""
25
+ description: "Topic to return to after specialist consultation"
26
+ specialist_result: mutable string = ""
27
+ description: "Result from specialist topic"
28
+ consultation_status: mutable string = ""
29
+ description: "Status of specialist consultation"
30
+
31
+ # Main orchestration topic
32
+ start_agent main_hub:
33
+ label: "Main Hub"
34
+ description: "Central hub that routes to specialists and handles results"
35
+
36
+ reasoning:
37
+ instructions: ->
38
+ | You are the main coordinator.
39
+ | When user needs specialized help:
40
+ | - For pricing questions, consult the pricing specialist
41
+ | - For technical issues, consult the technical specialist
42
+ |
43
+ | After specialist returns, communicate their findings to the user.
44
+ |
45
+ | Current specialist result: {!@variables.specialist_result}
46
+ | Consultation status: {!@variables.consultation_status}
47
+ actions:
48
+ # Route to pricing specialist (store return address first)
49
+ consult_pricing: @utils.transition to @topic.pricing_specialist
50
+ available when @variables.consultation_status != "in_progress"
51
+
52
+ # Route to technical specialist
53
+ consult_technical: @utils.transition to @topic.technical_specialist
54
+ available when @variables.consultation_status != "in_progress"
55
+
56
+ end_conversation: @utils.transition to @topic.farewell
57
+
58
+ # Pricing specialist topic
59
+ topic pricing_specialist:
60
+ label: "Pricing Specialist"
61
+ description: "Handles complex pricing calculations and returns results"
62
+
63
+ actions:
64
+ calculate_price:
65
+ description: "Calculates complex pricing"
66
+ inputs:
67
+ product_id: string
68
+ description: "Product to price"
69
+ quantity: number
70
+ description: "Quantity requested"
71
+ outputs:
72
+ final_price: number
73
+ description: "Calculated price"
74
+ discount_applied: string
75
+ description: "Any discounts applied"
76
+ target: "flow://Calculate_Complex_Pricing"
77
+
78
+ # Mark consultation as in progress when entering
79
+ before_reasoning:
80
+ set @variables.consultation_status = "in_progress"
81
+ set @variables.return_topic = "main_hub"
82
+
83
+ reasoning:
84
+ instructions: ->
85
+ | You are the pricing specialist.
86
+ | Focus ONLY on pricing questions.
87
+ | Calculate the price and prepare your findings.
88
+ | When done, return to the main hub with your results.
89
+ actions:
90
+ calculate: @actions.calculate_price
91
+ with product_id=...
92
+ with quantity=...
93
+ set @variables.specialist_result = @outputs.final_price
94
+
95
+ # Return to main hub with results
96
+ return_with_results: @utils.transition to @topic.main_hub
97
+
98
+ # Mark consultation complete when leaving
99
+ after_reasoning:
100
+ set @variables.consultation_status = "completed"
101
+
102
+ # Technical specialist topic
103
+ topic technical_specialist:
104
+ label: "Technical Specialist"
105
+ description: "Handles technical troubleshooting and returns results"
106
+
107
+ actions:
108
+ diagnose_issue:
109
+ description: "Diagnoses technical issues"
110
+ inputs:
111
+ symptoms: string
112
+ description: "Reported symptoms"
113
+ outputs:
114
+ diagnosis: string
115
+ description: "Technical diagnosis"
116
+ solution: string
117
+ description: "Recommended solution"
118
+ target: "flow://Technical_Diagnosis"
119
+
120
+ before_reasoning:
121
+ set @variables.consultation_status = "in_progress"
122
+ set @variables.return_topic = "main_hub"
123
+
124
+ reasoning:
125
+ instructions: ->
126
+ | You are the technical specialist.
127
+ | Focus ONLY on technical issues.
128
+ | Diagnose the problem and prepare your findings.
129
+ | When done, return to the main hub with your results.
130
+ actions:
131
+ diagnose: @actions.diagnose_issue
132
+ with symptoms=...
133
+ set @variables.specialist_result = @outputs.diagnosis
134
+
135
+ return_with_results: @utils.transition to @topic.main_hub
136
+
137
+ after_reasoning:
138
+ set @variables.consultation_status = "completed"
139
+
140
+ topic farewell:
141
+ label: "Farewell"
142
+ description: "Ends the conversation"
143
+
144
+ reasoning:
145
+ instructions: ->
146
+ | Thank the user and say goodbye.
147
+
148
+ # ★ Alternative: Simple one-way transitions (when you don't need to return)
149
+ #
150
+ # If the specialist doesn't need to return results to a coordinator,
151
+ # use simple transitions without the return_topic pattern:
152
+ #
153
+ # go_orders: @utils.transition to @topic.orders
154
+ # go_billing: @utils.transition to @topic.billing
155
+ #
156
+ # The bidirectional pattern adds complexity - only use when needed.
@@ -0,0 +1,244 @@
1
+ # Critical Input Collection Pattern
2
+ # Ensures reliable capture of critical data before proceeding with workflows
3
+ #
4
+ # ★ Problem This Solves:
5
+ # - LLM sends empty JSON to actions
6
+ # - LLM sends wrong field names (_id instead of account_id)
7
+ # - LLM extracts wrong values from conversation
8
+ # - Agent proceeds without required data, causing crashes
9
+ #
10
+ # ★ Root Cause:
11
+ # Slot filling (`with account_id=...`) relies on LLM inference, which is
12
+ # probabilistic and can fail in subtle ways. Critical inputs need
13
+ # deterministic collection with validation.
14
+ #
15
+ # ★ Key Patterns:
16
+ # 1. First-Interaction Collection - Tell LLM its PRIMARY GOAL
17
+ # 2. Variable Setter Action - Dedicated action to capture + validate + store
18
+ # 3. Single-Use Pattern - `available when @var == ""` disables after use
19
+ # 4. Null Guard Pattern - Block ALL downstream actions until input is valid
20
+ # 5. Explicit Action References - Guide LLM with `{!@actions.x}` in instructions
21
+ #
22
+ # ★ When To Use This Pattern:
23
+ # - Workflows that REQUIRE a specific ID (account, order, case, etc.)
24
+ # - When slot filling has been unreliable
25
+ # - When invalid input causes downstream failures
26
+ # - Multi-topic agents where input must persist across transitions
27
+ #
28
+ # This is a COMPLETE template - customize for your use case
29
+
30
+ system:
31
+ instructions: "You are a research assistant. Your PRIMARY GOAL is to collect the account ID before performing any research. Never proceed without a validated account ID."
32
+ messages:
33
+ welcome: "Hello! I can help you research account information. Please provide the account ID to get started."
34
+ error: "I encountered an issue. Let me try again."
35
+
36
+ config:
37
+ agent_name: "Account_Research_Agent"
38
+ default_agent_user: "agent@company.salesforce.com"
39
+ agent_label: "Account Research Agent"
40
+ description: "Demonstrates critical input collection patterns for reliable slot filling"
41
+
42
+ variables:
43
+ # Standard linked variables (required)
44
+ EndUserId: linked string
45
+ source: @MessagingSession.MessagingEndUserId
46
+ description: "Messaging End User ID"
47
+ RoutableId: linked string
48
+ source: @MessagingSession.Id
49
+ description: "Messaging Session ID"
50
+ ContactId: linked string
51
+ source: @MessagingEndUser.ContactId
52
+ description: "Contact ID"
53
+
54
+ # ★ CRITICAL INPUT - The value that MUST be collected before proceeding
55
+ account_id: mutable string = ""
56
+ description: "The Salesforce Account ID (18-char, starts with 001) - MUST be collected and validated before any research"
57
+
58
+ # ★ VALIDATION STATE - Track whether input has been validated
59
+ account_id_validated: mutable boolean = False
60
+ description: "Whether account_id has been validated as a real Salesforce ID"
61
+
62
+ # ★ COLLECTION ATTEMPTS - Track retries to prevent infinite loops
63
+ collection_attempts: mutable number = 0
64
+ description: "Number of times we've tried to collect account_id"
65
+
66
+ # Research results
67
+ account_name: mutable string = ""
68
+ description: "Name of the account (from lookup)"
69
+ research_summary: mutable string = ""
70
+ description: "Research summary for the account"
71
+
72
+ language:
73
+ default_locale: "en_US"
74
+ additional_locales: ""
75
+ all_additional_locales: False
76
+
77
+ # ★ ENTRY POINT: Input Collection Topic
78
+ # This topic's ONLY job is to collect and validate the critical input
79
+ start_agent input_collector:
80
+ label: "Input Collector"
81
+ description: "Collects and validates the account ID before allowing research"
82
+
83
+ actions:
84
+ # ★ PATTERN 2: Variable Setter Action
85
+ # Dedicated action that captures, validates, and stores the input
86
+ capture_account_id:
87
+ description: "Captures and validates the Salesforce Account ID from user input"
88
+ inputs:
89
+ account_id: string
90
+ description: "The 18-character Salesforce Account ID provided by the user (format: starts with '001')"
91
+ is_required: True
92
+ outputs:
93
+ validated_account_id: string
94
+ description: "The validated account ID (empty if invalid)"
95
+ is_valid: boolean
96
+ description: "True if the account ID is valid and exists"
97
+ account_name: string
98
+ description: "Name of the account if found"
99
+ error_message: string
100
+ description: "Error message if validation failed"
101
+ target: "flow://Validate_Account_Id"
102
+ require_user_confirmation: False
103
+ include_in_progress_indicator: True
104
+ progress_indicator_message: "Validating account ID..."
105
+
106
+ reasoning:
107
+ # ★ PATTERN 1: First-Interaction Collection
108
+ # Tell the LLM its PRIMARY GOAL is to collect the input
109
+ instructions: ->
110
+ | YOUR PRIMARY GOAL: Collect the account ID from the user.
111
+ |
112
+ | CURRENT STATE:
113
+ if @variables.account_id == "":
114
+ | ⚠️ Account ID NOT YET COLLECTED
115
+ | ASK the user for their Salesforce Account ID.
116
+ | The ID should be 18 characters and start with "001".
117
+ |
118
+ | Example prompt: "Please provide the Account ID you'd like me to research."
119
+
120
+ if @variables.account_id != "" and @variables.account_id_validated == False:
121
+ | 🔄 Account ID received: {!@variables.account_id}
122
+ | Attempting validation...
123
+ |
124
+ | Use {!@actions.capture_account_id} to validate this ID.
125
+
126
+ if @variables.account_id_validated == True:
127
+ | ✅ Account ID validated: {!@variables.account_id}
128
+ | Account Name: {!@variables.account_name}
129
+ |
130
+ | Transition to research topic to begin analysis.
131
+
132
+ if @variables.collection_attempts > 2 and @variables.account_id_validated == False:
133
+ | ❌ Multiple validation failures.
134
+ | Ask the user to verify their Account ID is correct.
135
+ | Suggest they check Salesforce for the correct ID format.
136
+
137
+ actions:
138
+ # ★ PATTERN 3: Single-Use Pattern
139
+ # Action becomes unavailable once account_id is successfully captured
140
+ validate_id: @actions.capture_account_id
141
+ with account_id=...
142
+ set @variables.account_id = @outputs.validated_account_id
143
+ set @variables.account_id_validated = @outputs.is_valid
144
+ set @variables.account_name = @outputs.account_name
145
+ set @variables.collection_attempts = @variables.collection_attempts + 1
146
+ # ★ SINGLE-USE: Unavailable once validated
147
+ available when @variables.account_id_validated == False
148
+
149
+ # ★ PATTERN 4: Null Guard Pattern
150
+ # Transition ONLY available when input is validated
151
+ go_research: @utils.transition to @topic.research
152
+ available when @variables.account_id_validated == True
153
+
154
+ # ★ RESEARCH TOPIC: Only accessible after input is validated
155
+ topic research:
156
+ label: "Account Research"
157
+ description: "Performs research on the validated account"
158
+
159
+ actions:
160
+ # Research action that USES the validated account_id
161
+ research_account:
162
+ description: "Performs detailed research on the account"
163
+ inputs:
164
+ account_id: string
165
+ description: "The validated account ID"
166
+ is_required: True
167
+ outputs:
168
+ research_summary: string
169
+ description: "Summary of research findings"
170
+ signal_summary: string
171
+ description: "Key signals detected"
172
+ target: "flow://Research_Account"
173
+ include_in_progress_indicator: True
174
+ progress_indicator_message: "Researching account..."
175
+
176
+ reasoning:
177
+ instructions: ->
178
+ | Researching account: {!@variables.account_name} ({!@variables.account_id})
179
+ |
180
+ if @variables.research_summary == "":
181
+ | Use {!@actions.research_account} to analyze this account.
182
+ if @variables.research_summary != "":
183
+ | Research complete!
184
+ | {!@variables.research_summary}
185
+
186
+ actions:
187
+ # ★ PATTERN 4: Null Guard - Uses variable binding, NOT slot filling
188
+ # This ensures the validated ID is used, not LLM re-extraction
189
+ do_research: @actions.research_account
190
+ with account_id=@variables.account_id
191
+ set @variables.research_summary = @outputs.research_summary
192
+ # ★ GUARD: Only available if we have validated ID (defensive)
193
+ available when @variables.account_id_validated == True
194
+ available when @variables.research_summary == ""
195
+
196
+ # Return to collector for new account
197
+ new_account: @utils.transition to @topic.input_collector
198
+ available when @variables.research_summary != ""
199
+
200
+ # ═══════════════════════════════════════════════════════════════════════════
201
+ # ★ INSIGHTS: Critical Input Collection
202
+ # ═══════════════════════════════════════════════════════════════════════════
203
+ #
204
+ # WHY SLOT FILLING FAILS:
205
+ # The `...` syntax relies on LLM to extract values from conversation.
206
+ # This is probabilistic and can fail when:
207
+ # - User provides ID in unexpected format
208
+ # - Multiple IDs mentioned in conversation
209
+ # - LLM abbreviates or modifies field names
210
+ # - Context window is cluttered with other data
211
+ #
212
+ # THE SOLUTION: DETERMINISTIC COLLECTION
213
+ # Instead of `with account_id=...` on EVERY action:
214
+ # 1. Collect ONCE with a dedicated setter action
215
+ # 2. Validate BEFORE storing
216
+ # 3. Store in variable: `set @variables.account_id = @outputs.validated_id`
217
+ # 4. Use variable binding: `with account_id=@variables.account_id`
218
+ # 5. Guard all actions: `available when @variables.account_id_validated == True`
219
+ #
220
+ # PATTERN SUMMARY:
221
+ #
222
+ # ┌─────────────────────────────────────────────────────────────────┐
223
+ # │ CRITICAL INPUT COLLECTION FLOW │
224
+ # ├─────────────────────────────────────────────────────────────────┤
225
+ # │ │
226
+ # │ User provides ID ────► Setter Action (slot fills once) │
227
+ # │ │ │
228
+ # │ ▼ │
229
+ # │ Validation │
230
+ # │ │ │
231
+ # │ ┌────────┴────────┐ │
232
+ # │ ▼ ▼ │
233
+ # │ Valid Invalid │
234
+ # │ │ │ │
235
+ # │ set @variables.account_id Ask again │
236
+ # │ set @variables.validated=True (limit retries) │
237
+ # │ │ │
238
+ # │ ▼ │
239
+ # │ All downstream actions use │
240
+ # │ @variables.account_id (NOT ...) │
241
+ # │ │
242
+ # └─────────────────────────────────────────────────────────────────┘
243
+ #
244
+ # ═══════════════════════════════════════════════════════════════════════════
@@ -0,0 +1,89 @@
1
+ # Topic Delegation vs Transition Pattern
2
+ # Understanding the difference between delegation and permanent handoffs
3
+ #
4
+ # ★ KEY CONCEPTS:
5
+ #
6
+ # DELEGATION (@topic.* syntax):
7
+ # - Syntax: action_name: @topic.topic_name
8
+ # - Control CAN return to the calling topic
9
+ # - Use for: consulting specialists, sub-tasks, getting help
10
+ #
11
+ # TRANSITION (@utils.transition syntax):
12
+ # - Syntax: action_name: @utils.transition to @topic.topic_name
13
+ # - PERMANENT handoff - control does NOT return
14
+ # - Use for: menu navigation, workflow stages, permanent routing
15
+ #
16
+ # ★ When To Use Each:
17
+ # DELEGATION: "Consult an expert then continue here"
18
+ # TRANSITION: "Go to this topic and stay there"
19
+ #
20
+ # ★ Implementation Note:
21
+ # If delegation syntax doesn't work in your deployment method,
22
+ # use the bidirectional-routing.agent pattern which manually
23
+ # tracks return context via variables.
24
+ #
25
+ # This is a PARTIAL template - integrate into a complete agent file
26
+
27
+ # ═══════════════════════════════════════════════════════════════
28
+ # PATTERN 1: Topic Delegation (can return)
29
+ # ═══════════════════════════════════════════════════════════════
30
+
31
+ # Delegation syntax in reasoning.actions:
32
+ #
33
+ # reasoning:
34
+ # actions:
35
+ # # Delegation - specialist CAN return control to this topic
36
+ # consult_expert: @topic.specialist_topic
37
+ # description: "Consult specialist for complex questions"
38
+ # available when @variables.needs_expert_help == True
39
+ #
40
+ # The specialist topic processes the request and control returns
41
+ # to the original topic when done.
42
+
43
+ # ═══════════════════════════════════════════════════════════════
44
+ # PATTERN 2: Transition (permanent handoff)
45
+ # ═══════════════════════════════════════════════════════════════
46
+
47
+ # Transition syntax in reasoning.actions:
48
+ #
49
+ # reasoning:
50
+ # actions:
51
+ # # Transition - permanent move to orders topic
52
+ # go_orders: @utils.transition to @topic.orders
53
+ #
54
+ # Control moves to orders topic and STAYS there.
55
+ # User continues in that topic until another transition occurs.
56
+
57
+ # ═══════════════════════════════════════════════════════════════
58
+ # PATTERN 3: Manual Bidirectional (fallback pattern)
59
+ # ═══════════════════════════════════════════════════════════════
60
+
61
+ # If delegation doesn't work, use variables to track return:
62
+ # See: bidirectional-routing.agent for full implementation
63
+
64
+ variables:
65
+ return_topic: mutable string = ""
66
+ description: "Topic to return to after specialist"
67
+ specialist_result: mutable string = ""
68
+ description: "Result from specialist consultation"
69
+
70
+ # Before going to specialist, store return address:
71
+ # set @variables.return_topic = "main_hub"
72
+ # go_specialist: @utils.transition to @topic.specialist
73
+
74
+ # In specialist, transition back when done:
75
+ # return_home: @utils.transition to @topic.main_hub
76
+
77
+ # ═══════════════════════════════════════════════════════════════
78
+ # COMPARISON TABLE
79
+ # ═══════════════════════════════════════════════════════════════
80
+ #
81
+ # | Feature | Delegation | Transition |
82
+ # |----------------------|-------------------|-------------------------|
83
+ # | Syntax | @topic.name | @utils.transition to |
84
+ # | Returns to caller? | YES | NO |
85
+ # | Use in actions: | YES | YES |
86
+ # | Use in lifecycle: | NO | YES (bare syntax) |
87
+ # | Best for | Consult & return | Menu/workflow routing |
88
+ #
89
+ # ═══════════════════════════════════════════════════════════════
@@ -0,0 +1,127 @@
1
+ # Lifecycle Events Pattern
2
+ # Use before_reasoning and after_reasoning for initialization and cleanup
3
+ #
4
+ # ★ When To Use This Pattern:
5
+ # - Initialize state BEFORE the LLM starts reasoning
6
+ # - Track metrics (turn count, session duration)
7
+ # - Clean up or log AFTER reasoning completes
8
+ # - Set up context that instructions need to reference
9
+ #
10
+ # ★ Key Insight:
11
+ # - before_reasoning: Runs BEFORE each reasoning step (use for setup)
12
+ # - after_reasoning: Runs AFTER each reasoning step (use for cleanup/logging)
13
+ # - These are deterministic - they ALWAYS run, unlike LLM-chosen actions
14
+ #
15
+ # ★ CRITICAL SYNTAX RULES for Lifecycle Blocks:
16
+ # 1. Use "transition to" NOT "@utils.transition to" for transitions
17
+ # 2. The pipe (|) command is NOT supported in lifecycle blocks
18
+ # 3. after_reasoning may NOT run if a transition occurs mid-topic
19
+ # 4. `run` has inconsistent runtime behavior in lifecycle blocks —
20
+ # reliable primitives are `set`, `if`/`else`, `transition to`
21
+ #
22
+ # ★ Common Use Cases:
23
+ # - Increment conversation turn counter
24
+ # - Fetch fresh data before each response
25
+ # - Log conversation analytics after each turn
26
+ # - Reset temporary flags
27
+ # - Conditional routing based on state (use "transition to")
28
+ #
29
+ # This is a PARTIAL template - integrate into a complete agent file
30
+
31
+ # Variables needed for lifecycle tracking
32
+ variables:
33
+ # ... standard linked variables ...
34
+ turn_count: mutable number = 0
35
+ description: "Number of turns in conversation"
36
+ session_start: mutable string = ""
37
+ description: "Timestamp when session started"
38
+ last_activity: mutable string = ""
39
+ description: "Timestamp of last activity"
40
+ current_context: mutable string = ""
41
+ description: "Refreshed context for current turn"
42
+
43
+ topic conversation:
44
+ label: "Conversation"
45
+ description: "Main conversation topic with lifecycle tracking"
46
+
47
+ actions:
48
+ get_timestamp:
49
+ description: "Gets current timestamp"
50
+ outputs:
51
+ current_timestamp: string
52
+ description: "Current ISO timestamp"
53
+ target: "apex://TimeService.getCurrentTimestamp"
54
+
55
+ refresh_context:
56
+ description: "Fetches latest context for user"
57
+ inputs:
58
+ user_id: string
59
+ description: "User to get context for"
60
+ outputs:
61
+ context: string
62
+ description: "User's current context"
63
+ target: "flow://Get_User_Context"
64
+
65
+ log_turn:
66
+ description: "Logs conversation turn analytics"
67
+ inputs:
68
+ turn_number: number
69
+ description: "Which turn this is"
70
+ topic_name: string
71
+ description: "Current topic"
72
+ outputs:
73
+ logged: boolean
74
+ description: "Whether log succeeded"
75
+ target: "apex://AnalyticsService.logTurn"
76
+
77
+ # ★ before_reasoning: Runs BEFORE each reasoning step
78
+ before_reasoning:
79
+ # Increment turn counter
80
+ set @variables.turn_count = @variables.turn_count + 1
81
+
82
+ # On first turn, record session start
83
+ if @variables.turn_count == 1:
84
+ run @actions.get_timestamp
85
+ set @variables.session_start = @outputs.current_timestamp
86
+
87
+ # ★ CORRECT: Use "transition to" (not @utils.transition to) in lifecycle blocks
88
+ # Example: Route away if session expired
89
+ # if @variables.session_expired == True:
90
+ # transition to @topic.session_expired
91
+
92
+ # Refresh context before every turn
93
+ run @actions.refresh_context
94
+ with user_id=@variables.EndUserId
95
+ set @variables.current_context = @outputs.context
96
+
97
+ # Main reasoning block
98
+ reasoning:
99
+ instructions: ->
100
+ | You are on turn {!@variables.turn_count} of this conversation.
101
+ | Session started: {!@variables.session_start}
102
+ |
103
+ | Current user context:
104
+ | {!@variables.current_context}
105
+ |
106
+ | Respond helpfully using the refreshed context above.
107
+ actions:
108
+ end_conversation: @utils.transition to @topic.farewell
109
+
110
+ # ★ after_reasoning: Runs AFTER each reasoning step
111
+ after_reasoning:
112
+ # Log analytics for each turn
113
+ run @actions.log_turn
114
+ with turn_number=@variables.turn_count
115
+ with topic_name="conversation"
116
+
117
+ # Update last activity timestamp
118
+ run @actions.get_timestamp
119
+ set @variables.last_activity = @outputs.current_timestamp
120
+
121
+ # ★ Insight: Lifecycle blocks vs Action callbacks
122
+ #
123
+ # - before_reasoning/after_reasoning: Run every turn, automatic
124
+ # - run callbacks: Run only when parent action is invoked
125
+ #
126
+ # Use lifecycle for: Metrics, context refresh, session management
127
+ # Use callbacks for: Post-action processing, chained operations