@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:
Willie Ruemmele 2026-04-10 08:39:39 -06:00
parent 7b5c4b1a76
commit df3467f20b
No known key found for this signature in database
GPG Key ID: 1D9B229D6258195C
52 changed files with 451 additions and 451 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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:

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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: |

View File

@ -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: ->

View File

@ -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"

View File

@ -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."

View File

@ -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"

View File

@ -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.

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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 != ""
# ═══════════════════════════════════════════════════════════════════════════

View File

@ -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) |

View File

@ -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:

View File

@ -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"

View File

@ -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

View File

@ -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
#

View File

@ -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
#

View File

@ -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
#

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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: |

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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`.

View File

@ -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"
```

View File

@ -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:**

View File

@ -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`) |

View File

@ -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"

View File

@ -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
```

View File

@ -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

View File

@ -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?
---

View File

@ -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: ->

View File

@ -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.

View File

@ -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. |

View File

@ -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.

View File

@ -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.

View File

@ -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 |

View File

@ -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` |
---

View File

@ -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"

View File

@ -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"
```