Action parameters
Action parameters are the arguments NeMo passes to an action by name: context holds the conversation variables, and any other name comes from the Colang call.
Last updated: 30 Sep, 2026 · NeMo Guardrails 0.24.1
The PII action in @action and register_action asked for context and got one, though nothing in the Colang passed it. The runtime fills the parameters it knows by name.
Syntax:
async def my_action(context: dict): # filled by the runtime
context["user_message"] # the message being checked
$status = execute lookup_ticket(ticket_id=$ticket_id) # your own arguments, by nameAn action that prints what it is given
from nemoguardrails.actions import action
@action(is_system_action=True)
async def peek_context(context: dict):
print(sorted(context))
return Truedefine flow peek
$ok = execute peek_contextView the code here
models:
- type: main
engine: openai
model: openai/gpt-oss-120b
api_key_env_var: GROQ_API_KEY
parameters:
base_url: https://api.groq.com/openai/v1
temperature: 0
instructions:
- type: general
content: |
You are an Enterprise IT Assistant specialising in Kubernetes,
Intel hardware, and enterprise networking.
Only answer questions about these topics.
Answer in one or two short sentences.
rails:
input:
flows:
- detect urgency
Printing the context
from actions import peek_context
from nemoguardrails import LLMRails, RailsConfig
rails = LLMRails(RailsConfig.from_path("."))
rails.register_action(peek_context)
rails.generate(messages=[{"role": "user", "content": "URGENT: the cluster is down!"}])['event', 'i', 'input_flows', 'last_bot_message', 'last_user_message', 'triggered_input_rail', 'user_message']
user_messageandlast_user_messagehold the message. An input rail almost always wants the first.last_bot_messageis what the bot said last turn.triggered_input_railandinput_flowsname the rail that is running and the whole list.
The video's urgency detector
The video's second action reads the same user_message and returns True for words such as outage, down or P0. Its flow says an acknowledgement and does not stop, so the turn carries on.
@action(is_system_action=True)
async def classify_urgency(context: Optional[dict] = None):
"""Returns True if the message signals a production emergency."""
msg = (context.get("user_message", "") if context else "").lower()
urgent_keywords = ["outage", "down", "crash", "critical",
"emergency", "not working", "urgent", "p0", "p1"]
return any(kw in msg for kw in urgent_keywords)define bot acknowledge urgency
"This sounds urgent! Let me help you as quickly as possible."
define flow detect urgency
$is_urgent = execute classify_urgency
if $is_urgent
bot acknowledge urgencyfrom actions import classify_urgency
from nemoguardrails import LLMRails, RailsConfig
rails = LLMRails(RailsConfig.from_path("."))
rails.register_action(classify_urgency)
def chat(message):
reply = rails.generate(messages=[{"role": "user", "content": message}])
print("User:", message)
print("Bot :", reply["content"])
chat("URGENT: Production Kubernetes cluster is completely down!")
print(rails.explain().colang_history)User: URGENT: Production Kubernetes cluster is completely down! Bot : This sounds urgent! Let me help you as quickly as possible. bot acknowledge urgency "This sounds urgent! Let me help you as quickly as possible."
The reply is the acknowledgement alone. The history shows why: the input rail said bot acknowledge urgency, and that became the turn's bot message. The flow did not stop, but a bot message already said in the input rail ends the turn without a model answer. The video's saved run shows the same single sentence.
Runtime parameters vs your own
| Parameter | Comes from |
|---|---|
context | The runtime: the conversation variables |
events, llm, config | The runtime, when you ask for them by name |
| Anything else | The Colang call: execute name(x=$value) |
Where each is used
Each lesson in this part replaces actions.py with its own version, and rails.co and config.yml change with it.
- Input rails read
user_message; output rails readbot_message, in $bot_message in an output rail. - Lookups take their own arguments from the flow.
Related
- Previous: @action and register_action
- Next: Custom input rail
- Reference: Action parameters
- Add
eventstopeek_context's signature and printlen(events). - Add
stopunderbot acknowledge urgencyand send the outage message again.
This is what real progress feels like.