afv-library/skills/agentforce-generate/assets/patterns/lifecycle-events.agent

127 lines
4.7 KiB
Plaintext

# Lifecycle Events Pattern
# Use before_reasoning and after_reasoning for per-turn external work
#
# ★ When To Use This Pattern:
# - Refresh external context BEFORE the LLM starts reasoning
# - Clean up or log AFTER reasoning completes
# - Supply trusted action output that instructions need to reference
#
# ★ Key Insight:
# - before_reasoning: Runs when execution reaches the pre-reasoning hook
# - after_reasoning: Runs when execution reaches the post-reasoning hook
# - Hook contents are deterministic, unlike LLM-chosen actions
#
# ★ CRITICAL SYNTAX RULES for Lifecycle Blocks:
# 1. Use "transition to" NOT "@utils.transition to" for transitions
# 2. The pipe (|) command is NOT supported in lifecycle blocks
# 3. after_reasoning may NOT run if a transition occurs mid-subagent
# 4. `run` is supported for deterministic action execution and callbacks.
#
# ★ Common Use Cases:
# - Fetch fresh data before each response
# - Log conversation analytics after each turn
# - Conditional routing based on state (use "transition to")
#
# This is a COMPLETE template - customize actions and metadata.
system:
instructions: |
You are a context-aware service assistant. Answer using the external
context refreshed for the current turn. Do not infer external facts
that are absent from the refresh result.
messages:
welcome: "Hello! How can I help?"
error: "I couldn't refresh the information needed for that request."
access:
default_agent_user: "agent@company.salesforce.com"
config:
developer_name: "Lifecycle_Events_Agent"
agent_label: "Lifecycle Events"
description: "Demonstrates deterministic context refresh and analytics logging"
variables:
EndUserId: linked string
source: @MessagingSession.MessagingEndUserId
description: "Messaging end user identifier"
RoutableId: linked string
source: @MessagingSession.Id
description: "Messaging session identifier for analytics"
current_context: mutable string = ""
description: "Trusted external context refreshed and consumed on each turn"
language:
default_locale: "en_US"
start_agent conversation:
label: "Conversation"
description: "Main conversation handler with lifecycle tracking"
actions:
refresh_context:
description: "Fetches latest context for user"
inputs:
user_id: string
description: "User to get context for"
outputs:
context: string
description: "User's current context"
target: "flow://Get_User_Context"
log_turn:
description: "Logs conversation turn analytics"
inputs:
session_id: string
description: "Messaging session being logged"
handler_name: string
description: "Request handler producing the event"
outputs:
logged: boolean
description: "Whether log succeeded"
target: "apex://AnalyticsLogTurn"
# ★ before_reasoning: Runs once when this handler enters its reasoning loop
before_reasoning:
# ★ CORRECT: Use "transition to" (not @utils.transition to) in lifecycle blocks
# Example: Route away if session expired
# if @variables.session_expired == True:
# transition to @subagent.session_expired
# Refresh context before every turn
run @actions.refresh_context
with user_id=@variables.EndUserId
set @variables.current_context = @outputs.context
# Main reasoning block
reasoning:
instructions: ->
| Current user context:
| {!@variables.current_context}
|
| Respond helpfully using the refreshed context above.
actions:
end_conversation: @utils.transition to @subagent.farewell
# ★ after_reasoning: Runs once when this handler completes its reasoning loop
after_reasoning:
# Log analytics for each turn
run @actions.log_turn
with session_id=@variables.RoutableId
with handler_name="conversation"
# ★ Insight: Lifecycle blocks vs Action callbacks
#
# - before_reasoning/after_reasoning: Run automatically when execution reaches them
# - run callbacks: Run only when parent action is invoked
#
# Use lifecycle for: External context refresh, logging, and session management
# Use callbacks for: Post-action processing, chained operations
subagent farewell:
label: "Farewell"
description: "Ends the conversation when the user is finished"
reasoning:
instructions: ->
| Thank the user and close the conversation politely.