Introduction

In previous lessons, you learned how to control timing and manage flows in Colang to make your chatbot more flexible and responsive. However, sometimes the built-in actions and flow logic in Colang aren’t enough. For advanced tasks—like performing complex calculations, calling external APIs, or using specialized Python libraries—you need to extend Colang with custom Python actions.

In this lesson, you’ll learn how to create, use, and manage custom Python actions in your Colang projects. This unlocks the full power of Python within your Colang flows, making your chatbots much more capable and flexible.

Custom Python Actions

Custom Python actions are functions you define in the actions.py file in the root of your project. These functions are decorated as actions and can be called directly from your Colang flows. This allows you to implement more complex functionality that cannot be achieved with Colang alone. All Python actions run in the context of the Colang interpreter, so they have access to the same runtime environment and resources as your Colang flows.

Defining Custom Python Actions

To make a Python function available to Colang, use the @action decorator from nemoguardrails.actions. This registers your function as an action that can be called from Colang flows.

Example:

from nemoguardrails.actions import action

@action(name="CustomAction")
async def func(value: int):
    # Perform a calculation or any logic you need
    return value * 2

Key Points:

  • Use the @action decorator to register your function.
  • The name parameter sets the action’s name (should end with Action by convention).
  • Define your function as async def.
  • The function can accept any parameters you need.
Calling Python Actions from Colang Flows

Once you’ve defined a Python action, you can call it from a Colang flow using the await keyword. This pauses the flow until the action completes and returns a result.

Example:

flow main
  $val = await CustomAction(value=5)
  bot say "The calculated value is: {$val}"

How it works:

  • await CustomAction(value=5) calls your Python action and stores the result in $val.
  • You can then use $val in subsequent steps, such as sending a message to the user.
Asynchronous Python Actions
Accessing Special Parameters in Python Actions

Python actions can access special parameters for more control and context:

  • events: recent conversation events
  • context: global variables (read or update)
  • config: configuration from config.yml
  • llm_task_manager: LLM task manager object
  • state: state machine state object

Add these as parameters to your function as needed.

Example:

from nemoguardrails.actions import action

@action(name="GetModelName")
async def custom_test(config: dict):
    return config.models[0].model

Here, the action gets the LLM model as defined in the config.yaml:

colang_version: "2.x"

models:
  - type: main
    engine: openai
    model: gpt-4o-mini

Example 2:

from nemoguardrails.actions import action

@action(name="GetLatestEventAction")
async def custom_test(events: dict):
    return events[-1]

This returns something like:

{'type': 'StartGetLatestEventAction', 'uid': '7d04e832-2c57-457b-92be-2df189eae369', 'event_created_at': 
'20xx-xx-xxThh:nn:ss.msssss+00:00', 'source_uid': 'NeMoGuardrails-Colang-2.x', 'action_uid': 'c2902f69-f17f-4d24-a03d-09c96e581c1d', 'number': 
5}
Summary
  • Use the @action decorator to define Python functions as Colang actions.
  • Call actions from Colang flows with await, passing parameters as needed.
  • For long-running tasks, set execute_async=True and use start/match or await in your flows.
  • Access special parameters like context and events for advanced control.

In the next practice, you’ll write your own Python actions, call them from Colang, and see how they work together to build more advanced, agentic AI chatbots.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal