mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 11:19:27 +08:00
@W-21955450@ Rename topic to subagent for Agent Script v2
Aligns with Agent Script v2 naming standards where `topic` is renamed to `subagent` across all skill documentation and templates. Changes: - Agent Script templates: topic keyword → subagent keyword - References: @topic.* → @subagent.* - Documentation: Updated all skill references and guides - Natural language references preserved in comments/descriptions
This commit is contained in:
parent
7b5c4b1a76
commit
df3467f20b
@ -46,11 +46,11 @@ start_agent topic_selector:
|
||||
| Route them to the most appropriate topic.
|
||||
| If unclear, ask clarifying questions.
|
||||
actions:
|
||||
go_to_topic_one: @utils.transition to @topic.{{topic_one_name}}
|
||||
go_to_topic_two: @utils.transition to @topic.{{topic_two_name}}
|
||||
go_to_topic_three: @utils.transition to @topic.{{topic_three_name}}
|
||||
go_to_farewell: @utils.transition to @topic.farewell
|
||||
go_to_escalation: @utils.transition to @topic.escalation
|
||||
go_to_topic_one: @utils.transition to @subagent.{{topic_one_name}}
|
||||
go_to_topic_two: @utils.transition to @subagent.{{topic_two_name}}
|
||||
go_to_topic_three: @utils.transition to @subagent.{{topic_three_name}}
|
||||
go_to_farewell: @utils.transition to @subagent.farewell
|
||||
go_to_escalation: @utils.transition to @subagent.escalation
|
||||
|
||||
topic {{topic_one_name}}:
|
||||
label: "{{TopicOneLabel}}"
|
||||
@ -60,7 +60,7 @@ topic {{topic_one_name}}:
|
||||
instructions: ->
|
||||
| {{TopicOneInstructions}}
|
||||
actions:
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic {{topic_two_name}}:
|
||||
label: "{{TopicTwoLabel}}"
|
||||
@ -70,7 +70,7 @@ topic {{topic_two_name}}:
|
||||
instructions: ->
|
||||
| {{TopicTwoInstructions}}
|
||||
actions:
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic {{topic_three_name}}:
|
||||
label: "{{TopicThreeLabel}}"
|
||||
@ -80,9 +80,9 @@ topic {{topic_three_name}}:
|
||||
instructions: ->
|
||||
| {{TopicThreeInstructions}}
|
||||
actions:
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic farewell:
|
||||
subagent farewell:
|
||||
label: "Farewell"
|
||||
description: "Ends the conversation gracefully"
|
||||
|
||||
@ -92,7 +92,7 @@ topic farewell:
|
||||
| Wish them a great day.
|
||||
| Let them know they can return anytime.
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Handles requests to transfer to a live human agent"
|
||||
|
||||
|
||||
@ -70,19 +70,19 @@ start_agent topic_selector:
|
||||
- Returns -> use to_returns
|
||||
- Tracking -> use to_tracking
|
||||
actions:
|
||||
to_verify: @utils.transition to @topic.verification
|
||||
to_verify: @utils.transition to @subagent.verification
|
||||
description: "Begin identity verification"
|
||||
to_orders: @utils.transition to @topic.order_status
|
||||
to_orders: @utils.transition to @subagent.order_status
|
||||
description: "Check order status"
|
||||
available when @variables.customer_verified == True
|
||||
to_returns: @utils.transition to @topic.returns
|
||||
to_returns: @utils.transition to @subagent.returns
|
||||
description: "Process a return"
|
||||
available when @variables.customer_verified == True
|
||||
to_tracking: @utils.transition to @topic.shipment_tracking
|
||||
to_tracking: @utils.transition to @subagent.shipment_tracking
|
||||
description: "Track a shipment"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
topic verification:
|
||||
subagent verification:
|
||||
label: "Identity Verification"
|
||||
description: "Verify customer identity before accessing order information"
|
||||
|
||||
@ -115,14 +115,14 @@ topic verification:
|
||||
set @variables.customer_verified = @outputs.verified
|
||||
set @variables.customer_email = @outputs.customer_name
|
||||
|
||||
proceed_to_orders: @utils.transition to @topic.order_status
|
||||
proceed_to_orders: @utils.transition to @subagent.order_status
|
||||
description: "Move to order lookup"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to human agent"
|
||||
|
||||
topic order_status:
|
||||
subagent order_status:
|
||||
label: "Order Status"
|
||||
description: "Look up order details and provide status updates"
|
||||
|
||||
@ -164,18 +164,18 @@ topic order_status:
|
||||
set @variables.order_status = @outputs.status
|
||||
set @variables.tracking_number = @outputs.tracking_number
|
||||
|
||||
to_returns: @utils.transition to @topic.returns
|
||||
to_returns: @utils.transition to @subagent.returns
|
||||
description: "Start a return"
|
||||
available when @variables.order_status != ""
|
||||
|
||||
to_tracking: @utils.transition to @topic.shipment_tracking
|
||||
to_tracking: @utils.transition to @subagent.shipment_tracking
|
||||
description: "Track shipment"
|
||||
available when @variables.tracking_number != ""
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
topic shipment_tracking:
|
||||
subagent shipment_tracking:
|
||||
label: "Shipment Tracking"
|
||||
description: "Track shipment status and estimated delivery"
|
||||
|
||||
@ -208,10 +208,10 @@ topic shipment_tracking:
|
||||
description: "Get tracking details"
|
||||
with tracking_number = @variables.tracking_number
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
topic returns:
|
||||
subagent returns:
|
||||
label: "Returns"
|
||||
description: "Process return requests and generate return labels"
|
||||
|
||||
@ -251,14 +251,14 @@ topic returns:
|
||||
set @variables.return_initiated = True
|
||||
set @variables.return_label_url = @outputs.return_label_url
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
after_reasoning: ->
|
||||
if @variables.return_initiated == True:
|
||||
transition to @topic.follow_up
|
||||
transition to @subagent.follow_up
|
||||
|
||||
topic follow_up:
|
||||
subagent follow_up:
|
||||
label: "Follow Up"
|
||||
description: "Handle follow-up actions and next steps"
|
||||
reasoning:
|
||||
@ -266,7 +266,7 @@ topic follow_up:
|
||||
The customer's request has been processed.
|
||||
Ask if there is anything else you can help with.
|
||||
actions:
|
||||
new_order: @utils.transition to @topic.order_status
|
||||
new_order: @utils.transition to @subagent.order_status
|
||||
description: "Look up another order"
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Start over"
|
||||
|
||||
@ -48,10 +48,10 @@ start_agent topic_selector:
|
||||
| If the question is about a specific topic, note it.
|
||||
| Route to the FAQ handler for processing.
|
||||
actions:
|
||||
handle_faq: @utils.transition to @topic.faq_handler
|
||||
end_conversation: @utils.transition to @topic.farewell
|
||||
handle_faq: @utils.transition to @subagent.faq_handler
|
||||
end_conversation: @utils.transition to @subagent.farewell
|
||||
|
||||
topic faq_handler:
|
||||
subagent faq_handler:
|
||||
label: "FAQ Handler"
|
||||
description: "Handles frequently asked questions and provides helpful answers"
|
||||
|
||||
@ -74,11 +74,11 @@ topic faq_handler:
|
||||
| - Suggest contacting customer support
|
||||
| - Offer to help with something else
|
||||
actions:
|
||||
new_question: @utils.transition to @topic.topic_selector
|
||||
end_conversation: @utils.transition to @topic.farewell
|
||||
escalate: @utils.transition to @topic.escalation
|
||||
new_question: @utils.transition to @subagent.topic_selector
|
||||
end_conversation: @utils.transition to @subagent.farewell
|
||||
escalate: @utils.transition to @subagent.escalation
|
||||
|
||||
topic farewell:
|
||||
subagent farewell:
|
||||
label: "Farewell"
|
||||
description: "Ends the conversation politely"
|
||||
|
||||
@ -88,7 +88,7 @@ topic farewell:
|
||||
| Wish them a great day.
|
||||
| Let them know they can return anytime for more help.
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Handles requests to speak with a human agent"
|
||||
|
||||
|
||||
@ -44,10 +44,10 @@ start_agent topic_selector:
|
||||
| Listen to the user's question.
|
||||
| Route to the Q&A handler for processing.
|
||||
actions:
|
||||
handle_question: @utils.transition to @topic.qa_handler
|
||||
end_conversation: @utils.transition to @topic.farewell
|
||||
handle_question: @utils.transition to @subagent.qa_handler
|
||||
end_conversation: @utils.transition to @subagent.farewell
|
||||
|
||||
topic qa_handler:
|
||||
subagent qa_handler:
|
||||
label: "Q&A Handler"
|
||||
description: "Handles questions and provides answers"
|
||||
|
||||
@ -58,10 +58,10 @@ topic qa_handler:
|
||||
| Keep responses clear and easy to understand.
|
||||
| If you need more information, ask clarifying questions.
|
||||
actions:
|
||||
new_question: @utils.transition to @topic.topic_selector
|
||||
end_conversation: @utils.transition to @topic.farewell
|
||||
new_question: @utils.transition to @subagent.topic_selector
|
||||
end_conversation: @utils.transition to @subagent.farewell
|
||||
|
||||
topic farewell:
|
||||
subagent farewell:
|
||||
label: "Farewell"
|
||||
description: "Ends the conversation gracefully"
|
||||
|
||||
|
||||
@ -68,16 +68,16 @@ start_agent topic_selector:
|
||||
- Account questions -> use to_account
|
||||
- Refund requests -> use to_refund
|
||||
actions:
|
||||
to_verify: @utils.transition to @topic.identity_verification
|
||||
to_verify: @utils.transition to @subagent.identity_verification
|
||||
description: "Begin identity verification"
|
||||
to_account: @utils.transition to @topic.account_management
|
||||
to_account: @utils.transition to @subagent.account_management
|
||||
description: "Access account settings"
|
||||
available when @variables.customer_verified == True
|
||||
to_refund: @utils.transition to @topic.refund_processor
|
||||
to_refund: @utils.transition to @subagent.refund_processor
|
||||
description: "Process a refund request"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
topic identity_verification:
|
||||
subagent identity_verification:
|
||||
label: "Identity Verification"
|
||||
description: "Verify customer identity before proceeding"
|
||||
|
||||
@ -96,7 +96,7 @@ topic identity_verification:
|
||||
instructions: ->
|
||||
if @variables.failed_attempts >= 3:
|
||||
| Too many failed attempts. Transferring to a human agent.
|
||||
transition to @topic.escalation
|
||||
transition to @subagent.escalation
|
||||
|
||||
if @variables.customer_verified == True:
|
||||
| Identity verified! How can I help you today?
|
||||
@ -110,18 +110,18 @@ topic identity_verification:
|
||||
with email = ...
|
||||
set @variables.customer_verified = @outputs.verified
|
||||
|
||||
go_to_account: @utils.transition to @topic.account_management
|
||||
go_to_account: @utils.transition to @subagent.account_management
|
||||
description: "Access account settings"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
go_to_refund: @utils.transition to @topic.refund_processor
|
||||
go_to_refund: @utils.transition to @subagent.refund_processor
|
||||
description: "Process a refund request"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to human agent"
|
||||
|
||||
topic account_management:
|
||||
subagent account_management:
|
||||
label: "Account Management"
|
||||
description: "Manage customer account settings (requires verification)"
|
||||
|
||||
@ -151,7 +151,7 @@ topic account_management:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
if @variables.customer_verified == False:
|
||||
transition to @topic.identity_verification
|
||||
transition to @subagent.identity_verification
|
||||
|
||||
| Welcome to account management.
|
||||
| What would you like to do with your account?
|
||||
@ -169,10 +169,10 @@ topic account_management:
|
||||
with pref_value = ...
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
|
||||
topic refund_processor:
|
||||
subagent refund_processor:
|
||||
label: "Refund Processor"
|
||||
description: "Process refund requests (requires verification)"
|
||||
|
||||
@ -225,13 +225,13 @@ topic refund_processor:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
if @variables.customer_verified == False:
|
||||
transition to @topic.identity_verification
|
||||
transition to @subagent.identity_verification
|
||||
|
||||
if @variables.refund_status == "Approved":
|
||||
run @actions.create_crm_case
|
||||
with customer_id = @variables.ContactId
|
||||
with refund_amount = @variables.refund_amount
|
||||
transition to @topic.success_confirmation
|
||||
transition to @subagent.success_confirmation
|
||||
|
||||
run @actions.check_churn_risk
|
||||
with customer_id = @variables.ContactId
|
||||
@ -257,7 +257,7 @@ topic refund_processor:
|
||||
with amount = 10
|
||||
set @variables.refund_status = @outputs.status
|
||||
|
||||
topic success_confirmation:
|
||||
subagent success_confirmation:
|
||||
label: "Success Confirmation"
|
||||
description: "Confirm successful operation"
|
||||
reasoning:
|
||||
@ -265,10 +265,10 @@ topic success_confirmation:
|
||||
Great news! Your request has been processed successfully.
|
||||
Is there anything else I can help you with?
|
||||
actions:
|
||||
new_request: @utils.transition to @topic.topic_selector
|
||||
new_request: @utils.transition to @subagent.topic_selector
|
||||
description: "Start a new request"
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Escalate to human agent"
|
||||
reasoning:
|
||||
|
||||
@ -52,7 +52,7 @@ topic {{topic_name}}:
|
||||
available when @variables.validation_passed == True
|
||||
|
||||
# Handle errors
|
||||
retry_operation: @utils.transition to @topic.{{topic_name}}
|
||||
retry_operation: @utils.transition to @subagent.{{topic_name}}
|
||||
available when @variables.operation_success == False
|
||||
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
@ -93,11 +93,11 @@ start_agent topic_selector:
|
||||
| If they ask for a human or live agent, route to escalation.
|
||||
| Otherwise, try to help them directly.
|
||||
actions:
|
||||
go_help: @utils.transition to @topic.help
|
||||
go_escalation: @utils.transition to @topic.escalation
|
||||
go_help: @utils.transition to @subagent.help
|
||||
go_escalation: @utils.transition to @subagent.escalation
|
||||
available when @variables.escalation_requested == True
|
||||
|
||||
topic help:
|
||||
subagent help:
|
||||
label: "Help"
|
||||
description: "Provides assistance to customers"
|
||||
|
||||
@ -117,11 +117,11 @@ topic help:
|
||||
| Track escalation reason if provided:
|
||||
set @variables.escalation_reason = ...
|
||||
actions:
|
||||
offer_escalation: @utils.transition to @topic.escalation
|
||||
offer_escalation: @utils.transition to @subagent.escalation
|
||||
|
||||
immediate_escalation: @utils.transition to @topic.escalation
|
||||
immediate_escalation: @utils.transition to @subagent.escalation
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Transfers conversation to human agent"
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
# | Help the user with their request.
|
||||
# | Use the available actions when needed.
|
||||
# actions:
|
||||
# back_to_menu: @utils.transition to @topic.topic_selector
|
||||
# back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# Common Flow Target Patterns:
|
||||
# - flow://Get_Account_Details
|
||||
|
||||
@ -23,14 +23,14 @@
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
# Example: Require multiple authentication checks
|
||||
topic secure_action:
|
||||
subagent secure_action:
|
||||
label: "Secure Action"
|
||||
description: "Performs security-sensitive operations"
|
||||
|
||||
before_reasoning:
|
||||
# All three conditions must be true
|
||||
if @variables.is_authenticated and @variables.has_permission and @variables.session_valid:
|
||||
transition to @topic.authorized_action
|
||||
transition to @subagent.authorized_action
|
||||
# Otherwise stay in this topic
|
||||
|
||||
reasoning:
|
||||
@ -42,22 +42,22 @@ topic secure_action:
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
# Example: Any elevated role gets access
|
||||
topic admin_panel:
|
||||
subagent admin_panel:
|
||||
label: "Admin Panel"
|
||||
description: "Administrative features"
|
||||
|
||||
before_reasoning:
|
||||
# Any one of these roles grants access
|
||||
if @variables.is_admin or @variables.is_moderator or @variables.is_superuser:
|
||||
transition to @topic.admin_features
|
||||
transition to @subagent.admin_features
|
||||
# Non-admins redirected
|
||||
transition to @topic.access_denied
|
||||
transition to @subagent.access_denied
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# PATTERN 3: N-ary conditions in available when
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
topic order_management:
|
||||
subagent order_management:
|
||||
label: "Order Management"
|
||||
description: "Handles order operations"
|
||||
|
||||
@ -84,14 +84,14 @@ topic order_management:
|
||||
# PATTERN 4: Complex grouped conditions
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
topic smart_routing:
|
||||
subagent smart_routing:
|
||||
label: "Smart Routing"
|
||||
description: "Routes based on complex criteria"
|
||||
|
||||
before_reasoning:
|
||||
# Premium with any product type OR standard with warranty
|
||||
if (@variables.tier == "premium" and @variables.product_type != None) or (@variables.tier == "standard" and @variables.has_warranty == True):
|
||||
transition to @topic.priority_support
|
||||
transition to @subagent.priority_support
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# ANTI-PATTERNS - DO NOT USE
|
||||
@ -102,9 +102,9 @@ topic smart_routing:
|
||||
# if @variables.a == True:
|
||||
# if @variables.b == True:
|
||||
# if @variables.c == True:
|
||||
# transition to @topic.x
|
||||
# transition to @subagent.x
|
||||
|
||||
# ✅ CORRECT - Flat N-ary condition
|
||||
# before_reasoning:
|
||||
# if @variables.a == True and @variables.b == True and @variables.c == True:
|
||||
# transition to @topic.x
|
||||
# transition to @subagent.x
|
||||
|
||||
@ -36,5 +36,5 @@ topic {{topic_name}}:
|
||||
with {{input_name}}=...
|
||||
set @variables.{{result_variable}} = @outputs.{{output_name}}
|
||||
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
|
||||
@ -54,13 +54,13 @@ start_agent topic_selector:
|
||||
# HIGH-CONFIDENCE ROUTING
|
||||
if @variables.confidence_score >= 80:
|
||||
if @variables.classified_intent == "billing":
|
||||
transition to @topic.billing
|
||||
transition to @subagent.billing
|
||||
if @variables.classified_intent == "technical_support":
|
||||
transition to @topic.technical_support
|
||||
transition to @subagent.technical_support
|
||||
if @variables.classified_intent == "sales":
|
||||
transition to @topic.sales
|
||||
transition to @subagent.sales
|
||||
if @variables.classified_intent == "returns":
|
||||
transition to @topic.returns
|
||||
transition to @subagent.returns
|
||||
|
||||
# LOW-CONFIDENCE: Confirm with user
|
||||
if @variables.confidence_score < 80:
|
||||
@ -88,19 +88,19 @@ start_agent topic_selector:
|
||||
set @variables.needs_classification = False
|
||||
|
||||
# Manual routing for low-confidence cases
|
||||
go_billing: @utils.transition to @topic.billing
|
||||
go_billing: @utils.transition to @subagent.billing
|
||||
description: "Yes, I need billing help"
|
||||
available when @variables.low_confidence_warning == True and @variables.classified_intent == "billing"
|
||||
|
||||
go_support: @utils.transition to @topic.technical_support
|
||||
go_support: @utils.transition to @subagent.technical_support
|
||||
description: "Yes, I need technical support"
|
||||
available when @variables.low_confidence_warning == True and @variables.classified_intent == "technical_support"
|
||||
|
||||
go_sales: @utils.transition to @topic.sales
|
||||
go_sales: @utils.transition to @subagent.sales
|
||||
description: "Yes, I need sales help"
|
||||
available when @variables.low_confidence_warning == True and @variables.classified_intent == "sales"
|
||||
|
||||
go_returns: @utils.transition to @topic.returns
|
||||
go_returns: @utils.transition to @subagent.returns
|
||||
description: "Yes, I need returns help"
|
||||
available when @variables.low_confidence_warning == True and @variables.classified_intent == "returns"
|
||||
|
||||
@ -117,50 +117,50 @@ start_agent topic_selector:
|
||||
# ROUTED TOPICS
|
||||
# ============================================================
|
||||
|
||||
topic billing:
|
||||
subagent billing:
|
||||
description: "Handle billing inquiries"
|
||||
reasoning:
|
||||
instructions: |
|
||||
Help the customer with their billing question.
|
||||
You can view invoices, explain charges, or process payments.
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to billing specialist"
|
||||
|
||||
topic technical_support:
|
||||
subagent technical_support:
|
||||
description: "Handle technical support issues"
|
||||
reasoning:
|
||||
instructions: |
|
||||
Help the customer with their technical issue.
|
||||
Troubleshoot problems and provide solutions.
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to technical specialist"
|
||||
|
||||
topic sales:
|
||||
subagent sales:
|
||||
description: "Handle sales inquiries"
|
||||
reasoning:
|
||||
instructions: |
|
||||
Help the customer with sales questions.
|
||||
Provide product information and pricing.
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to sales representative"
|
||||
|
||||
topic returns:
|
||||
subagent returns:
|
||||
description: "Handle return requests"
|
||||
reasoning:
|
||||
instructions: |
|
||||
Help the customer with their return request.
|
||||
Check eligibility and process returns.
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to returns specialist"
|
||||
|
||||
@ -72,20 +72,20 @@ start_agent entry:
|
||||
Greet the customer and understand their needs.
|
||||
Try to help directly, escalate if needed.
|
||||
actions:
|
||||
go_support: @utils.transition to @topic.support
|
||||
go_support: @utils.transition to @subagent.support
|
||||
description: "Help with support issue"
|
||||
|
||||
# ============================================================
|
||||
# SUPPORT TOPIC (With Escalation Triggers)
|
||||
# ============================================================
|
||||
|
||||
topic support:
|
||||
subagent support:
|
||||
description: "Attempt to resolve issue, escalate if unable"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
# POST-ACTION: Check if escalation was triggered
|
||||
if @variables.ready_to_escalate == True:
|
||||
transition to @topic.pre_escalation
|
||||
transition to @subagent.pre_escalation
|
||||
|
||||
# Track attempts
|
||||
| I'm here to help you with your issue.
|
||||
@ -120,7 +120,7 @@ topic support:
|
||||
# PRE-ESCALATION TOPIC (Gather Context)
|
||||
# ============================================================
|
||||
|
||||
topic pre_escalation:
|
||||
subagent pre_escalation:
|
||||
description: "Gather information before escalating"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -138,7 +138,7 @@ topic pre_escalation:
|
||||
| - Reason for transfer: {!@variables.escalation_reason}
|
||||
|
|
||||
| Ready to connect you now.
|
||||
transition to @topic.escalation
|
||||
transition to @subagent.escalation
|
||||
|
||||
actions:
|
||||
# Capture customer name
|
||||
@ -148,7 +148,7 @@ topic pre_escalation:
|
||||
with customer_name = ... # LLM extracts name from response
|
||||
|
||||
# Proceed to escalation
|
||||
proceed: @utils.transition to @topic.escalation
|
||||
proceed: @utils.transition to @subagent.escalation
|
||||
description: "Proceed with transfer"
|
||||
available when @variables.customer_name != ""
|
||||
|
||||
@ -157,13 +157,13 @@ topic pre_escalation:
|
||||
description: "Actually, let me try again with the bot"
|
||||
with ready_to_escalate = False
|
||||
with escalation_reason = ""
|
||||
run @utils.transition to @topic.support
|
||||
run @utils.transition to @subagent.support
|
||||
|
||||
# ============================================================
|
||||
# ESCALATION TOPIC (Handoff)
|
||||
# ============================================================
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
description: "Execute escalation to human agent"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -186,7 +186,7 @@ topic escalation:
|
||||
# OPTIONAL: SPECIALIZED ESCALATION QUEUES
|
||||
# ============================================================
|
||||
|
||||
topic escalate_billing:
|
||||
subagent escalate_billing:
|
||||
description: "Escalate specifically to billing team"
|
||||
reasoning:
|
||||
instructions: |
|
||||
@ -198,7 +198,7 @@ topic escalate_billing:
|
||||
billing_handoff: @utils.escalate
|
||||
description: "Transfer to billing team"
|
||||
|
||||
topic escalate_technical:
|
||||
subagent escalate_technical:
|
||||
description: "Escalate specifically to technical support"
|
||||
reasoning:
|
||||
instructions: |
|
||||
|
||||
@ -50,14 +50,14 @@ start_agent entry:
|
||||
instructions: |
|
||||
Welcome the customer and offer to help with order lookups.
|
||||
actions:
|
||||
go_lookup: @utils.transition to @topic.order_lookup
|
||||
go_lookup: @utils.transition to @subagent.order_lookup
|
||||
description: "Start order lookup"
|
||||
|
||||
# ============================================================
|
||||
# ORDER LOOKUP TOPIC (Flow Action Pattern)
|
||||
# ============================================================
|
||||
|
||||
topic order_lookup:
|
||||
subagent order_lookup:
|
||||
description: "Look up order details using Flow action"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
|
||||
@ -41,18 +41,18 @@ start_agent topic_selector:
|
||||
- Return/refund requests → returns topic
|
||||
- General questions → support topic
|
||||
actions:
|
||||
check_order: @utils.transition to @topic.orders
|
||||
check_order: @utils.transition to @subagent.orders
|
||||
description: "Customer wants to check order status"
|
||||
process_return: @utils.transition to @topic.returns
|
||||
process_return: @utils.transition to @subagent.returns
|
||||
description: "Customer wants to return or refund"
|
||||
general_help: @utils.transition to @topic.support
|
||||
general_help: @utils.transition to @subagent.support
|
||||
description: "General support questions"
|
||||
|
||||
# ============================================================
|
||||
# SPOKE: Orders Topic
|
||||
# ============================================================
|
||||
|
||||
topic orders:
|
||||
subagent orders:
|
||||
description: "Handle order status and tracking inquiries"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -65,14 +65,14 @@ topic orders:
|
||||
lookup_order: @actions.get_order_status
|
||||
description: "Look up order details"
|
||||
with order_id = @variables.order_id
|
||||
back_to_hub: @utils.transition to @topic.topic_selector
|
||||
back_to_hub: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
|
||||
# ============================================================
|
||||
# SPOKE: Returns Topic
|
||||
# ============================================================
|
||||
|
||||
topic returns:
|
||||
subagent returns:
|
||||
description: "Handle return and refund requests"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -84,14 +84,14 @@ topic returns:
|
||||
description: "Start a return process"
|
||||
process_refund: @actions.process_refund
|
||||
description: "Process a refund"
|
||||
back_to_hub: @utils.transition to @topic.topic_selector
|
||||
back_to_hub: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
|
||||
# ============================================================
|
||||
# SPOKE: Support Topic
|
||||
# ============================================================
|
||||
|
||||
topic support:
|
||||
subagent support:
|
||||
description: "Handle general support questions"
|
||||
reasoning:
|
||||
instructions: |
|
||||
@ -100,5 +100,5 @@ topic support:
|
||||
actions:
|
||||
escalate: @utils.escalate
|
||||
description: "Transfer to human agent"
|
||||
back_to_hub: @utils.transition to @topic.topic_selector
|
||||
back_to_hub: @utils.transition to @subagent.topic_selector
|
||||
description: "Return to main menu"
|
||||
|
||||
@ -69,17 +69,17 @@ start_agent topic_selector:
|
||||
# Each action is a transition to a topic.
|
||||
# The runtime matches the user's utterance against topic descriptions
|
||||
# and selects the best transition.
|
||||
go_to_local_weather: @utils.transition to @topic.local_weather
|
||||
go_to_local_events: @utils.transition to @topic.local_events
|
||||
go_to_resort_hours: @utils.transition to @topic.resort_hours
|
||||
go_to_escalation: @utils.transition to @topic.escalation
|
||||
go_to_off_topic: @utils.transition to @topic.off_topic
|
||||
go_to_ambiguous_question: @utils.transition to @topic.ambiguous_question
|
||||
go_to_local_weather: @utils.transition to @subagent.local_weather
|
||||
go_to_local_events: @utils.transition to @subagent.local_events
|
||||
go_to_resort_hours: @utils.transition to @subagent.resort_hours
|
||||
go_to_escalation: @utils.transition to @subagent.escalation
|
||||
go_to_off_topic: @utils.transition to @subagent.off_topic
|
||||
go_to_ambiguous_question: @utils.transition to @subagent.ambiguous_question
|
||||
|
||||
# --- ESCALATION TOPIC ---
|
||||
# Handles requests to transfer to a live human agent.
|
||||
# Uses the built-in @utils.escalate utility.
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Handles requests from users who want to transfer or escalate their conversation to a live human agent."
|
||||
|
||||
@ -96,7 +96,7 @@ topic escalation:
|
||||
# --- OFF-TOPIC TOPIC ---
|
||||
# Catches utterances that don't match any functional topic.
|
||||
# No actions — just instruction-driven redirection.
|
||||
topic off_topic:
|
||||
subagent off_topic:
|
||||
label: "Off Topic"
|
||||
description: "Redirect conversation to relevant topics when user request goes off-topic"
|
||||
|
||||
@ -121,7 +121,7 @@ topic off_topic:
|
||||
# --- AMBIGUOUS QUESTION TOPIC ---
|
||||
# Similar to off_topic but for unclear requests that might map to a real topic
|
||||
# if the user provides more detail.
|
||||
topic ambiguous_question:
|
||||
subagent ambiguous_question:
|
||||
label: "Ambiguous Question"
|
||||
description: "Redirect conversation to relevant topics when user request is too ambiguous"
|
||||
|
||||
@ -147,7 +147,7 @@ topic ambiguous_question:
|
||||
# --- LOCAL WEATHER TOPIC ---
|
||||
# Demonstrates: action with Apex backing, input parameters, output fields,
|
||||
# progress indicators, and detailed reasoning instructions.
|
||||
topic local_weather:
|
||||
subagent local_weather:
|
||||
label: "Local Weather"
|
||||
description: "This topic addresses customer inquiries related to current and forecast weather conditions at Coral Cloud Resort, including temperature, chance of rain, and other weather details."
|
||||
|
||||
@ -222,7 +222,7 @@ topic local_weather:
|
||||
# --- LOCAL EVENTS TOPIC ---
|
||||
# Demonstrates: gating logic (available when), @utils.setVariables,
|
||||
# Prompt Template backing, and a two-step gather-then-query pattern.
|
||||
topic local_events:
|
||||
subagent local_events:
|
||||
label: "Local Events"
|
||||
description: "This topic provides details about local events happening outside of Coral Cloud Resort in Port Aurelia. Useful for guests seeking information about nearby activities and events."
|
||||
|
||||
@ -288,7 +288,7 @@ topic local_events:
|
||||
# Demonstrates: Flow backing, output-to-variable binding (set),
|
||||
# conditional instructions (if/else on a variable), and multiple
|
||||
# input parameters.
|
||||
topic resort_hours:
|
||||
subagent resort_hours:
|
||||
label: "Resort Hours"
|
||||
description: "This topic helps guests find operating hours and reservation requirements for resort facilities at Coral Cloud Resort, including the spa, pool, restaurant, and fitness center."
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ config:
|
||||
# session_id: linked string
|
||||
# source: @session.sessionID
|
||||
|
||||
topic main:
|
||||
subagent main:
|
||||
description: "Main conversation handler"
|
||||
reasoning:
|
||||
instructions: |
|
||||
@ -38,5 +38,5 @@ start_agent entry:
|
||||
instructions: |
|
||||
Greet the user and route to the main topic.
|
||||
actions:
|
||||
begin: @utils.transition to @topic.main
|
||||
begin: @utils.transition to @subagent.main
|
||||
description: "Start the main conversation"
|
||||
|
||||
@ -71,7 +71,7 @@ process_order: @actions.create_order
|
||||
|
||||
**Key syntax**:
|
||||
```agentscript
|
||||
topic conversation:
|
||||
subagent conversation:
|
||||
before_reasoning:
|
||||
set @variables.turn_count = @variables.turn_count + 1
|
||||
run @actions.refresh_context
|
||||
@ -99,7 +99,7 @@ topic conversation:
|
||||
**Key syntax**:
|
||||
```agentscript
|
||||
# In main topic
|
||||
consult_pricing: @utils.transition to @topic.pricing_specialist
|
||||
consult_pricing: @utils.transition to @subagent.pricing_specialist
|
||||
|
||||
# In specialist topic
|
||||
before_reasoning:
|
||||
@ -107,7 +107,7 @@ before_reasoning:
|
||||
|
||||
# ... do specialist work ...
|
||||
|
||||
return_with_results: @utils.transition to @topic.main_hub
|
||||
return_with_results: @utils.transition to @subagent.main_hub
|
||||
```
|
||||
|
||||
---
|
||||
@ -205,9 +205,9 @@ reasoning:
|
||||
# topic_selector bypasses LLM when open_gate is set
|
||||
before_reasoning:
|
||||
if @variables.open_gate == "protected_workflow":
|
||||
transition to @topic.protected_workflow
|
||||
transition to @subagent.protected_workflow
|
||||
if @variables.open_gate == "authentication_gate":
|
||||
transition to @topic.authentication_gate
|
||||
transition to @subagent.authentication_gate
|
||||
```
|
||||
|
||||
**Credit**: Hua Xu (Salesforce APAC FDE team) — production pattern from Kogan agent deployment.
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
#
|
||||
# This is a PARTIAL template - integrate into a complete agent file
|
||||
|
||||
topic order_processing:
|
||||
subagent order_processing:
|
||||
label: "Order Processing"
|
||||
description: "Processes orders with guaranteed confirmation and logging"
|
||||
|
||||
@ -84,7 +84,7 @@ topic order_processing:
|
||||
with event_type="ORDER_CREATED"
|
||||
with details=@variables.order_id
|
||||
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# ★ Anti-Pattern: Nested run (DO NOT DO THIS)
|
||||
#
|
||||
@ -111,7 +111,7 @@ topic order_processing:
|
||||
#
|
||||
# Example: Create case and track count (works in BOTH bundle types)
|
||||
|
||||
topic case_management:
|
||||
subagent case_management:
|
||||
label: "Case Management"
|
||||
description: "Creates cases and tracks statistics"
|
||||
|
||||
@ -143,7 +143,7 @@ topic case_management:
|
||||
set @variables.case_id = @outputs.out_CaseId
|
||||
set @variables.cases_created = @variables.cases_created + 1 # Direct increment!
|
||||
|
||||
back_to_menu: @utils.transition to @topic.topic_selector
|
||||
back_to_menu: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# ⛔ INVALID KEYWORDS - NEVER USE THESE
|
||||
|
||||
@ -32,7 +32,7 @@ variables:
|
||||
status: mutable string = ""
|
||||
description: "Current operation status"
|
||||
|
||||
topic order_processing:
|
||||
subagent order_processing:
|
||||
label: "Order Processing"
|
||||
description: "Demonstrates advanced input binding patterns"
|
||||
|
||||
|
||||
@ -46,17 +46,17 @@ start_agent main_hub:
|
||||
| Consultation status: {!@variables.consultation_status}
|
||||
actions:
|
||||
# Route to pricing specialist (store return address first)
|
||||
consult_pricing: @utils.transition to @topic.pricing_specialist
|
||||
consult_pricing: @utils.transition to @subagent.pricing_specialist
|
||||
available when @variables.consultation_status != "in_progress"
|
||||
|
||||
# Route to technical specialist
|
||||
consult_technical: @utils.transition to @topic.technical_specialist
|
||||
consult_technical: @utils.transition to @subagent.technical_specialist
|
||||
available when @variables.consultation_status != "in_progress"
|
||||
|
||||
end_conversation: @utils.transition to @topic.farewell
|
||||
end_conversation: @utils.transition to @subagent.farewell
|
||||
|
||||
# Pricing specialist topic
|
||||
topic pricing_specialist:
|
||||
subagent pricing_specialist:
|
||||
label: "Pricing Specialist"
|
||||
description: "Handles complex pricing calculations and returns results"
|
||||
|
||||
@ -93,14 +93,14 @@ topic pricing_specialist:
|
||||
set @variables.specialist_result = @outputs.final_price
|
||||
|
||||
# Return to main hub with results
|
||||
return_with_results: @utils.transition to @topic.main_hub
|
||||
return_with_results: @utils.transition to @subagent.main_hub
|
||||
|
||||
# Mark consultation complete when leaving
|
||||
after_reasoning:
|
||||
set @variables.consultation_status = "completed"
|
||||
|
||||
# Technical specialist topic
|
||||
topic technical_specialist:
|
||||
subagent technical_specialist:
|
||||
label: "Technical Specialist"
|
||||
description: "Handles technical troubleshooting and returns results"
|
||||
|
||||
@ -132,12 +132,12 @@ topic technical_specialist:
|
||||
with symptoms=...
|
||||
set @variables.specialist_result = @outputs.diagnosis
|
||||
|
||||
return_with_results: @utils.transition to @topic.main_hub
|
||||
return_with_results: @utils.transition to @subagent.main_hub
|
||||
|
||||
after_reasoning:
|
||||
set @variables.consultation_status = "completed"
|
||||
|
||||
topic farewell:
|
||||
subagent farewell:
|
||||
label: "Farewell"
|
||||
description: "Ends the conversation"
|
||||
|
||||
@ -150,7 +150,7 @@ topic farewell:
|
||||
# If the specialist doesn't need to return results to a coordinator,
|
||||
# use simple transitions without the return_topic pattern:
|
||||
#
|
||||
# go_orders: @utils.transition to @topic.orders
|
||||
# go_billing: @utils.transition to @topic.billing
|
||||
# go_orders: @utils.transition to @subagent.orders
|
||||
# go_billing: @utils.transition to @subagent.billing
|
||||
#
|
||||
# The bidirectional pattern adds complexity - only use when needed.
|
||||
|
||||
@ -148,11 +148,11 @@ start_agent input_collector:
|
||||
|
||||
# ★ PATTERN 4: Null Guard Pattern
|
||||
# Transition ONLY available when input is validated
|
||||
go_research: @utils.transition to @topic.research
|
||||
go_research: @utils.transition to @subagent.research
|
||||
available when @variables.account_id_validated == True
|
||||
|
||||
# ★ RESEARCH TOPIC: Only accessible after input is validated
|
||||
topic research:
|
||||
subagent research:
|
||||
label: "Account Research"
|
||||
description: "Performs research on the validated account"
|
||||
|
||||
@ -194,7 +194,7 @@ topic research:
|
||||
available when @variables.research_summary == ""
|
||||
|
||||
# Return to collector for new account
|
||||
new_account: @utils.transition to @topic.input_collector
|
||||
new_account: @utils.transition to @subagent.input_collector
|
||||
available when @variables.research_summary != ""
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
#
|
||||
# ★ KEY CONCEPTS:
|
||||
#
|
||||
# DELEGATION (@topic.* syntax):
|
||||
# - Syntax: action_name: @topic.topic_name
|
||||
# DELEGATION (@subagent.* syntax):
|
||||
# - Syntax: action_name: @subagent.topic_name
|
||||
# - Control CAN return to the calling topic
|
||||
# - Use for: consulting specialists, sub-tasks, getting help
|
||||
#
|
||||
# TRANSITION (@utils.transition syntax):
|
||||
# - Syntax: action_name: @utils.transition to @topic.topic_name
|
||||
# - Syntax: action_name: @utils.transition to @subagent.topic_name
|
||||
# - PERMANENT handoff - control does NOT return
|
||||
# - Use for: menu navigation, workflow stages, permanent routing
|
||||
#
|
||||
@ -33,7 +33,7 @@
|
||||
# reasoning:
|
||||
# actions:
|
||||
# # Delegation - specialist CAN return control to this topic
|
||||
# consult_expert: @topic.specialist_topic
|
||||
# consult_expert: @subagent.specialist_topic
|
||||
# description: "Consult specialist for complex questions"
|
||||
# available when @variables.needs_expert_help == True
|
||||
#
|
||||
@ -49,7 +49,7 @@
|
||||
# reasoning:
|
||||
# actions:
|
||||
# # Transition - permanent move to orders topic
|
||||
# go_orders: @utils.transition to @topic.orders
|
||||
# go_orders: @utils.transition to @subagent.orders
|
||||
#
|
||||
# Control moves to orders topic and STAYS there.
|
||||
# User continues in that topic until another transition occurs.
|
||||
@ -69,10 +69,10 @@ variables:
|
||||
|
||||
# Before going to specialist, store return address:
|
||||
# set @variables.return_topic = "main_hub"
|
||||
# go_specialist: @utils.transition to @topic.specialist
|
||||
# go_specialist: @utils.transition to @subagent.specialist
|
||||
|
||||
# In specialist, transition back when done:
|
||||
# return_home: @utils.transition to @topic.main_hub
|
||||
# return_home: @utils.transition to @subagent.main_hub
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# COMPARISON TABLE
|
||||
@ -80,7 +80,7 @@ variables:
|
||||
#
|
||||
# | Feature | Delegation | Transition |
|
||||
# |----------------------|-------------------|-------------------------|
|
||||
# | Syntax | @topic.name | @utils.transition to |
|
||||
# | Syntax | @subagent.name | @utils.transition to |
|
||||
# | Returns to caller? | YES | NO |
|
||||
# | Use in actions: | YES | YES |
|
||||
# | Use in lifecycle: | NO | YES (bare syntax) |
|
||||
|
||||
@ -40,7 +40,7 @@ variables:
|
||||
current_context: mutable string = ""
|
||||
description: "Refreshed context for current turn"
|
||||
|
||||
topic conversation:
|
||||
subagent conversation:
|
||||
label: "Conversation"
|
||||
description: "Main conversation topic with lifecycle tracking"
|
||||
|
||||
@ -87,7 +87,7 @@ topic conversation:
|
||||
# ★ CORRECT: Use "transition to" (not @utils.transition to) in lifecycle blocks
|
||||
# Example: Route away if session expired
|
||||
# if @variables.session_expired == True:
|
||||
# transition to @topic.session_expired
|
||||
# transition to @subagent.session_expired
|
||||
|
||||
# Refresh context before every turn
|
||||
run @actions.refresh_context
|
||||
@ -105,7 +105,7 @@ topic conversation:
|
||||
|
|
||||
| Respond helpfully using the refreshed context above.
|
||||
actions:
|
||||
end_conversation: @utils.transition to @topic.farewell
|
||||
end_conversation: @utils.transition to @subagent.farewell
|
||||
|
||||
# ★ after_reasoning: Runs AFTER each reasoning step
|
||||
after_reasoning:
|
||||
|
||||
@ -27,7 +27,7 @@ variables:
|
||||
action_taken: mutable string
|
||||
description: "Last action taken by agent"
|
||||
|
||||
topic order_assistance:
|
||||
subagent order_assistance:
|
||||
label: "Order Assistance"
|
||||
description: "Helps customers with order-related questions"
|
||||
|
||||
@ -123,8 +123,8 @@ topic order_assistance:
|
||||
available when @variables.order_status != "shipped"
|
||||
|
||||
# Topic transitions
|
||||
go_help: @utils.transition to @topic.general_help
|
||||
go_escalation: @utils.transition to @topic.escalation
|
||||
go_help: @utils.transition to @subagent.general_help
|
||||
go_escalation: @utils.transition to @subagent.escalation
|
||||
available when @variables.needs_human == True
|
||||
|
||||
# ★ Insight: When to Use Each Method
|
||||
@ -150,7 +150,7 @@ topic order_assistance:
|
||||
# ★ Example: Action Callback Pattern (Deterministic Chaining)
|
||||
# Use "run" for guaranteed follow-up actions after a primary action
|
||||
|
||||
topic checkout:
|
||||
subagent checkout:
|
||||
label: "Checkout"
|
||||
description: "Handles order checkout"
|
||||
|
||||
|
||||
@ -50,11 +50,11 @@ start_agent topic_selector:
|
||||
before_reasoning:
|
||||
# ★ GATE CHECK: If a topic holds focus, bypass LLM entirely
|
||||
if @variables.open_gate == "protected_workflow":
|
||||
transition to @topic.protected_workflow
|
||||
transition to @subagent.protected_workflow
|
||||
if @variables.open_gate == "account_management":
|
||||
transition to @topic.account_management
|
||||
transition to @subagent.account_management
|
||||
if @variables.open_gate == "authentication_gate":
|
||||
transition to @topic.authentication_gate
|
||||
transition to @subagent.authentication_gate
|
||||
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -64,15 +64,15 @@ start_agent topic_selector:
|
||||
| - Account settings or profile changes → account management
|
||||
| - General questions → general inquiry
|
||||
actions:
|
||||
go_protected: @utils.transition to @topic.protected_workflow
|
||||
go_account: @utils.transition to @topic.account_management
|
||||
go_general: @utils.transition to @topic.general_inquiry
|
||||
go_protected: @utils.transition to @subagent.protected_workflow
|
||||
go_account: @utils.transition to @subagent.account_management
|
||||
go_general: @utils.transition to @subagent.general_inquiry
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
# PROTECTED WORKFLOW (Requires Authentication)
|
||||
# Checks auth state, redirects to auth gate if needed, locks focus if authed
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
topic protected_workflow:
|
||||
subagent protected_workflow:
|
||||
description: "Handles order status, returns, and shipping (requires authentication)"
|
||||
|
||||
before_reasoning:
|
||||
@ -80,7 +80,7 @@ topic protected_workflow:
|
||||
if @variables.authenticated == False:
|
||||
set @variables.next_topic = "protected_workflow"
|
||||
set @variables.open_gate = "authentication_gate"
|
||||
transition to @topic.authentication_gate
|
||||
transition to @subagent.authentication_gate
|
||||
|
||||
# ★ FOCUS LOCK: Keep gate open so topic selector bypasses LLM
|
||||
set @variables.open_gate = "protected_workflow"
|
||||
@ -98,7 +98,7 @@ topic protected_workflow:
|
||||
set @variables.order_result = @outputs.status
|
||||
|
||||
# ★ EXIT_PROTOCOL: User changed intent — release gate
|
||||
exit_to_menu: @utils.transition to @topic.exit_protocol
|
||||
exit_to_menu: @utils.transition to @subagent.exit_protocol
|
||||
|
||||
after_reasoning:
|
||||
# Logging or cleanup after each turn (optional)
|
||||
@ -108,7 +108,7 @@ topic protected_workflow:
|
||||
# ACCOUNT MANAGEMENT (Second Protected Topic)
|
||||
# Demonstrates the pattern scales to N protected topics
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
topic account_management:
|
||||
subagent account_management:
|
||||
description: "Handles account settings and profile changes (requires authentication)"
|
||||
|
||||
before_reasoning:
|
||||
@ -116,7 +116,7 @@ topic account_management:
|
||||
if @variables.authenticated == False:
|
||||
set @variables.next_topic = "account_management"
|
||||
set @variables.open_gate = "authentication_gate"
|
||||
transition to @topic.authentication_gate
|
||||
transition to @subagent.authentication_gate
|
||||
|
||||
# ★ FOCUS LOCK
|
||||
set @variables.open_gate = "account_management"
|
||||
@ -135,13 +135,13 @@ topic account_management:
|
||||
set @variables.update_result = @outputs.success
|
||||
|
||||
# ★ EXIT_PROTOCOL: User changed intent — release gate
|
||||
exit_to_menu: @utils.transition to @topic.exit_protocol
|
||||
exit_to_menu: @utils.transition to @subagent.exit_protocol
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
# AUTHENTICATION GATE
|
||||
# Handles auth flow, then routes back via next_topic
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
topic authentication_gate:
|
||||
subagent authentication_gate:
|
||||
description: "Verifies customer identity before allowing access to protected topics"
|
||||
|
||||
before_reasoning:
|
||||
@ -167,23 +167,23 @@ topic authentication_gate:
|
||||
if @variables.authenticated == True:
|
||||
if @variables.next_topic == "protected_workflow":
|
||||
set @variables.open_gate = "protected_workflow"
|
||||
transition to @topic.protected_workflow
|
||||
transition to @subagent.protected_workflow
|
||||
if @variables.next_topic == "account_management":
|
||||
set @variables.open_gate = "account_management"
|
||||
transition to @topic.account_management
|
||||
transition to @subagent.account_management
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
# EXIT PROTOCOL (Resets Gate State)
|
||||
# Clears open_gate so LLM topic selector regains control
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
topic exit_protocol:
|
||||
subagent exit_protocol:
|
||||
description: "Resets gate state and returns to topic selector"
|
||||
|
||||
before_reasoning:
|
||||
# ★ RELEASE GATE: Clear all gate state
|
||||
set @variables.open_gate = "null"
|
||||
set @variables.next_topic = ""
|
||||
transition to @topic.topic_selector
|
||||
transition to @subagent.topic_selector
|
||||
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -193,7 +193,7 @@ topic exit_protocol:
|
||||
# GENERAL INQUIRY (Unprotected Topic)
|
||||
# Demonstrates that not every topic needs gating
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
topic general_inquiry:
|
||||
subagent general_inquiry:
|
||||
description: "Handles general questions that do not require authentication"
|
||||
|
||||
reasoning:
|
||||
@ -204,8 +204,8 @@ topic general_inquiry:
|
||||
| If the customer needs help with orders or account settings,
|
||||
| let them know they will need to verify their identity first.
|
||||
actions:
|
||||
go_protected: @utils.transition to @topic.protected_workflow
|
||||
go_account: @utils.transition to @topic.account_management
|
||||
go_protected: @utils.transition to @subagent.protected_workflow
|
||||
go_account: @utils.transition to @subagent.account_management
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════
|
||||
# ARCHITECTURE DIAGRAM
|
||||
|
||||
@ -147,11 +147,11 @@ start_agent topic_selector:
|
||||
| - Account questions
|
||||
|
||||
actions:
|
||||
go_orders: @utils.transition to @topic.order_status
|
||||
go_cases: @utils.transition to @topic.support_cases
|
||||
go_account: @utils.transition to @topic.account_help
|
||||
go_orders: @utils.transition to @subagent.order_status
|
||||
go_cases: @utils.transition to @subagent.support_cases
|
||||
go_account: @utils.transition to @subagent.account_help
|
||||
|
||||
topic order_status:
|
||||
subagent order_status:
|
||||
label: "Order Status"
|
||||
description: "Check order status with lazy loading"
|
||||
|
||||
@ -194,9 +194,9 @@ topic order_status:
|
||||
actions:
|
||||
get_details: @actions.get_tracking_details
|
||||
with order_id=@variables.recent_order_id
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic support_cases:
|
||||
subagent support_cases:
|
||||
label: "Support Cases"
|
||||
description: "Review support cases with lazy loading"
|
||||
|
||||
@ -225,11 +225,11 @@ topic support_cases:
|
||||
| - Return to the main menu
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
escalate: @utils.escalate
|
||||
description: "Transfer to support specialist"
|
||||
|
||||
topic account_help:
|
||||
subagent account_help:
|
||||
label: "Account Help"
|
||||
description: "Account questions - customer data already loaded"
|
||||
|
||||
@ -245,7 +245,7 @@ topic account_help:
|
||||
| What would you like to know about your account?
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# ★ Insight: Procedural vs Declarative Actions
|
||||
#
|
||||
|
||||
@ -72,10 +72,10 @@ start_agent topic_selector:
|
||||
|
|
||||
| Route to the appropriate topic.
|
||||
actions:
|
||||
go_schedule: @utils.transition to @topic.schedule_generation
|
||||
go_email: @utils.transition to @topic.email_generation
|
||||
go_schedule: @utils.transition to @subagent.schedule_generation
|
||||
go_email: @utils.transition to @subagent.email_generation
|
||||
|
||||
topic schedule_generation:
|
||||
subagent schedule_generation:
|
||||
label: "Schedule Generation"
|
||||
description: "Generate personalized daily schedules"
|
||||
|
||||
@ -123,9 +123,9 @@ topic schedule_generation:
|
||||
with "Input:timezone"=@variables.user_timezone
|
||||
set @variables.generated_schedule = @outputs.promptResponse
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic email_generation:
|
||||
subagent email_generation:
|
||||
label: "Email Generation"
|
||||
description: "Generate professional emails"
|
||||
|
||||
@ -168,7 +168,7 @@ topic email_generation:
|
||||
with "Input:tone"=...
|
||||
set @variables.generated_email = @outputs.promptResponse
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# ★ Insight: Prompt Template Integration Checklist
|
||||
#
|
||||
|
||||
@ -111,9 +111,9 @@ start_agent topic_selector:
|
||||
| Route the customer to the appropriate topic.
|
||||
|
||||
actions:
|
||||
go_orders: @utils.transition to @topic.orders
|
||||
go_billing: @utils.transition to @topic.billing
|
||||
go_support: @utils.transition to @topic.support
|
||||
go_orders: @utils.transition to @subagent.orders
|
||||
go_billing: @utils.transition to @subagent.billing
|
||||
go_support: @utils.transition to @subagent.support
|
||||
available when @variables.business_hours == True
|
||||
|
||||
actions:
|
||||
@ -134,7 +134,7 @@ start_agent topic_selector:
|
||||
description: "True if in business hours"
|
||||
target: "flow://Check_Business_Hours"
|
||||
|
||||
topic orders:
|
||||
subagent orders:
|
||||
label: "Order Management"
|
||||
description: "Handle order inquiries with tier-appropriate service"
|
||||
|
||||
@ -149,9 +149,9 @@ topic orders:
|
||||
| Look up order status, process changes, or handle returns.
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic billing:
|
||||
subagent billing:
|
||||
label: "Billing Support"
|
||||
description: "Handle billing with appropriate authority levels"
|
||||
|
||||
@ -171,12 +171,12 @@ topic billing:
|
||||
| Help the customer understand their bill and resolve issues.
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
escalate: @utils.escalate
|
||||
description: "Transfer to billing specialist"
|
||||
available when @variables.customer_tier == "standard"
|
||||
|
||||
topic support:
|
||||
subagent support:
|
||||
label: "Technical Support"
|
||||
description: "Technical support with business hours awareness"
|
||||
|
||||
@ -192,7 +192,7 @@ topic support:
|
||||
| Help resolve the customer's technical issue.
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# ★ TOPIC-LEVEL SYSTEM OVERRIDES (NEW PATTERN)
|
||||
@ -200,7 +200,7 @@ topic support:
|
||||
# system: blocks that OVERRIDE the global system instructions.
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
topic formal_mode:
|
||||
subagent formal_mode:
|
||||
label: "Formal Communication"
|
||||
description: "Professional business communication mode"
|
||||
|
||||
@ -217,9 +217,9 @@ topic formal_mode:
|
||||
| I am prepared to address your inquiry with the utmost professionalism.
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic creative_mode:
|
||||
subagent creative_mode:
|
||||
label: "Creative Assistant"
|
||||
description: "Creative and imaginative communication mode"
|
||||
|
||||
@ -238,9 +238,9 @@ topic creative_mode:
|
||||
| What shall we dream up today?
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
topic technical_expert:
|
||||
subagent technical_expert:
|
||||
label: "Technical Expert"
|
||||
description: "Deep technical expertise mode"
|
||||
|
||||
@ -259,7 +259,7 @@ topic technical_expert:
|
||||
| What technical challenge are we solving?
|
||||
|
||||
actions:
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
|
||||
# ★ Insight: Three Levels of Instruction Control
|
||||
#
|
||||
|
||||
@ -43,14 +43,14 @@ start_agent entry:
|
||||
instructions: |
|
||||
Welcome the user and offer to help with questions.
|
||||
actions:
|
||||
go_search: @utils.transition to @topic.knowledge_search
|
||||
go_search: @utils.transition to @subagent.knowledge_search
|
||||
description: "Start knowledge search"
|
||||
|
||||
# ============================================================
|
||||
# KNOWLEDGE SEARCH TOPIC (RAG Pattern)
|
||||
# ============================================================
|
||||
|
||||
topic knowledge_search:
|
||||
subagent knowledge_search:
|
||||
description: "Search knowledge base and generate grounded responses"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -113,7 +113,7 @@ topic knowledge_search:
|
||||
# FOLLOW-UP QUESTIONS TOPIC
|
||||
# ============================================================
|
||||
|
||||
topic follow_up:
|
||||
subagent follow_up:
|
||||
description: "Handle follow-up questions using cached context"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -124,8 +124,8 @@ topic follow_up:
|
||||
with query = ... # Follow-up question extracted by LLM
|
||||
with context = @variables.search_results # Reuse cached results!
|
||||
else:
|
||||
transition to @topic.knowledge_search
|
||||
transition to @subagent.knowledge_search
|
||||
|
||||
actions:
|
||||
back_to_search: @utils.transition to @topic.knowledge_search
|
||||
back_to_search: @utils.transition to @subagent.knowledge_search
|
||||
description: "Start a new search"
|
||||
|
||||
@ -31,13 +31,13 @@ start_agent topic_selector:
|
||||
description: "Welcome the user and determine the appropriate topic based on user input"
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_topic_a: @utils.transition to @topic.topic_a
|
||||
go_to_topic_b: @utils.transition to @topic.topic_b
|
||||
go_to_topic_c: @utils.transition to @topic.topic_c
|
||||
go_to_escalation: @utils.transition to @topic.escalation
|
||||
go_to_off_topic: @utils.transition to @topic.off_topic
|
||||
go_to_topic_a: @utils.transition to @subagent.topic_a
|
||||
go_to_topic_b: @utils.transition to @subagent.topic_b
|
||||
go_to_topic_c: @utils.transition to @subagent.topic_c
|
||||
go_to_escalation: @utils.transition to @subagent.escalation
|
||||
go_to_off_topic: @utils.transition to @subagent.off_topic
|
||||
|
||||
topic topic_a:
|
||||
subagent topic_a:
|
||||
label: "Topic A"
|
||||
description: "Describe what this topic handles"
|
||||
|
||||
@ -66,7 +66,7 @@ topic topic_a:
|
||||
is_displayable: True
|
||||
filter_from_agent: False
|
||||
|
||||
topic topic_b:
|
||||
subagent topic_b:
|
||||
label: "Topic B"
|
||||
description: "Describe what this topic handles"
|
||||
|
||||
@ -102,7 +102,7 @@ topic topic_b:
|
||||
label: "Result"
|
||||
is_displayable: False
|
||||
|
||||
topic topic_c:
|
||||
subagent topic_c:
|
||||
label: "Topic C"
|
||||
description: "Describe what this topic handles"
|
||||
|
||||
@ -139,7 +139,7 @@ topic topic_c:
|
||||
is_displayable: True
|
||||
filter_from_agent: False
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Handles requests from users who want to transfer or escalate their conversation to a live human agent."
|
||||
|
||||
@ -150,7 +150,7 @@ topic escalation:
|
||||
escalate_to_human: @utils.escalate
|
||||
description: "Escalate to a human agent."
|
||||
|
||||
topic off_topic:
|
||||
subagent off_topic:
|
||||
label: "Off Topic"
|
||||
description: "Redirect conversation to relevant topics when user request goes off-topic"
|
||||
|
||||
|
||||
@ -26,11 +26,11 @@ start_agent topic_selector:
|
||||
description: "Welcome the user and determine the appropriate topic based on user input"
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_main: @utils.transition to @topic.main
|
||||
go_to_escalation: @utils.transition to @topic.escalation
|
||||
go_to_off_topic: @utils.transition to @topic.off_topic
|
||||
go_to_main: @utils.transition to @subagent.main
|
||||
go_to_escalation: @utils.transition to @subagent.escalation
|
||||
go_to_off_topic: @utils.transition to @subagent.off_topic
|
||||
|
||||
topic main:
|
||||
subagent main:
|
||||
label: "Main Topic"
|
||||
description: "Describe what this topic handles. The Atlas Reasoning Engine matches user utterances against this description."
|
||||
|
||||
@ -60,7 +60,7 @@ topic main:
|
||||
is_displayable: True
|
||||
filter_from_agent: False
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
label: "Escalation"
|
||||
description: "Handles requests from users who want to transfer or escalate their conversation to a live human agent."
|
||||
|
||||
@ -71,7 +71,7 @@ topic escalation:
|
||||
escalate_to_human: @utils.escalate
|
||||
description: "Escalate to a human agent."
|
||||
|
||||
topic off_topic:
|
||||
subagent off_topic:
|
||||
label: "Off Topic"
|
||||
description: "Redirect conversation to relevant topics when user request goes off-topic"
|
||||
|
||||
|
||||
@ -56,21 +56,21 @@ start_agent entry:
|
||||
instructions: |
|
||||
Welcome the customer and route to identity verification.
|
||||
actions:
|
||||
start_verification: @utils.transition to @topic.identity_verification
|
||||
start_verification: @utils.transition to @subagent.identity_verification
|
||||
description: "Begin identity verification process"
|
||||
|
||||
# ============================================================
|
||||
# VERIFICATION GATE (Security Check)
|
||||
# ============================================================
|
||||
|
||||
topic identity_verification:
|
||||
subagent identity_verification:
|
||||
description: "Verify customer identity before proceeding"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
# SECURITY: Check for lockout FIRST (deterministic)
|
||||
if @variables.failed_attempts >= 3:
|
||||
| Too many failed attempts. Transferring to a human agent.
|
||||
transition to @topic.escalation
|
||||
transition to @subagent.escalation
|
||||
|
||||
# Already verified? Proceed to protected topics
|
||||
if @variables.customer_verified == True:
|
||||
@ -88,11 +88,11 @@ topic identity_verification:
|
||||
set @variables.customer_verified = @outputs.verified
|
||||
|
||||
# GUARDED: Only visible when verified
|
||||
go_to_account: @utils.transition to @topic.account_management
|
||||
go_to_account: @utils.transition to @subagent.account_management
|
||||
description: "Access account settings"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
go_to_refund: @utils.transition to @topic.refund_processor
|
||||
go_to_refund: @utils.transition to @subagent.refund_processor
|
||||
description: "Process a refund request"
|
||||
available when @variables.customer_verified == True
|
||||
|
||||
@ -104,13 +104,13 @@ topic identity_verification:
|
||||
# PROTECTED: Account Management
|
||||
# ============================================================
|
||||
|
||||
topic account_management:
|
||||
subagent account_management:
|
||||
description: "Manage customer account (requires verification)"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
# SECURITY GATE: Re-check verification
|
||||
if @variables.customer_verified == False:
|
||||
transition to @topic.identity_verification
|
||||
transition to @subagent.identity_verification
|
||||
|
||||
| Welcome to account management.
|
||||
| What would you like to do with your account?
|
||||
@ -122,20 +122,20 @@ topic account_management:
|
||||
update_preferences: @actions.update_preferences
|
||||
description: "Update communication preferences"
|
||||
available when @variables.customer_verified == True
|
||||
back: @utils.transition to @topic.identity_verification
|
||||
back: @utils.transition to @subagent.identity_verification
|
||||
description: "Return to main menu"
|
||||
|
||||
# ============================================================
|
||||
# PROTECTED: Refund Processor (with Post-Action Pattern)
|
||||
# ============================================================
|
||||
|
||||
topic refund_processor:
|
||||
subagent refund_processor:
|
||||
description: "Process refund requests (requires verification)"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
# SECURITY GATE: Re-check verification
|
||||
if @variables.customer_verified == False:
|
||||
transition to @topic.identity_verification
|
||||
transition to @subagent.identity_verification
|
||||
|
||||
# ====================================================
|
||||
# POST-ACTION CHECK (at TOP - triggers on loop)
|
||||
@ -145,7 +145,7 @@ topic refund_processor:
|
||||
run @actions.create_crm_case
|
||||
with customer_id = @variables.customer_id
|
||||
with refund_amount = @variables.refund_amount
|
||||
transition to @topic.success_confirmation
|
||||
transition to @subagent.success_confirmation
|
||||
|
||||
# ====================================================
|
||||
# PRE-LLM: Load churn risk data
|
||||
@ -181,14 +181,14 @@ topic refund_processor:
|
||||
# SUCCESS CONFIRMATION
|
||||
# ============================================================
|
||||
|
||||
topic success_confirmation:
|
||||
subagent success_confirmation:
|
||||
description: "Confirm successful operation"
|
||||
reasoning:
|
||||
instructions: |
|
||||
Great news! Your request has been processed successfully.
|
||||
Is there anything else I can help you with?
|
||||
actions:
|
||||
new_request: @utils.transition to @topic.identity_verification
|
||||
new_request: @utils.transition to @subagent.identity_verification
|
||||
description: "Start a new request"
|
||||
end_conversation: @actions.end_session
|
||||
description: "End the conversation"
|
||||
@ -197,7 +197,7 @@ topic success_confirmation:
|
||||
# ESCALATION (Handoff to Human)
|
||||
# ============================================================
|
||||
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
description: "Escalate to human agent"
|
||||
reasoning:
|
||||
instructions: |
|
||||
|
||||
@ -50,7 +50,7 @@ actions:
|
||||
Reference the action definition in your `.agent` file:
|
||||
|
||||
```agentscript
|
||||
topic schedule_generation:
|
||||
subagent schedule_generation:
|
||||
reasoning:
|
||||
actions:
|
||||
generate_schedule: @actions.Generate_Personalized_Schedule
|
||||
|
||||
@ -146,7 +146,7 @@ Agent Script provides two ways to invoke actions:
|
||||
The LLM automatically selects appropriate actions from those defined in the `reasoning.actions` block:
|
||||
|
||||
```agentscript
|
||||
topic order_management:
|
||||
subagent order_management:
|
||||
description: "Handles order inquiries"
|
||||
|
||||
reasoning:
|
||||
@ -355,7 +355,7 @@ public with sharing class CalculateDiscountAction {
|
||||
#### Step 2: Reference DIRECTLY in Agent Script via `apex://`
|
||||
|
||||
```yaml
|
||||
topic discount_calculator:
|
||||
subagent discount_calculator:
|
||||
description: "Calculates discount for customer order"
|
||||
|
||||
# Level 1: Action DEFINITION with target
|
||||
|
||||
@ -157,7 +157,7 @@ Every topic in an agent serves one of three roles: domain, guardrail, or escalat
|
||||
**Guardrail Topics.** Specialized topics that enforce agent boundaries. The standard Agentforce template includes two guardrail topics by default: `off_topic` (redirects users back to the agent's scope) and `ambiguous_question` (asks for clarification instead of guessing). Preserve these when modifying existing agents.
|
||||
|
||||
```agentscript
|
||||
topic off_topic:
|
||||
subagent off_topic:
|
||||
description: "Handle off-topic requests"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -165,7 +165,7 @@ topic off_topic:
|
||||
I can only help with [list your capabilities].
|
||||
What can I help you with today?
|
||||
|
||||
topic ambiguous_question:
|
||||
subagent ambiguous_question:
|
||||
description: "Ask for clarification"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -176,7 +176,7 @@ topic ambiguous_question:
|
||||
**Escalation Topics.** Hand off to a human via `@utils.escalate`. This is a permanent exit — the user leaves the agent for a support channel (phone, email, chat with a human). Once triggered, the agent session ends. The escalation action does NOT return.
|
||||
|
||||
```agentscript
|
||||
topic escalation:
|
||||
subagent escalation:
|
||||
reasoning:
|
||||
actions:
|
||||
escalate: @utils.escalate
|
||||
@ -208,18 +208,18 @@ Example: The Local Info Agent. The `topic_selector` topic (hub) routes to domain
|
||||
start_agent topic_selector:
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_weather: @utils.transition to @topic.local_weather
|
||||
go_to_events: @utils.transition to @topic.local_events
|
||||
go_to_hours: @utils.transition to @topic.resort_hours
|
||||
go_to_off_topic: @utils.transition to @topic.off_topic
|
||||
go_to_ambiguous_question: @utils.transition to @topic.ambiguous_question
|
||||
go_to_weather: @utils.transition to @subagent.local_weather
|
||||
go_to_events: @utils.transition to @subagent.local_events
|
||||
go_to_hours: @utils.transition to @subagent.resort_hours
|
||||
go_to_off_topic: @utils.transition to @subagent.off_topic
|
||||
go_to_ambiguous_question: @utils.transition to @subagent.ambiguous_question
|
||||
|
||||
# Domain topics — each has its own instructions and actions
|
||||
topic local_weather:
|
||||
subagent local_weather:
|
||||
reasoning:
|
||||
instructions: | Handle weather questions.
|
||||
|
||||
topic local_events:
|
||||
subagent local_events:
|
||||
reasoning:
|
||||
instructions: | Handle event questions.
|
||||
|
||||
@ -232,30 +232,30 @@ topic local_events:
|
||||
start_agent intake:
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.verification
|
||||
go_next: @utils.transition to @subagent.verification
|
||||
|
||||
topic verification:
|
||||
subagent verification:
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.details_gathering
|
||||
go_next: @utils.transition to @subagent.details_gathering
|
||||
|
||||
topic details_gathering:
|
||||
subagent details_gathering:
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.confirmation
|
||||
go_next: @utils.transition to @subagent.confirmation
|
||||
```
|
||||
|
||||
**Escalation Chain.** Tiered support where each level has increasing capabilities. First-level resolves common issues with basic actions; second-level has access to more powerful actions or broader authority; final level escalates to a human. Use when support difficulty varies and you want to resolve simple issues quickly without involving higher tiers.
|
||||
|
||||
```agentscript
|
||||
topic level_1_support:
|
||||
subagent level_1_support:
|
||||
reasoning:
|
||||
instructions: | Try to resolve the issue using the FAQ and basic troubleshooting.
|
||||
actions:
|
||||
check_faq: @actions.search_faq
|
||||
escalate: @utils.transition to @topic.level_2_support
|
||||
escalate: @utils.transition to @subagent.level_2_support
|
||||
|
||||
topic level_2_support:
|
||||
subagent level_2_support:
|
||||
reasoning:
|
||||
instructions: | You have access to account tools. Try to resolve before escalating.
|
||||
actions:
|
||||
@ -270,12 +270,12 @@ topic level_2_support:
|
||||
start_agent security_gate:
|
||||
reasoning:
|
||||
actions:
|
||||
go_admin: @utils.transition to @topic.admin_panel
|
||||
go_admin: @utils.transition to @subagent.admin_panel
|
||||
available when @variables.user_role == "admin"
|
||||
go_denied: @utils.transition to @topic.access_denied
|
||||
go_denied: @utils.transition to @subagent.access_denied
|
||||
available when @variables.user_role != "admin"
|
||||
|
||||
topic access_denied:
|
||||
subagent access_denied:
|
||||
reasoning:
|
||||
instructions: | You don't have permission to access this.
|
||||
```
|
||||
@ -415,7 +415,7 @@ Each `@InvocableVariable` on the request class becomes an action input; each on
|
||||
|
||||
```agentscript
|
||||
# WRONG — snake_case doesn't match the Apex field names
|
||||
topic orders:
|
||||
subagent orders:
|
||||
actions:
|
||||
check_order: @actions.check_order
|
||||
target: "apex://OrderLookup"
|
||||
@ -425,7 +425,7 @@ topic orders:
|
||||
order_date: date # Apex field is orderDate, NOT order_date
|
||||
|
||||
# RIGHT — names match Apex @InvocableVariable field names exactly
|
||||
topic orders:
|
||||
subagent orders:
|
||||
actions:
|
||||
check_order: @actions.check_order
|
||||
target: "apex://OrderLookup"
|
||||
@ -638,16 +638,16 @@ Use handoff when:
|
||||
- One-way workflows (checkout → order_confirmation → end)
|
||||
|
||||
```agentscript
|
||||
topic topic_selector:
|
||||
subagent topic_selector:
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_checkout: @utils.transition to @topic.checkout
|
||||
go_to_checkout: @utils.transition to @subagent.checkout
|
||||
description: "Start checkout"
|
||||
|
||||
topic checkout:
|
||||
subagent checkout:
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_confirm: @utils.transition to @topic.order_confirmation
|
||||
go_to_confirm: @utils.transition to @subagent.order_confirmation
|
||||
description: "Proceed to confirmation"
|
||||
```
|
||||
|
||||
@ -655,21 +655,21 @@ After `go_to_confirm` executes, the user is in `order_confirmation`. If they lat
|
||||
|
||||
### Delegation: Handoff with Explicit Return
|
||||
|
||||
Delegation hands control to another topic using `@topic.X` in `reasoning.actions`. It signals *intent* to return, but the return does not happen automatically — the delegated topic must explicitly transition back to the caller.
|
||||
Delegation hands control to another topic using `@subagent.X` in `reasoning.actions`. It signals *intent* to return, but the return does not happen automatically — the delegated topic must explicitly transition back to the caller.
|
||||
|
||||
Use delegation when:
|
||||
- One topic needs advice from a specialist and should continue after
|
||||
- Reusable sub-workflows (e.g., identity verification called from multiple topics)
|
||||
- A topic needs to temporarily visit another topic, then resume
|
||||
|
||||
**Critical Rule:** `@topic.X` delegates control. It does NOT implement call-return semantics. If you want the user to return to the calling topic, code an explicit `transition to @topic.<caller>` in the delegated topic. Without it, the next user utterance falls through to `topic_selector`.
|
||||
**Critical Rule:** `@subagent.X` delegates control. It does NOT implement call-return semantics. If you want the user to return to the calling topic, code an explicit `transition to @subagent.<caller>` in the delegated topic. Without it, the next user utterance falls through to `topic_selector`.
|
||||
|
||||
WRONG: Assuming `@topic.specialist` returns automatically
|
||||
WRONG: Assuming `@subagent.specialist` returns automatically
|
||||
```agentscript
|
||||
topic main:
|
||||
subagent main:
|
||||
reasoning:
|
||||
actions:
|
||||
consult_specialist: @topic.specialist # WRONG — assumes return
|
||||
consult_specialist: @subagent.specialist # WRONG — assumes return
|
||||
|
||||
# After specialist runs, control does NOT return to main.
|
||||
# The next user utterance routes through topic_selector.
|
||||
@ -677,16 +677,16 @@ topic main:
|
||||
|
||||
RIGHT: Delegated topic defines explicit return transition
|
||||
```agentscript
|
||||
topic main:
|
||||
subagent main:
|
||||
reasoning:
|
||||
actions:
|
||||
consult_specialist: @topic.specialist
|
||||
consult_specialist: @subagent.specialist
|
||||
description: "Consult specialist"
|
||||
|
||||
topic specialist:
|
||||
subagent specialist:
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_main: @utils.transition to @topic.main
|
||||
go_to_main: @utils.transition to @subagent.main
|
||||
description: "Return to main"
|
||||
```
|
||||
|
||||
@ -713,7 +713,7 @@ Instructions are suggestions the LLM *may* follow. Gates and guards are enforced
|
||||
|
||||
WRONG: Security rule as an instruction (LLM can ignore it)
|
||||
```agentscript
|
||||
topic admin_panel:
|
||||
subagent admin_panel:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Only respond if the user is an admin.
|
||||
@ -730,7 +730,7 @@ Two factors govern subjective control effectiveness: instruction ordering and gr
|
||||
|
||||
RIGHT: Post-action check at the top (LLM sees it first)
|
||||
```agentscript
|
||||
topic checkout:
|
||||
subagent checkout:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
# Post-action check — LLM sees this first
|
||||
@ -752,7 +752,7 @@ topic checkout:
|
||||
|
||||
WRONG: Post-action check at the bottom (LLM may respond before seeing it)
|
||||
```agentscript
|
||||
topic checkout:
|
||||
subagent checkout:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Your current cart total is {!@variables.cart_total}.
|
||||
@ -787,7 +787,7 @@ An action marked `available when <condition>` is hidden from the LLM when the co
|
||||
|
||||
**WRONG: Relying on instructions to prevent action calls**
|
||||
```agentscript
|
||||
topic booking:
|
||||
subagent booking:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| if @variables.booking_pending:
|
||||
@ -801,7 +801,7 @@ The action is visible; instructions tell the LLM not to call it. The LLM may ign
|
||||
|
||||
**RIGHT: Using `available when` to hide the action**
|
||||
```agentscript
|
||||
topic booking:
|
||||
subagent booking:
|
||||
reasoning:
|
||||
actions:
|
||||
confirm: @actions.confirm_booking
|
||||
@ -815,7 +815,7 @@ If `booking_pending` is False, the LLM sees no `confirm` action.
|
||||
Use `if/else` in instructions to show/hide text based on state. This doesn't hide actions; it changes what the LLM is told to do.
|
||||
|
||||
```agentscript
|
||||
topic support:
|
||||
subagent support:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| You're helping a customer with their order.
|
||||
@ -836,10 +836,10 @@ Use conditional instructions when you want to steer the LLM's reasoning without
|
||||
The `before_reasoning` block runs before the LLM is invoked. Code here executes every time the topic is entered. The LLM never sees it, cannot override it, and cannot skip it.
|
||||
|
||||
```agentscript
|
||||
topic admin_panel:
|
||||
subagent admin_panel:
|
||||
before_reasoning:
|
||||
if @variables.user_role != "admin":
|
||||
transition to @topic.access_denied
|
||||
transition to @subagent.access_denied
|
||||
|
||||
reasoning:
|
||||
instructions: | You are in the admin panel.
|
||||
@ -854,10 +854,10 @@ Combine `available when`, conditional instructions, and guards to enforce comple
|
||||
Example: "Show the payment action only if the user is authenticated AND the cart is not empty AND we're not in a preview/demo mode"
|
||||
|
||||
```agentscript
|
||||
topic checkout:
|
||||
subagent checkout:
|
||||
before_reasoning:
|
||||
if @variables.is_demo_mode:
|
||||
transition to @topic.demo_complete
|
||||
transition to @subagent.demo_complete
|
||||
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -882,7 +882,7 @@ variables:
|
||||
step2_verified: mutable boolean = False
|
||||
step3_verified: mutable boolean = False
|
||||
|
||||
topic verification:
|
||||
subagent verification:
|
||||
reasoning:
|
||||
actions:
|
||||
verify_step1: @actions.run_check_1
|
||||
@ -890,7 +890,7 @@ topic verification:
|
||||
available when @variables.step1_verified == True
|
||||
verify_step3: @actions.run_check_3
|
||||
available when @variables.step2_verified == True
|
||||
proceed: @utils.transition to @topic.confirmed
|
||||
proceed: @utils.transition to @subagent.confirmed
|
||||
available when @variables.step3_verified == True
|
||||
```
|
||||
|
||||
@ -916,7 +916,7 @@ An action loop occurs when the LLM calls the same action repeatedly without new
|
||||
|
||||
**WRONG: All three loop conditions present**
|
||||
```agentscript
|
||||
topic events:
|
||||
subagent events:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Use the {!@actions.check_events} action to find events.
|
||||
@ -935,7 +935,7 @@ No gate, variable-bound input, no post-action guidance. The LLM can call `check_
|
||||
Tell the LLM to stop calling the action after receiving results. Name the specific output fields the LLM should include in its text response — vague instructions like "present the results" let platform tools hijack the response (see Section 7, Grounding).
|
||||
|
||||
```agentscript
|
||||
topic events:
|
||||
subagent events:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Use {!@actions.check_events} to find events matching the guest's interest.
|
||||
@ -955,7 +955,7 @@ topic events:
|
||||
Move the agent out of the topic after the action completes, breaking the cycle.
|
||||
|
||||
```agentscript
|
||||
topic events:
|
||||
subagent events:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Use {!@actions.check_events} to find events.
|
||||
@ -966,7 +966,7 @@ topic events:
|
||||
|
||||
after_reasoning:
|
||||
if @outputs.events_found:
|
||||
transition to @topic.results_displayed
|
||||
transition to @subagent.results_displayed
|
||||
```
|
||||
|
||||
After `check_events` runs, the `after_reasoning` block transitions to a new topic. The agent never cycles back to `events`, so the action can't be called again.
|
||||
@ -976,7 +976,7 @@ After `check_events` runs, the `after_reasoning` block transitions to a new topi
|
||||
Use `...` (LLM slot-fill) instead of variable binding. This forces the LLM to extract values from the conversation each cycle, adding natural decision friction.
|
||||
|
||||
```agentscript
|
||||
topic search:
|
||||
subagent search:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Help the user search for products.
|
||||
@ -992,7 +992,7 @@ With `...`, the LLM must actively decide "do I have a new search query?" on ever
|
||||
**Combine mitigations for reinforcement:**
|
||||
|
||||
```agentscript
|
||||
topic lookup:
|
||||
subagent lookup:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Once you have the result, present it. Do NOT call the action again.
|
||||
@ -1003,7 +1003,7 @@ topic lookup:
|
||||
|
||||
after_reasoning:
|
||||
if @outputs.data_found:
|
||||
transition to @topic.done # Exit the topic
|
||||
transition to @subagent.done # Exit the topic
|
||||
```
|
||||
|
||||
Combine mitigations for reinforcement.
|
||||
|
||||
@ -28,7 +28,7 @@ Agent Script operates in two phases: deterministic resolution, then LLM reasonin
|
||||
**Worked Example.** Consider this topic:
|
||||
|
||||
```agentscript
|
||||
topic check_order:
|
||||
subagent check_order:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
if @variables.order_id != "":
|
||||
@ -83,15 +83,15 @@ language:
|
||||
start_agent topic_selector:
|
||||
...
|
||||
|
||||
topic my_topic:
|
||||
subagent my_topic:
|
||||
...
|
||||
```
|
||||
|
||||
**Required blocks:** `system`, `config`, `start_agent`, and at least one `topic`.
|
||||
**Required blocks:** `system`, `config`, `start_agent`, and at least one `subagent`.
|
||||
|
||||
**Optional blocks:** `variables`, `connections`, `knowledge`, `language`. Omit them if not needed.
|
||||
|
||||
**Within `start_agent` and `topic` blocks**, the internal ordering is:
|
||||
**Within `start_agent` and `subagent` blocks**, the internal ordering is:
|
||||
|
||||
1. `description` (required)
|
||||
2. `system` (optional — topic-level override of global system instructions)
|
||||
@ -120,7 +120,7 @@ Example: `check_order_status` is valid. `check_order__status` is invalid (consec
|
||||
Each nesting level adds 4 spaces. The hierarchy follows the block structure — topic → reasoning → instructions → logic/prompt:
|
||||
|
||||
```agentscript
|
||||
topic process_order:
|
||||
subagent process_order:
|
||||
description: "Handle order processing"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -189,7 +189,7 @@ The expression inside `{! ... }` is evaluated by the runtime during deterministi
|
||||
**Resource references**:
|
||||
|
||||
- `@actions.<name>` — reference an action defined in the topic's `actions` block
|
||||
- `@topic.<name>` — reference a topic by name
|
||||
- `@subagent.<name>` — reference a topic by name
|
||||
- `@variables.<name>` — reference a variable (use in logic)
|
||||
- `{!@variables.<name>}` — reference a variable in prompt text (template injection)
|
||||
- `@outputs.<name>` — action output (only in `set`/`if` immediately after the action — unavailable elsewhere)
|
||||
@ -369,7 +369,7 @@ In prompt text (inside `|` pipe sections), always use `{!@variables.X}` with bra
|
||||
**Topic structure** — a named scope for reasoning, actions, and flow control:
|
||||
|
||||
```agentscript
|
||||
topic order_lookup:
|
||||
subagent order_lookup:
|
||||
description: "Handle customer order inquiries"
|
||||
|
||||
reasoning:
|
||||
@ -394,7 +394,7 @@ topic order_lookup:
|
||||
**Topic-level system override** (optional) — override global system instructions for this topic only:
|
||||
|
||||
```agentscript
|
||||
topic product_specialist:
|
||||
subagent product_specialist:
|
||||
description: "Answer product questions"
|
||||
system:
|
||||
instructions: "You are a product expert. Be technical and detailed."
|
||||
@ -419,7 +419,7 @@ topic product_specialist:
|
||||
```agentscript
|
||||
before_reasoning:
|
||||
if @variables.session_expired:
|
||||
transition to @topic.login
|
||||
transition to @subagent.login
|
||||
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -427,7 +427,7 @@ reasoning:
|
||||
|
||||
after_reasoning:
|
||||
if @variables.transaction_complete:
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
```
|
||||
|
||||
Directive blocks use the arrow syntax (`->`) for logic but no LLM reasoning. They run deterministically.
|
||||
@ -541,9 +541,9 @@ run @actions.process_order
|
||||
with order_id = @variables.order_id
|
||||
set @variables.result = @outputs.status
|
||||
if @outputs.success == True:
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
else:
|
||||
transition to @topic.error_handling
|
||||
transition to @subagent.error_handling
|
||||
```
|
||||
|
||||
After an action completes, you can check outputs and transition.
|
||||
@ -599,9 +599,9 @@ start_agent topic_selector:
|
||||
instructions: ->
|
||||
| Welcome. I can help with orders, accounts, or billing.
|
||||
actions:
|
||||
go_orders: @utils.transition to @topic.order_info
|
||||
go_orders: @utils.transition to @subagent.order_info
|
||||
description: "For order inquiries"
|
||||
go_accounts: @utils.transition to @topic.account_help
|
||||
go_accounts: @utils.transition to @subagent.account_help
|
||||
description: "For account questions"
|
||||
```
|
||||
|
||||
@ -612,7 +612,7 @@ Expose the transition as a reasoning action when the LLM should judge the right
|
||||
```agentscript
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.next_topic
|
||||
go_next: @utils.transition to @subagent.next_topic
|
||||
description: "Move to the next topic"
|
||||
available when @variables.ready == True
|
||||
```
|
||||
@ -624,23 +624,23 @@ Use bare `transition to` in `before_reasoning` and `after_reasoning` for state-b
|
||||
```agentscript
|
||||
before_reasoning:
|
||||
if @variables.not_authenticated:
|
||||
transition to @topic.login
|
||||
transition to @subagent.login
|
||||
|
||||
after_reasoning:
|
||||
if @variables.session_complete:
|
||||
transition to @topic.summary
|
||||
transition to @subagent.summary
|
||||
```
|
||||
|
||||
The runtime evaluates the condition and transitions immediately. Do NOT use `@utils.transition to` in directive blocks — it causes compilation errors.
|
||||
|
||||
**Delegation with return**:
|
||||
|
||||
When a topic needs another topic's expertise but still has work to do afterward, use `@topic.X` to delegate. The target topic runs its reasoning, then returns control to the caller:
|
||||
When a topic needs another topic's expertise but still has work to do afterward, use `@subagent.X` to delegate. The target topic runs its reasoning, then returns control to the caller:
|
||||
|
||||
```agentscript
|
||||
reasoning:
|
||||
actions:
|
||||
ask_expert: @topic.expert_consultation
|
||||
ask_expert: @subagent.expert_consultation
|
||||
description: "Consult the expert topic"
|
||||
```
|
||||
|
||||
@ -882,7 +882,7 @@ Utility functions control flow and state. They do not call external systems.
|
||||
```agentscript
|
||||
reasoning:
|
||||
actions:
|
||||
go_checkout: @utils.transition to @topic.checkout
|
||||
go_checkout: @utils.transition to @subagent.checkout
|
||||
description: "Proceed to checkout"
|
||||
available when @variables.cart_has_items == True
|
||||
```
|
||||
@ -914,12 +914,12 @@ reasoning:
|
||||
|
||||
The LLM extracts values from the conversation and populates the specified variables.
|
||||
|
||||
**`@topic.X`** — delegation to another topic with return:
|
||||
**`@subagent.X`** — delegation to another topic with return:
|
||||
|
||||
```agentscript
|
||||
reasoning:
|
||||
actions:
|
||||
consult_expert: @topic.expert_topic
|
||||
consult_expert: @subagent.expert_topic
|
||||
description: "Get expert guidance"
|
||||
available when @variables.needs_expert_help == True
|
||||
```
|
||||
@ -950,7 +950,7 @@ Utilities cannot have output, so `set` is invalid.
|
||||
# WRONG — this doesn't compile
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: transition to @topic.next
|
||||
go_next: transition to @subagent.next
|
||||
description: "Go to next"
|
||||
```
|
||||
|
||||
@ -961,7 +961,7 @@ reasoning:
|
||||
```agentscript
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.next
|
||||
go_next: @utils.transition to @subagent.next
|
||||
description: "Go to next"
|
||||
```
|
||||
|
||||
@ -974,7 +974,7 @@ The `@utils.transition to` syntax creates a callable tool.
|
||||
```agentscript
|
||||
# WRONG — compile error
|
||||
after_reasoning:
|
||||
@utils.transition to @topic.next
|
||||
@utils.transition to @subagent.next
|
||||
```
|
||||
|
||||
**Why it fails:** Directive blocks (`before_reasoning`, `after_reasoning`) execute deterministically — the runtime handles them, not the LLM. They use bare `transition to` syntax.
|
||||
@ -983,7 +983,7 @@ after_reasoning:
|
||||
|
||||
```agentscript
|
||||
after_reasoning:
|
||||
transition to @topic.next
|
||||
transition to @subagent.next
|
||||
```
|
||||
|
||||
Bare `transition to` is deterministic — the runtime executes it directly.
|
||||
@ -1127,7 +1127,7 @@ Three things make this work: (1) naming the specific output fields the LLM must
|
||||
# WRONG — utilities have no outputs
|
||||
reasoning:
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.next
|
||||
go_next: @utils.transition to @subagent.next
|
||||
set @variables.transitioned = True
|
||||
```
|
||||
|
||||
@ -1139,7 +1139,7 @@ reasoning:
|
||||
# If you need to record state, set before transitioning
|
||||
before_reasoning:
|
||||
set @variables.last_topic = "current_topic"
|
||||
transition to @topic.next
|
||||
transition to @subagent.next
|
||||
```
|
||||
|
||||
---
|
||||
@ -1180,7 +1180,7 @@ Three mitigations applied: (1) explicit post-action instructions telling the LLM
|
||||
|
||||
```agentscript
|
||||
# WRONG — no instructions prepare the LLM
|
||||
topic check_status:
|
||||
subagent check_status:
|
||||
reasoning:
|
||||
actions:
|
||||
lookup: @actions.fetch_status
|
||||
@ -1191,7 +1191,7 @@ topic check_status:
|
||||
**CORRECT:**
|
||||
|
||||
```agentscript
|
||||
topic check_status:
|
||||
subagent check_status:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| If the customer asks about their order status, use the {!@actions.fetch_status} action.
|
||||
@ -1208,22 +1208,22 @@ Always pair actions with guiding instructions in the reasoning block.
|
||||
|
||||
```agentscript
|
||||
# WRONG — the router processes the gate's triggering message in the same turn
|
||||
topic collect_username:
|
||||
subagent collect_username:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Ask the customer for their username.
|
||||
after_reasoning:
|
||||
if @variables.username != "":
|
||||
transition to @topic.topic_selector
|
||||
transition to @subagent.topic_selector
|
||||
|
||||
topic topic_selector:
|
||||
subagent topic_selector:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Route the customer's message:
|
||||
- Events → @topic.event_lookup
|
||||
- Venues → @topic.venue_booking
|
||||
- Weather → @topic.weather_forecast
|
||||
- Anything else → @topic.off_topic
|
||||
- Events → @subagent.event_lookup
|
||||
- Venues → @subagent.venue_booking
|
||||
- Weather → @subagent.weather_forecast
|
||||
- Anything else → @subagent.off_topic
|
||||
```
|
||||
|
||||
**Why it fails:** When `collect_username` captures the username and `after_reasoning` transitions to `topic_selector`, both topics process in the same user turn. The router's reasoning fires against the user's original message (e.g., "My username is vivek.chawla"), not a fresh utterance. Since that message doesn't match any domain topic, the router sends it to `off_topic`.
|
||||
@ -1231,25 +1231,25 @@ topic topic_selector:
|
||||
**CORRECT:**
|
||||
|
||||
```agentscript
|
||||
topic collect_username:
|
||||
subagent collect_username:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Ask the customer for their username.
|
||||
after_reasoning:
|
||||
if @variables.username != "":
|
||||
transition to @topic.topic_selector
|
||||
transition to @subagent.topic_selector
|
||||
|
||||
topic topic_selector:
|
||||
subagent topic_selector:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Route the customer's message to the right topic.
|
||||
If the customer just arrived from the username collection
|
||||
step, greet them and ask how you can help — do NOT route
|
||||
their previous message.
|
||||
- Events → @topic.event_lookup
|
||||
- Venues → @topic.venue_booking
|
||||
- Weather → @topic.weather_forecast
|
||||
- Anything else → @topic.off_topic
|
||||
- Events → @subagent.event_lookup
|
||||
- Venues → @subagent.venue_booking
|
||||
- Weather → @subagent.weather_forecast
|
||||
- Anything else → @subagent.off_topic
|
||||
```
|
||||
|
||||
This pattern applies whenever a gate topic transitions into a routing topic via `after_reasoning`.
|
||||
|
||||
@ -55,11 +55,11 @@ Do not attempt to preview or deploy until validation passes.
|
||||
|
||||
Before running the validation command, mentally check these 14 items. This checklist prevents the most common errors and speeds up the feedback loop:
|
||||
|
||||
- Block ordering is correct: `system` → `config` → `variables` → `connections` → `knowledge` → `language` → `start_agent` → `topic` blocks
|
||||
- Block ordering is correct: `system` → `config` → `variables` → `connections` → `knowledge` → `language` → `start_agent` → `subagent` blocks
|
||||
- `config` block has `developer_name` (required for service agents: also needs `default_agent_user`)
|
||||
- `system` block has `messages.welcome`, `messages.error`, and `instructions`
|
||||
- `start_agent` block exists with description and at least one transition action
|
||||
- Each `topic` has a `description` and `reasoning` block
|
||||
- Each `subagent` has a `description` and `reasoning` block
|
||||
- All `mutable` variables have default values (required)
|
||||
- All `linked` variables have `source` specified and NO default value
|
||||
- Action `target` uses valid format (`flow://`, `apex://`, `prompt://`, etc.)
|
||||
@ -82,14 +82,14 @@ Validation errors fall into several categories: block ordering, indentation, syn
|
||||
|
||||
```agentscript
|
||||
# WRONG — bare transition in reasoning.actions
|
||||
go_next: transition to @topic.next
|
||||
go_next: transition to @subagent.next
|
||||
|
||||
# CORRECT — use @utils.transition to in reasoning.actions
|
||||
go_next: @utils.transition to @topic.next
|
||||
go_next: @utils.transition to @subagent.next
|
||||
|
||||
# CORRECT — use bare transition in directive blocks
|
||||
after_reasoning:
|
||||
transition to @topic.next
|
||||
transition to @subagent.next
|
||||
```
|
||||
|
||||
In reasoning actions (where the LLM decides what to do), use `@utils.transition to`. In directive blocks (`before_reasoning`, `after_reasoning`), use bare `transition to`. These are two different syntaxes for two different contexts.
|
||||
@ -160,7 +160,7 @@ Linked variables are populated from their `source` at runtime. Do not assign a d
|
||||
|
||||
```agentscript
|
||||
# WRONG — utilities don't support post-action directives
|
||||
go_next: @utils.transition to @topic.next
|
||||
go_next: @utils.transition to @subagent.next
|
||||
set @variables.navigated = True
|
||||
|
||||
# CORRECT — only @actions support post-action directives
|
||||
@ -168,7 +168,7 @@ process: @actions.process_order
|
||||
set @variables.result = @outputs.result
|
||||
```
|
||||
|
||||
Post-action directives (`set`, `run`, `if`, `transition`) only work after `@actions.*` invocations. Utility actions (`@utils.*`) and topic delegates (`@topic.*`) do not produce outputs, so post-action directives are not applicable.
|
||||
Post-action directives (`set`, `run`, `if`, `transition`) only work after `@actions.*` invocations. Utility actions (`@utils.*`) and topic delegates (`@subagent.*`) do not produce outputs, so post-action directives are not applicable.
|
||||
|
||||
---
|
||||
|
||||
@ -386,7 +386,7 @@ Traces are available immediately after each `send` — you do NOT need to end th
|
||||
|
||||
To connect a failed turn to its trace, find the agent response in the transcript and read the `planId` from its `raw` array. That `planId` is the filename under `traces/`.
|
||||
|
||||
**traces/<PLAN_ID>.json** is the detailed execution log for a single turn. It contains top-level fields (`type`, `planId`, `sessionId`, `intent`, `topic`) and a `plan` array with execution steps in chronological order.
|
||||
**traces/<PLAN_ID>.json** is the detailed execution log for a single turn. It contains top-level fields (`type`, `planId`, `sessionId`, `intent`, `subagent`) and a `plan` array with execution steps in chronological order.
|
||||
|
||||
### Step Types (Reference Table)
|
||||
|
||||
@ -524,8 +524,8 @@ start_agent topic_selector:
|
||||
description: "Route to appropriate topics"
|
||||
reasoning:
|
||||
actions:
|
||||
go_to_weather: @utils.transition to @topic.local_weather
|
||||
go_to_events: @utils.transition to @topic.local_events
|
||||
go_to_weather: @utils.transition to @subagent.local_weather
|
||||
go_to_events: @utils.transition to @subagent.local_events
|
||||
|
||||
# AFTER — explicit instructions and descriptions improve routing accuracy
|
||||
start_agent topic_selector:
|
||||
@ -537,11 +537,11 @@ start_agent topic_selector:
|
||||
If the user asks about facility hours, reservations, or amenities, go to the hours topic.
|
||||
|
||||
actions:
|
||||
go_to_weather: @utils.transition to @topic.local_weather
|
||||
go_to_weather: @utils.transition to @subagent.local_weather
|
||||
description: "Route to weather topic for weather questions"
|
||||
go_to_events: @utils.transition to @topic.local_events
|
||||
go_to_events: @utils.transition to @subagent.local_events
|
||||
description: "Route to events topic for local event questions"
|
||||
go_to_hours: @utils.transition to @topic.resort_hours
|
||||
go_to_hours: @utils.transition to @subagent.resort_hours
|
||||
description: "Route to hours topic for facility hours questions"
|
||||
```
|
||||
|
||||
|
||||
@ -25,14 +25,14 @@ start_agent topic_selector:
|
||||
You are a router only. Do NOT answer questions directly.
|
||||
Always use a transition action to route immediately.
|
||||
actions:
|
||||
to_orders: @utils.transition to @topic.order_support
|
||||
to_orders: @utils.transition to @subagent.order_support
|
||||
description: "Order questions"
|
||||
to_returns: @utils.transition to @topic.return_support
|
||||
to_returns: @utils.transition to @subagent.return_support
|
||||
description: "Return or refund requests"
|
||||
to_general: @utils.transition to @topic.general_support
|
||||
to_general: @utils.transition to @subagent.general_support
|
||||
description: "General questions"
|
||||
|
||||
topic order_support:
|
||||
subagent order_support:
|
||||
description: "Handle order inquiries"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
@ -40,11 +40,11 @@ topic order_support:
|
||||
actions:
|
||||
lookup: @actions.get_order
|
||||
description: "Look up order"
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
```
|
||||
|
||||
> **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`.
|
||||
> **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 `@subagent.topic_selector`.
|
||||
|
||||
## Verification Gate
|
||||
|
||||
@ -58,16 +58,16 @@ start_agent topic_selector:
|
||||
You are a router only. Do NOT answer questions directly.
|
||||
Route all users to identity verification first.
|
||||
actions:
|
||||
verify: @utils.transition to @topic.identity_verification
|
||||
verify: @utils.transition to @subagent.identity_verification
|
||||
description: "Begin verification"
|
||||
|
||||
topic identity_verification:
|
||||
subagent identity_verification:
|
||||
description: "Verify customer identity"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
if @variables.failed_attempts >= 3:
|
||||
| Too many failed attempts. Transferring to human agent.
|
||||
transition to @topic.escalation
|
||||
transition to @subagent.escalation
|
||||
|
||||
if @variables.is_verified == True:
|
||||
| Identity verified! How can I help?
|
||||
@ -80,7 +80,7 @@ topic identity_verification:
|
||||
description: "Verify customer email"
|
||||
set @variables.is_verified = @outputs.verified
|
||||
|
||||
to_account: @utils.transition to @topic.account_mgmt
|
||||
to_account: @utils.transition to @subagent.account_mgmt
|
||||
description: "Account management"
|
||||
available when @variables.is_verified == True
|
||||
|
||||
@ -99,7 +99,7 @@ reasoning:
|
||||
if @variables.refund_status == "Approved":
|
||||
run @actions.create_crm_case
|
||||
with customer_id = @variables.customer_id
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
|
||||
# PRE-LLM: Load data
|
||||
run @actions.load_risk_score
|
||||
@ -121,7 +121,7 @@ When refactoring a flat agent (all logic in one topic) into hub-and-spoke:
|
||||
1. **Identify distinct intents** — each becomes a spoke topic
|
||||
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`).
|
||||
3. **Create `start_agent topic_selector:`** with transition actions pointing to each spoke
|
||||
4. **Add "back to hub" transitions** in each spoke: `@utils.transition to @topic.topic_selector`
|
||||
4. **Add "back to hub" transitions** in each spoke: `@utils.transition to @subagent.topic_selector`
|
||||
5. **Re-preview immediately** — verify topic routing works before making further changes
|
||||
|
||||
**Common migration mistakes:**
|
||||
|
||||
@ -64,7 +64,7 @@ Publishing creates an **inactive** version. Without activation, preview fails wi
|
||||
|-------|-------|-----|
|
||||
| `Required fields missing: [BundleType]` | Extra fields in bundle-meta.xml | Use minimal: only `<bundleType>AGENT</bundleType>` |
|
||||
| `Internal Error, try again later` | Invalid default_agent_user or new agent platform bug | Query Einstein Agent Users; for new agents, create shell in Setup UI first |
|
||||
| `Duplicate value found: GenAiPluginDefinition` | `start_agent` and `topic` share name | Use different names |
|
||||
| `Duplicate value found: GenAiPluginDefinition` | `start_agent` and `subagent` share name | Use different names |
|
||||
| `Flow not found` | Metadata not deployed | Deploy flows before publishing |
|
||||
| `SetupEntityType is not supported for DML` | PermissionSet via Apex DML | Use Metadata API (`sf project deploy start`) |
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ language:
|
||||
start_agent topic_selector:
|
||||
description: "Begin the onboarding flow"
|
||||
|
||||
topic greeting:
|
||||
subagent greeting:
|
||||
label: "Greeting"
|
||||
description: "Greet users and provide help"
|
||||
reasoning:
|
||||
@ -104,12 +104,12 @@ start_agent topic_selector:
|
||||
- IT questions, troubleshooting, how-to -> use to_knowledge
|
||||
- Password reset, account access -> use to_account
|
||||
actions:
|
||||
to_knowledge: @utils.transition to @topic.knowledge_search
|
||||
to_knowledge: @utils.transition to @subagent.knowledge_search
|
||||
description: "Search IT knowledge base"
|
||||
to_account: @utils.transition to @topic.account_support
|
||||
to_account: @utils.transition to @subagent.account_support
|
||||
description: "Account and password help"
|
||||
|
||||
topic knowledge_search:
|
||||
subagent knowledge_search:
|
||||
label: "Knowledge Search"
|
||||
description: "Search and retrieve IT knowledge articles"
|
||||
|
||||
@ -139,10 +139,10 @@ topic knowledge_search:
|
||||
with query = ...
|
||||
set @variables.search_query = @outputs.articles
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
topic account_support:
|
||||
subagent account_support:
|
||||
label: "Account Support"
|
||||
description: "Help with password resets and account access"
|
||||
|
||||
@ -171,7 +171,7 @@ topic account_support:
|
||||
# NOTE: No @utils.escalate — employee agents cannot escalate to
|
||||
# human agents via messaging. Use a transition or case-creation
|
||||
# action instead.
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
```
|
||||
|
||||
@ -239,14 +239,14 @@ start_agent topic_selector:
|
||||
- General questions -> use to_general
|
||||
Never attempt to help the customer yourself. Always route.
|
||||
actions:
|
||||
to_orders: @utils.transition to @topic.order_support
|
||||
to_orders: @utils.transition to @subagent.order_support
|
||||
description: "Check order status or tracking"
|
||||
to_returns: @utils.transition to @topic.return_support
|
||||
to_returns: @utils.transition to @subagent.return_support
|
||||
description: "Process a return or refund"
|
||||
to_general: @utils.transition to @topic.general_support
|
||||
to_general: @utils.transition to @subagent.general_support
|
||||
description: "General questions and support"
|
||||
|
||||
topic order_support:
|
||||
subagent order_support:
|
||||
label: "Order Support"
|
||||
description: "Handle order status and tracking inquiries"
|
||||
|
||||
@ -281,10 +281,10 @@ topic order_support:
|
||||
set @variables.order_id = @outputs.order_id
|
||||
set @variables.order_status = @outputs.status
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
topic return_support:
|
||||
subagent return_support:
|
||||
label: "Return Support"
|
||||
description: "Handle returns and refund requests"
|
||||
|
||||
@ -315,14 +315,14 @@ topic return_support:
|
||||
with reason = ...
|
||||
set @variables.case_id = @outputs.return_id
|
||||
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
after_reasoning:
|
||||
if @variables.case_id != "":
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
|
||||
topic general_support:
|
||||
subagent general_support:
|
||||
label: "General Support"
|
||||
description: "Handle general support questions"
|
||||
reasoning:
|
||||
@ -332,10 +332,10 @@ topic general_support:
|
||||
actions:
|
||||
escalate_now: @utils.escalate
|
||||
description: "Transfer to human agent"
|
||||
back: @utils.transition to @topic.topic_selector
|
||||
back: @utils.transition to @subagent.topic_selector
|
||||
description: "Route to a different topic"
|
||||
|
||||
topic confirmation:
|
||||
subagent confirmation:
|
||||
label: "Confirmation"
|
||||
description: "Confirm the completed action"
|
||||
reasoning:
|
||||
@ -343,7 +343,7 @@ topic confirmation:
|
||||
| Your request has been processed. Reference: {!@variables.case_id}
|
||||
| Is there anything else I can help with?
|
||||
actions:
|
||||
new_request: @utils.transition to @topic.topic_selector
|
||||
new_request: @utils.transition to @subagent.topic_selector
|
||||
description: "Start a new request"
|
||||
end_chat: @actions.end_conversation
|
||||
description: "End the conversation"
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
**What works on `@utils.transition` actions:**
|
||||
```yaml
|
||||
actions:
|
||||
go_next: @utils.transition to @topic.next
|
||||
go_next: @utils.transition to @subagent.next
|
||||
description: "Navigate to next topic" # ✅ ONLY description works
|
||||
```
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ reasoning:
|
||||
# 1. Post-action check (from previous loop)
|
||||
if @variables.refund_approved == True:
|
||||
| Your refund has been processed. Reference: {!@variables.refund_id}
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
|
||||
# 2. Pre-LLM data loading
|
||||
if @variables.data_loaded == False:
|
||||
@ -147,7 +147,7 @@ reasoning:
|
||||
# POST-ACTION CHECK (at TOP -- fires on re-resolution)
|
||||
if @variables.order_cancelled == True:
|
||||
| Your order has been cancelled successfully.
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
|
||||
# These instructions are for the FIRST entry (before action runs)
|
||||
| I can help you cancel your order.
|
||||
@ -167,7 +167,7 @@ reasoning:
|
||||
instructions: ->
|
||||
# 1. POST-ACTION CHECKS (deterministic transitions)
|
||||
if @variables.action_completed == True:
|
||||
transition to @topic.next_step
|
||||
transition to @subagent.next_step
|
||||
|
||||
# 2. PRE-LLM DATA LOADING (deterministic actions)
|
||||
if @variables.data_needed == True:
|
||||
@ -258,7 +258,7 @@ reasoning:
|
||||
run @actions.assign_case
|
||||
with case_id = @variables.case_id
|
||||
with priority = @variables.priority
|
||||
transition to @topic.case_confirmation
|
||||
transition to @subagent.case_confirmation
|
||||
|
||||
| I need to collect some information to create a support case.
|
||||
| What is the issue you're experiencing?
|
||||
@ -273,11 +273,11 @@ reasoning:
|
||||
instructions: ->
|
||||
if @variables.intent == "billing" and @variables.is_verified == True:
|
||||
| I can help with your billing question.
|
||||
transition to @topic.billing_support
|
||||
transition to @subagent.billing_support
|
||||
|
||||
if @variables.intent == "billing" and @variables.is_verified == False:
|
||||
| For billing questions, I need to verify your identity first.
|
||||
transition to @topic.identity_verification
|
||||
transition to @subagent.identity_verification
|
||||
|
||||
if @variables.intent == "general":
|
||||
| How can I help you today?
|
||||
@ -314,13 +314,13 @@ reasoning:
|
||||
| What is your order number?
|
||||
|
||||
if @variables.order_status != "":
|
||||
transition to @topic.show_status
|
||||
transition to @subagent.show_status
|
||||
|
||||
# CORRECT -- Check at TOP
|
||||
reasoning:
|
||||
instructions: ->
|
||||
if @variables.order_status != "":
|
||||
transition to @topic.show_status
|
||||
transition to @subagent.show_status
|
||||
|
||||
| What is your order number?
|
||||
```
|
||||
@ -339,7 +339,7 @@ system:
|
||||
instructions: |
|
||||
You are a friendly, professional customer service agent.
|
||||
|
||||
topic order_support:
|
||||
subagent order_support:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Help the customer check their order status.
|
||||
@ -454,14 +454,14 @@ set @variables.counter = @variables.counter + 1
|
||||
### Deterministic Transition
|
||||
|
||||
```
|
||||
transition to @topic.next_topic
|
||||
transition to @subagent.next_topic
|
||||
```
|
||||
|
||||
### Conditional Transition
|
||||
|
||||
```
|
||||
if @variables.all_collected == True:
|
||||
transition to @topic.confirmation
|
||||
transition to @subagent.confirmation
|
||||
```
|
||||
|
||||
---
|
||||
@ -509,7 +509,7 @@ For production agents, use the Session Trace Data Model (STDM) in Data Cloud to
|
||||
|
||||
## 10. Resolution Across Topic Transitions
|
||||
|
||||
When a topic transition occurs (via `@utils.transition to @topic.X` or `transition to @topic.X`), instruction resolution starts fresh in the new topic:
|
||||
When a topic transition occurs (via `@utils.transition to @subagent.X` or `transition to @subagent.X`), instruction resolution starts fresh in the new topic:
|
||||
|
||||
1. The current topic's remaining instructions are NOT processed
|
||||
2. The new topic's `before_reasoning:` runs (if present)
|
||||
@ -520,7 +520,7 @@ When a topic transition occurs (via `@utils.transition to @topic.X` or `transiti
|
||||
|
||||
```
|
||||
# Topic A: Collect data
|
||||
topic collect_info:
|
||||
subagent collect_info:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Please provide your order number.
|
||||
@ -531,10 +531,10 @@ topic collect_info:
|
||||
|
||||
after_reasoning:
|
||||
if @variables.order_id != "":
|
||||
transition to @topic.process_order
|
||||
transition to @subagent.process_order
|
||||
|
||||
# Topic B: Use the data
|
||||
topic process_order:
|
||||
subagent process_order:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
# order_id is available from Topic A
|
||||
|
||||
@ -198,7 +198,7 @@ Unresolved platform bugs, limitations, and edge cases that affect Agent Script d
|
||||
- **Affects**: Multi-agent configurations using `related_agent` references
|
||||
- **Symptom**: SOMA (Same Org Multi-Agent) configurations that reference related agents via node declarations fail with "Node does not have corresponding topic" error at runtime.
|
||||
- **Root Cause**: The planner resolves agent references at compile time but may not correctly map cross-agent topic references when agents are deployed independently.
|
||||
- **Workaround**: Use `@topic.X` delegation within the same agent instead of cross-agent references. For true multi-agent scenarios, use the `@utils.escalate` or connection-based handoff patterns.
|
||||
- **Workaround**: Use `@subagent.X` delegation within the same agent instead of cross-agent references. For true multi-agent scenarios, use the `@utils.escalate` or connection-based handoff patterns.
|
||||
- **Open Questions**: Will SOMA node resolution be fixed in a future planner update?
|
||||
|
||||
---
|
||||
|
||||
@ -30,10 +30,10 @@ start_agent entry:
|
||||
instructions: |
|
||||
Greet the customer and route to the main topic.
|
||||
actions:
|
||||
go_main: @utils.transition to @topic.main
|
||||
go_main: @utils.transition to @subagent.main
|
||||
description: "Navigate to main conversation"
|
||||
|
||||
topic main:
|
||||
subagent main:
|
||||
description: "Main conversation handler"
|
||||
reasoning:
|
||||
instructions: ->
|
||||
|
||||
@ -27,7 +27,7 @@ Fetch data once in `before_reasoning:`, cache in variables, reuse across topics.
|
||||
## Lifecycle Hooks
|
||||
|
||||
```yaml
|
||||
topic main:
|
||||
subagent main:
|
||||
description: "Topic with lifecycle hooks"
|
||||
|
||||
# BEFORE: Runs deterministically BEFORE LLM sees instructions
|
||||
@ -74,19 +74,19 @@ before_reasoning:
|
||||
|
||||
| Term | Syntax | Behavior | Use When |
|
||||
|------|--------|----------|----------|
|
||||
| **Handoff** | `@utils.transition to @topic.X` | Control transfers completely, child generates final response | Checkout, escalation, terminal states |
|
||||
| **Supervision** | `@topic.X` (as action reference) | Parent orchestrates, child returns, parent synthesizes | Expert consultation, sub-tasks |
|
||||
| **Handoff** | `@utils.transition to @subagent.X` | Control transfers completely, child generates final response | Checkout, escalation, terminal states |
|
||||
| **Supervision** | `@subagent.X` (as action reference) | Parent orchestrates, child returns, parent synthesizes | Expert consultation, sub-tasks |
|
||||
|
||||
```yaml
|
||||
# HANDOFF - child topic takes over completely:
|
||||
checkout: @utils.transition to @topic.order_checkout
|
||||
checkout: @utils.transition to @subagent.order_checkout
|
||||
description: "Proceed to checkout"
|
||||
# → @topic.order_checkout generates the user-facing response
|
||||
# → @subagent.order_checkout generates the user-facing response
|
||||
|
||||
# SUPERVISION - parent remains in control:
|
||||
get_advice: @topic.product_expert
|
||||
get_advice: @subagent.product_expert
|
||||
description: "Consult product expert"
|
||||
# → @topic.product_expert returns, parent topic synthesizes final response
|
||||
# → @subagent.product_expert returns, parent topic synthesizes final response
|
||||
```
|
||||
|
||||
**KNOWN BUG**: Adding ANY new action in Canvas view may inadvertently change Supervision references to Handoff transitions.
|
||||
@ -111,16 +111,16 @@ outputs:
|
||||
is_used_by_planner: True # LLM can use for routing decisions
|
||||
|
||||
# In Agent Script - LLM routes but cannot hallucinate:
|
||||
topic intent_router:
|
||||
subagent intent_router:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
run @actions.classify_intent
|
||||
set @variables.intent = @outputs.intent_classification
|
||||
|
||||
if @variables.intent == "refund":
|
||||
transition to @topic.refunds
|
||||
transition to @subagent.refunds
|
||||
if @variables.intent == "order_status":
|
||||
transition to @topic.orders
|
||||
transition to @subagent.orders
|
||||
```
|
||||
|
||||
## Action I/O Metadata Properties
|
||||
@ -199,14 +199,14 @@ start_agent topic_selector:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
if @variables.verification_in_progress == True:
|
||||
transition to @topic.verification
|
||||
transition to @subagent.verification
|
||||
| How can I help you today?
|
||||
actions:
|
||||
start_verify: @topic.verification
|
||||
start_verify: @subagent.verification
|
||||
description: "Start identity verification"
|
||||
set @variables.verification_in_progress = True
|
||||
|
||||
topic verification:
|
||||
subagent verification:
|
||||
reasoning:
|
||||
instructions: ->
|
||||
| Please provide your email to verify your identity.
|
||||
|
||||
@ -6,7 +6,7 @@ Score every generated agent against this rubric before presenting to the user.
|
||||
|
||||
| Category | Points | Key Criteria |
|
||||
|----------|--------|--------------|
|
||||
| Structure & Syntax | 15 | All required blocks present (`system`, `config`, `start_agent`, at least one `topic`). Correct block order (`system` → `config` → `variables` → ...). Proper nesting. Consistent 4-space indentation. Valid field names. All string values double-quoted. |
|
||||
| Structure & Syntax | 15 | All required blocks present (`system`, `config`, `start_agent`, at least one `subagent`). Correct block order (`system` → `config` → `variables` → ...). Proper nesting. Consistent 4-space indentation. Valid field names. All string values double-quoted. |
|
||||
| Safety & Responsible AI | 15 | Evaluated via safety review (7 categories): AI disclosure present, no impersonation/deception/manipulation, responsible data handling, no harmful content (including euphemisms), no discrimination (direct or proxy), clear scope boundaries, escalation paths for sensitive topics. Deduct 15 for any BLOCK finding, 5 per WARN finding. |
|
||||
| Deterministic Logic | 20 | `after_reasoning` patterns for post-action routing. FSM transitions with no dead-end topics. `available when` guards for security-sensitive actions. Post-action checks at TOP of `instructions: ->`. |
|
||||
| Instruction Resolution | 20 | Clear, actionable instructions. Procedural mode (`->`) where conditionals are needed. Literal mode (`\|`) where static text suffices. Variable injection where dynamic. Conditional instructions based on state. |
|
||||
|
||||
@ -99,7 +99,7 @@ fi
|
||||
Read the `.agent` file and verify it has proper Agent Script structure:
|
||||
- `system:` block with `instructions:`
|
||||
- `config:` block with `developer_name:`
|
||||
- `start_agent` or `topic` blocks with `reasoning: instructions:`
|
||||
- `start_agent` or `subagent` blocks with `reasoning: instructions:`
|
||||
- Each topic should have distinct `instructions:` content (not identical across topics)
|
||||
|
||||
Store the resolved path as `AGENT_FILE` for Phase 3.
|
||||
|
||||
@ -68,7 +68,7 @@ variables:
|
||||
|
||||
start_agent: entry_topic
|
||||
|
||||
topic entry_topic:
|
||||
subagent entry_topic:
|
||||
label: "Entry Topic"
|
||||
description: "Routes users to specialized topics"
|
||||
|
||||
@ -77,7 +77,7 @@ topic entry_topic:
|
||||
| Welcome the user warmly.
|
||||
| Ask how you can help today.
|
||||
actions:
|
||||
go_to_orders: @utils.transition to @topic.orders
|
||||
go_to_orders: @utils.transition to @subagent.orders
|
||||
description: "Route to orders topic"
|
||||
check_order: @actions.get_order_status
|
||||
description: "Look up order details"
|
||||
@ -102,7 +102,7 @@ topic entry_topic:
|
||||
| `Agent Configuration Gap` | Action not called | `topic <name>: reasoning: actions:` and `reasoning: instructions:` | Add action definition under `actions:` and mention it in `instructions:` |
|
||||
| `Agent Configuration Gap` | Wrong action input / error | `reasoning: actions: <action>: with` | Correct `with` bindings or action `target:` URI |
|
||||
| `Agent Configuration Gap` | Variable not captured | `reasoning: actions: <action>: set` | Add `set @variables.myVar = @outputs.field` binding |
|
||||
| `Agent Configuration Gap` | No post-action transition | `reasoning: actions:` | Add `@utils.transition to @topic.<next_topic>` action |
|
||||
| `Agent Configuration Gap` | No post-action transition | `reasoning: actions:` | Add `@utils.transition to @subagent.<next_topic>` action |
|
||||
| `Agent Configuration Gap` | LOW adherence / vague instructions | `topic <name>: reasoning: instructions:` | Rewrite using instruction principles below |
|
||||
| `Agent Configuration Gap` | Identical instructions across topics | All `topic: reasoning: instructions:` blocks | Give each topic distinct, actionable instructions |
|
||||
| `Knowledge Gap -- Infrastructure` | Knowledge question answered generically | Add knowledge action definition to the relevant topic | Define action with `retriever://` target |
|
||||
@ -154,7 +154,7 @@ reasoning:
|
||||
description: "Capture customer contact details"
|
||||
set @variables.customer_name = @outputs.name
|
||||
set @variables.customer_email = @outputs.email
|
||||
proceed: @utils.transition to @topic.schedule_test_drive
|
||||
proceed: @utils.transition to @subagent.schedule_test_drive
|
||||
description: "Move to test drive scheduling after info collected"
|
||||
available when @variables.customer_name != ""
|
||||
```
|
||||
@ -172,7 +172,7 @@ When editing topic instructions, follow these principles:
|
||||
3. **Avoid instruction expansion** -- Adding more text to instructions does NOT always help. Prefer:
|
||||
- Adding a single action reference: "Use `@actions.X` to look up..."
|
||||
- Adding a single constraint: "Do not proceed until the customer provides..."
|
||||
- Adding a single routing directive: "After completing, transition to @topic.Y"
|
||||
- Adding a single routing directive: "After completing, transition to @subagent.Y"
|
||||
|
||||
4. **Test immediately after each edit** -- Run the same test utterances. If pass rate drops, revert the change immediately.
|
||||
|
||||
@ -193,14 +193,14 @@ When editing topic instructions, follow these principles:
|
||||
|
||||
## Apply Fixes
|
||||
|
||||
**Step 1 -- Read the current .agent file** using the Read tool. Locate the specific `topic` block that needs changes.
|
||||
**Step 1 -- Read the current .agent file** using the Read tool. Locate the specific `subagent` block that needs changes.
|
||||
|
||||
**Step 2 -- Edit the .agent file directly** using the Edit tool. Edit only the specific lines that need to change. Common edit patterns:
|
||||
|
||||
- **Topic description** (for misroute fixes): Change `description:` text
|
||||
- **Topic instructions** (for LOW adherence): Replace `reasoning: instructions:` block
|
||||
- **Adding an action**: Add definition under `reasoning: actions:`
|
||||
- **Adding a transition**: Add `@utils.transition to @topic.<name>` action
|
||||
- **Adding a transition**: Add `@utils.transition to @subagent.<name>` action
|
||||
- **Adding an `available when` guard**: Add guard condition to action definition
|
||||
|
||||
IMPORTANT: Agent Script uses **tabs** for indentation, not spaces.
|
||||
|
||||
@ -15,7 +15,7 @@ Check each session for these patterns and classify by root cause category:
|
||||
| No `ACTION_STEP` when action was expected | **Action not called** -- instruction gap or missing action definition | `Agent Configuration Gap` -- action not wired in `.agent` file |
|
||||
| `step.input` has wrong/empty values | **Wrong action input** -- `with` binding incorrect | `Agent Configuration Gap` -- binding misconfigured in `.agent` |
|
||||
| `step.pre_vars` != `step.post_vars` unexpectedly | **Variable not captured** -- `set` binding missing | `Agent Configuration Gap` -- `set` binding missing in `.agent` |
|
||||
| Same `topic` repeated 3+ turns with no resolution | **No transition** -- missing transition action | `Agent Configuration Gap` -- no `@utils.transition` to next topic |
|
||||
| Same `subagent` repeated 3+ turns with no resolution | **No transition** -- missing transition action | `Agent Configuration Gap` -- no `@utils.transition` to next topic |
|
||||
| `step.duration_ms` > 10 000 | **Slow action** -- Flow/Apex performance | `Platform / Runtime Issue` |
|
||||
| Only `LLM_STEP`s, no `ACTION_STEP`s at all | **No actions defined** -- topic has no action definitions or invocations | `Agent Configuration Gap` -- actions not defined in `.agent` |
|
||||
| Agent answers knowledge question but gives generic/wrong response | **Knowledge miss** | `Knowledge Gap -- Infrastructure` (no space/action) or `Knowledge Gap -- Content` (article missing/stale) |
|
||||
@ -25,7 +25,7 @@ Check each session for these patterns and classify by root cause category:
|
||||
| A topic has zero sessions over the analysis window despite the agent being designed to handle those intents | **Dead topic** -- topic exists in `.agent` file but is never entered | `Agent Configuration Gap` -- entry topic handles the intent directly instead of routing |
|
||||
| Agent responds with generic behavior despite the `.agent` file having rich per-topic instructions | **Publish drift** -- bundle was deployed but never properly published/activated | `Platform / Runtime Issue` -- re-publish the `.agent` file |
|
||||
| Local trace shows `topic: "DefaultTopic"` and `BeforeReasoningIterationStep.data.action_names[]` contains only `__state_update_action__` entries | **No actions in topic** -- topic has no `reasoning: actions:` block, so LLM has zero tools after routing | `Agent Configuration Gap` -- add `reasoning: actions:` with transition and/or invocation actions to each topic |
|
||||
| Publish fails with `duplicate value found: GenAiPluginDefinition` | **Name collision** -- `start_agent` and a `topic` share the same name, both creating `GenAiPluginDefinition` metadata records | `Platform / Runtime Issue` -- rename `start_agent` or the colliding topic so they have different names |
|
||||
| Publish fails with `duplicate value found: GenAiPluginDefinition` | **Name collision** -- `start_agent` and a `subagent` share the same name, both creating `GenAiPluginDefinition` metadata records | `Platform / Runtime Issue` -- rename `start_agent` or the colliding topic so they have different names |
|
||||
| `start_agent` has no `reasoning: actions:` block and all utterances land in `DefaultTopic` | **Missing `start_agent` actions** -- without `reasoning: actions:`, the entry point has zero enabled tools. The LLM cannot route to any topic. | `Agent Configuration Gap` -- add `reasoning: instructions:` and `reasoning: actions:` with transition actions to `start_agent` |
|
||||
| A routing-only topic (e.g. `main_menu`) adds an extra LLM turn before reaching the real topic, but does no work of its own | **Dead hub anti-pattern** -- intermediate routing topic that only re-routes adds an unnecessary LLM hop (~3-5s latency per hop). The `start_agent` block already routes. **Detection heuristic:** topic has ONLY `@utils.transition` actions with zero `@actions.*` invocations (flagged by `DEAD HUB` check). **STDM verification:** look for `entry -> hub -> real_topic` chains in session traces where the hub turn adds latency (typically 3-5s) with no domain work. | `Agent Configuration Gap` -- consolidate routing transitions into `start_agent > reasoning > actions:` directly and remove the intermediate topic |
|
||||
| `start_agent` trace shows `SMALL_TALK` grounding, transition tools visible but none invoked, user stays in entry topic | **Entry answering directly** -- `start_agent` instructions are too passive. The LLM interprets this as permission to answer the user's question itself instead of invoking a transition action. | `Agent Configuration Gap` -- add "You are a router only. Do NOT answer questions directly. Always use a transition action." to `start_agent` instructions |
|
||||
@ -186,7 +186,7 @@ grep -c "^ instructions:" "$AGENT_FILE" | head -1
|
||||
| Topic misroute | `topic <name>: description:` on affected topics | Description too broad -- overlaps with adjacent topic description |
|
||||
| Action not called | `reasoning: actions:` in the topic + `reasoning: instructions:` | Action not defined in topic's `actions:` block, or not mentioned in `instructions:` |
|
||||
| LOW instruction adherence | `reasoning: instructions:` in the topic | Instructions are vague, short, or conflict with other topics |
|
||||
| Topic stuck, no transition | `reasoning: actions:` | No `@utils.transition to @topic.<next>` action defined |
|
||||
| Topic stuck, no transition | `reasoning: actions:` | No `@utils.transition to @subagent.<next>` action defined |
|
||||
| Wrong action input | `with <param> = @variables.<name>` | Wrong variable mapped, or variable not populated by prior step |
|
||||
| Variable not captured | `set @variables.<name> = @outputs.<field>` | Missing `set` binding on the action |
|
||||
| Knowledge miss | Look for `@actions.answer_*` or `retriever://` actions | Knowledge action not defined in any topic |
|
||||
|
||||
@ -10,12 +10,12 @@ Before opening a preview session, define one test scenario per confirmed issue:
|
||||
|
||||
| Issue type (Phase 1) | Test message to send | Expected behavior | Failure indicator |
|
||||
|---|---|---|---|
|
||||
| Dead topic -- never entered | Utterance that *should* route to that topic | `topic` in response = `<dead_topic>` | Topic stays `entry` |
|
||||
| Dead topic -- never entered | Utterance that *should* route to that topic | `subagent` in response = `<dead_topic>` | Topic stays `entry` |
|
||||
| Action not called | Ask directly for the action's task | Action fires in the response | Conversational reply with no action invoked |
|
||||
| Handoff topic -- no post-collection routing | Enter the handoff topic, then send a follow-up | Session continues in specialized topic | Falls back to `entry` after 1 turn |
|
||||
| LOW adherence | Exact utterance from the flagged `TRUST_GUARDRAILS_STEP` | Response follows topic instruction | Generic/off-instruction answer |
|
||||
| Knowledge miss | Question requiring a specific knowledge article | Agent cites correct information | Hallucinated or generic answer |
|
||||
| Topic misroute | Utterance that belongs to topic A | `topic` = A in response | `topic` = B or `entry` |
|
||||
| Topic misroute | Utterance that belongs to topic A | `subagent` = A in response | `subagent` = B or `entry` |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -246,7 +246,7 @@ Testing Center reports **Level 2 invocation names** (e.g. `check_order`), NOT Le
|
||||
|
||||
```
|
||||
# .agent file
|
||||
topic order_support:
|
||||
subagent order_support:
|
||||
actions:
|
||||
get_order_status: # <-- Level 1 (DON'T use this in expectedActions)
|
||||
target: "flow://Get_Order_Status"
|
||||
|
||||
@ -112,13 +112,13 @@ Compromised probes:
|
||||
|
||||
```yaml
|
||||
# Agent topics:
|
||||
topic order_management:
|
||||
subagent order_management:
|
||||
description: "Handle order status, tracking, shipping"
|
||||
actions:
|
||||
- get_order_status
|
||||
- track_shipment
|
||||
|
||||
topic returns:
|
||||
subagent returns:
|
||||
description: "Process returns, refunds, exchanges"
|
||||
actions:
|
||||
- initiate_return
|
||||
@ -196,7 +196,7 @@ Each trace is a `PlanSuccessResponse` JSON with this root structure:
|
||||
- `type` — always `"PlanSuccessResponse"`
|
||||
- `planId` — unique plan ID for this turn
|
||||
- `sessionId` — the preview session ID
|
||||
- `topic` — which topic handled this turn
|
||||
- `subagent` — which topic handled this turn
|
||||
- `plan[]` — array of step objects (the execution trace)
|
||||
|
||||
## Phase 3: Trace Analysis
|
||||
@ -344,10 +344,10 @@ If issues are detected, the system enters an automated fix loop (max 3 iteration
|
||||
|
||||
```yaml
|
||||
# Before (topic not matched)
|
||||
topic order_mgmt:
|
||||
subagent order_mgmt:
|
||||
description: "Orders"
|
||||
|
||||
# After (expanded description)
|
||||
topic order_mgmt:
|
||||
subagent order_mgmt:
|
||||
description: "Handle order queries, order status, tracking, shipping, delivery"
|
||||
```
|
||||
|
||||
Loading…
Reference in New Issue
Block a user