@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.
- package/package.json +4 -4
- package/skills/agentforce-development/SKILL.md +427 -0
- package/skills/agentforce-development/assets/README-legacy.md +89 -0
- package/skills/agentforce-development/assets/agent-spec-template.md +90 -0
- package/skills/agentforce-development/assets/agents/README.md +45 -0
- package/skills/agentforce-development/assets/agents/hello-world.agent +60 -0
- package/skills/agentforce-development/assets/agents/multi-topic.agent +105 -0
- package/skills/agentforce-development/assets/agents/production-faq.agent +101 -0
- package/skills/agentforce-development/assets/agents/production-faq.bundle-meta.xml +4 -0
- package/skills/agentforce-development/assets/agents/simple-qa.agent +72 -0
- package/skills/agentforce-development/assets/apex/models-api-queueable.cls +225 -0
- package/skills/agentforce-development/assets/bundle-meta.xml +23 -0
- package/skills/agentforce-development/assets/components/apex-action.agent +52 -0
- package/skills/agentforce-development/assets/components/error-handling.agent +58 -0
- package/skills/agentforce-development/assets/components/escalation-setup.agent +169 -0
- package/skills/agentforce-development/assets/components/flow-action.agent +66 -0
- package/skills/agentforce-development/assets/components/n-ary-conditions.agent +110 -0
- package/skills/agentforce-development/assets/components/topic-with-actions.agent +40 -0
- package/skills/agentforce-development/assets/deterministic-routing.agent +166 -0
- package/skills/agentforce-development/assets/escalation-pattern.agent +209 -0
- package/skills/agentforce-development/assets/flow-action-lookup.agent +115 -0
- package/skills/agentforce-development/assets/hub-and-spoke.agent +104 -0
- package/skills/agentforce-development/assets/invocable-apex-template.cls +187 -0
- package/skills/agentforce-development/assets/local-info-agent-annotated.agent +355 -0
- package/skills/agentforce-development/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +109 -0
- package/skills/agentforce-development/assets/metadata/genai-function-apex.xml +92 -0
- package/skills/agentforce-development/assets/metadata/genai-function-flow.xml +57 -0
- package/skills/agentforce-development/assets/metadata/genai-plugin.xml +72 -0
- package/skills/agentforce-development/assets/metadata/http-callout-flow.flow-meta.xml +348 -0
- package/skills/agentforce-development/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +136 -0
- package/skills/agentforce-development/assets/minimal-starter.agent +42 -0
- package/skills/agentforce-development/assets/patterns/README.md +254 -0
- package/skills/agentforce-development/assets/patterns/action-callbacks.agent +178 -0
- package/skills/agentforce-development/assets/patterns/advanced-input-bindings.agent +141 -0
- package/skills/agentforce-development/assets/patterns/bidirectional-routing.agent +156 -0
- package/skills/agentforce-development/assets/patterns/critical-input-collection.agent +244 -0
- package/skills/agentforce-development/assets/patterns/delegation-routing.agent +89 -0
- package/skills/agentforce-development/assets/patterns/lifecycle-events.agent +127 -0
- package/skills/agentforce-development/assets/patterns/llm-controlled-actions.agent +184 -0
- package/skills/agentforce-development/assets/patterns/multi-step-workflow.agent +282 -0
- package/skills/agentforce-development/assets/patterns/open-gate-routing.agent +286 -0
- package/skills/agentforce-development/assets/patterns/procedural-instructions.agent +273 -0
- package/skills/agentforce-development/assets/patterns/prompt-template-action.agent +188 -0
- package/skills/agentforce-development/assets/patterns/system-instruction-overrides.agent +293 -0
- package/skills/agentforce-development/assets/prompt-rag-search.agent +131 -0
- package/skills/agentforce-development/assets/template-multi-topic.agent +160 -0
- package/skills/agentforce-development/assets/template-single-topic.agent +81 -0
- package/skills/agentforce-development/assets/verification-gate.agent +208 -0
- package/skills/agentforce-development/references/action-prompt-templates.md +164 -0
- package/skills/agentforce-development/references/actions-reference.md +592 -0
- package/skills/agentforce-development/references/agent-access-guide.md +72 -0
- package/skills/agentforce-development/references/agent-design-and-spec-creation.md +1010 -0
- package/skills/agentforce-development/references/agent-metadata-and-lifecycle.md +575 -0
- package/skills/agentforce-development/references/agent-script-core-language.md +1218 -0
- package/skills/agentforce-development/references/agent-topic-map-diagrams.md +323 -0
- package/skills/agentforce-development/references/agent-user-setup.md +526 -0
- package/skills/agentforce-development/references/agent-validation-and-debugging.md +803 -0
- package/skills/agentforce-development/references/known-issues.md +353 -0
- package/skills/agentforce-development/references/minimal-examples.md +67 -0
- package/skills/agentforce-development/references/production-gotchas.md +279 -0
- package/skills/agentforce-development/references/salesforce-cli-for-agents.md +393 -0
- package/skills/agentforce-development/references/version-history.md +23 -0
- package/skills/generate-permission-set/SKILL.md +174 -0
- package/skills/salesforce-custom-application/SKILL.md +1 -2
- package/skills/salesforce-custom-field/SKILL.md +0 -4
- package/skills/salesforce-custom-tab/SKILL.md +84 -8
- package/skills/salesforce-experience-lwr-site/SKILL.md +196 -0
- package/skills/salesforce-experience-lwr-site/docs/bootstrap-template-byo-lwr.md +224 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-brandingSet.md +131 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-route.md +232 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-themeLayout.md +141 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-content-view.md +233 -0
- package/skills/salesforce-experience-lwr-site/docs/configure-guest-sharing-rules.md +42 -0
- package/skills/salesforce-experience-lwr-site/docs/handle-component-and-region-ids.md +27 -0
- package/skills/salesforce-experience-lwr-site/docs/handle-ui-components.md +215 -0
- package/skills/salesforce-flow/SKILL.md +2 -2
- package/skills/salesforce-fragment/SKILL.md +85 -10
- package/skills/salesforce-lightning-app-build/SKILL.md +102 -10
- package/skills/apex-class/SKILL.md +0 -253
- package/skills/apex-class/examples/AccountDeduplicationBatch.cls +0 -148
- package/skills/apex-class/examples/AccountSelector.cls +0 -193
- package/skills/apex-class/examples/AccountService.cls +0 -201
- package/skills/apex-class/templates/abstract.cls +0 -128
- package/skills/apex-class/templates/batch.cls +0 -125
- package/skills/apex-class/templates/domain.cls +0 -102
- package/skills/apex-class/templates/dto.cls +0 -108
- package/skills/apex-class/templates/exception.cls +0 -51
- package/skills/apex-class/templates/interface.cls +0 -25
- package/skills/apex-class/templates/queueable.cls +0 -92
- package/skills/apex-class/templates/schedulable.cls +0 -75
- package/skills/apex-class/templates/selector.cls +0 -92
- package/skills/apex-class/templates/service.cls +0 -69
- package/skills/apex-class/templates/utility.cls +0 -97
- package/skills/apex-test-class/SKILL.md +0 -101
- package/skills/apex-test-class/references/assertion-patterns.md +0 -209
- package/skills/apex-test-class/references/async-testing.md +0 -276
- package/skills/apex-test-class/references/mocking-patterns.md +0 -219
- package/skills/apex-test-class/references/test-data-factory.md +0 -176
- package/skills/deployment-readiness-check/SKILL.md +0 -257
- package/skills/deployment-readiness-check/assets/deployment_checklist.md +0 -286
- package/skills/deployment-readiness-check/references/rollback_procedures.md +0 -308
- package/skills/deployment-readiness-check/scripts/check_metadata.sh +0 -207
- 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
|