Flows

A flow is the structured execution process that defines how an agent responds to events, routes work to skills, and manages conversational state. Flows are the primary organizational unit inside every Newo agent, connecting incoming events to the skills that handle them.

What is a flow?

Every agent in the Newo Agent Framework (NAF) contains one or more flows. A flow groups together a set of skills, event bindings, and state fields into a cohesive unit of behavior. When an event arrives at an agent, the agent's flows determine which skill should execute and how the result feeds back into the conversation.

Flows are defined in YAML files and live inside the agent's directory structure:

agents/
  ConvoAgent/
    flows/
      CAMainFlow/
        CAMainFlow.yaml
        skills/
          ConversationStartedSkill.nslg
          UserNewoChatReplySkill.nslg
          ...
      CAMessageFlow/
        CAMessageFlow.yaml
        skills/
          SendMessage.nsl
          ...

Each flow directory contains the flow definition YAML and a skills/ subdirectory holding the prompt scripts (.nsl or .nslg files) that implement each skill.

Flow components

A flow definition is composed of four main sections:

Metadata

Top-level fields that identify the flow:

FieldDescription
titleHuman-readable name of the flow.
idnUnique machine-readable identifier (e.g., CAMainFlow). Must be unique within the agent.
descriptionOptional plain-text description of the flow's purpose.
agent_idThe ID of the agent that owns this flow. Populated at runtime; typically null in source YAML.
default_runner_typeDefault execution engine for skills in this flow (guidance or nsl).
default_provider_idnDefault LLM provider (e.g., google).
default_model_idnDefault model (e.g., gemini25_flash).
publication_typePublication visibility. Usually null for internal flows.

Skills

An ordered list of skill definitions. Each skill references a prompt script and specifies how it should be executed:

FieldDescription
idnUnique identifier for the skill within the flow. Used to bind events to this skill.
titleOptional human-readable name.
prompt_scriptRelative path to the prompt script file (e.g., flows/CAMainFlow/skills/ConversationStartedSkill.nslg).
runner_typeExecution engine: nsl (Newo Scripting Language) or guidance (template-based prompting).
modelAn object with model_idn and provider_idn that specifies which LLM to use for this skill.
parametersA list of named parameters with default_value entries. Parameters allow skills to receive input from other skills or from the event payload.

Events

The events section defines the routing rules that connect incoming events to skills. Each event binding is a rule that says: "When event X arrives from integration Y via connector Z, run skill S."

FieldDescription
idnThe event identifier to listen for (e.g., user_message, conversation_started, end_session).
skill_selectorThe strategy used to pick which skill runs. Either skill_idn (static) or skill_idn_from_state (dynamic).
skill_idnThe skill to invoke when skill_selector is skill_idn. Set to null when using skill_idn_from_state.
state_idnThe state field whose value contains the target skill identifier. Used only when skill_selector is skill_idn_from_state.
integration_idnFilters the event to a specific integration (e.g., newo_chat, vapi, telegram, system). When null, the binding matches any integration.
connector_idnFurther narrows matching to a specific connector within the integration.
interrupt_modeHow this event interacts with currently running skills: queue, interrupt, or cancel.

State fields

State fields are named variables scoped to either the agent level (shared across all users) or the user level (private to a single conversation participant). Skills can read and write these fields during execution, enabling flows to maintain context across multiple event cycles.

FieldDescription
idnUnique state field name within the flow.
default_valueInitial value assigned when the flow is first loaded.
scopeEither agent (shared) or user (per-user).

YAML structure: annotated example

Below is a simplified flow YAML based on CARagFlow, annotated to highlight each section:

# --- Metadata ---
title: CARagFlow                          # Human-readable name
idn: CARagFlow                            # Machine identifier
description: null
agent_id: null
default_runner_type: guidance              # Default execution engine
default_provider_idn: google              # Default LLM provider
default_model_idn: gemini25_flash         # Default model
publication_type: null

# --- Skills ---
skills:
  - title: ""
    idn: PrepareRagContext                 # Unique skill identifier
    prompt_script: flows/CARagFlow/skills/PrepareRagContext.nsl
    runner_type: nsl                       # Overrides the default runner_type
    model:
      model_idn: gemini25_flash
      provider_idn: google
    parameters: []                         # No input parameters needed

  - title: ""
    idn: get_memory
    prompt_script: flows/CARagFlow/skills/get_memory.nsl
    runner_type: nsl
    model:
      model_idn: gemini25_flash
      provider_idn: google
    parameters:                            # Parameters with defaults
      - name: user_id
        default_value: ""
      - name: count
        default_value: "15"
      - name: include_system
        default_value: "False"
      - name: include_thoughts
        default_value: "False"
      - name: actors
        default_value: ""
      - name: from_date
        default_value: ""
      - name: to_date
        default_value: ""

  - title: ""
    idn: structured_generation
    prompt_script: flows/CARagFlow/skills/structured_generation.nsl
    runner_type: nsl
    model:
      model_idn: gemini25_flash
      provider_idn: google
    parameters:
      - name: prompt
        default_value: ""
      - name: schema
        default_value: ""

# --- Events ---
events:
  - idn: prepare_rag_context_command       # Event identifier to listen for
    skill_selector: skill_idn              # Static routing: always call the named skill
    skill_idn: PrepareRagContext            # Target skill
    state_idn: null                        # Not using state-based routing
    integration_idn: null                  # Matches any integration
    connector_idn: null                    # Matches any connector
    interrupt_mode: queue                  # Queued behind any running skill

# --- State fields ---
state_fields: []                           # This flow has no persistent state

The skill_selector mechanism

The skill_selector field on each event binding controls how the platform resolves which skill to run. There are two strategies:

Static routing with skill_idn

The simplest and most common pattern. The skill_idn field directly names the skill to call:

- idn: end_session
  skill_selector: skill_idn
  skill_idn: EndSessionSkill        # Always run this specific skill
  state_idn: null
  integration_idn: system
  connector_idn: system
  interrupt_mode: queue

When the end_session event arrives from the system integration, the platform always invokes EndSessionSkill. This is a one-to-one binding.

Dynamic routing with skill_idn_from_state

For cases where the skill to invoke must be determined at runtime, the platform reads the skill identifier from a state field. The state_idn field names the state variable that holds the skill idn:

- idn: user_message
  skill_selector: skill_idn_from_state
  skill_idn: null                         # Not used; resolved from state
  state_idn: phone_reply_skill            # Read skill name from this state field
  integration_idn: newo_voice
  connector_idn: newo_voice_connector
  interrupt_mode: interrupt

The corresponding state field provides a default value that the platform uses initially:

state_fields:
  - idn: phone_reply_skill
    default_value: UserPhoneReplySkill    # Default skill if state is not modified
    scope: user

This pattern allows other skills to change which skill handles an event by writing a new value to the state field. For example, CAMainFlow uses skill_idn_from_state for the conversation_started event on the newo_voice integration. The state field conversation_started_newo_voice_skill defaults to v2v_conversation_started, but another skill can write a different value to switch behavior without modifying the flow YAML.

::: 🗒️ NOTE The skill_idn_from_state pattern is used exclusively in CAMainFlow today. It appears in two event bindings: the conversation_started event for the newo_voice integration and the user_message event for the newo_voice connector. :::

Interrupt modes

Each event binding declares an interrupt_mode that controls what happens when a new event arrives while a skill from the same flow is already executing:

ModeBehavior
queueThe new event waits in a queue until the currently executing skill completes. This is the default and most common mode.
interruptThe currently executing skill is interrupted, and the new skill begins immediately. Used for time-sensitive events like user_message on voice and SMS channels where responsiveness is critical.
cancelThe currently executing skill is cancelled entirely, and the new skill replaces it. Used sparingly, for example in CADataInjectionFlow for the prepare_injecting_data event.

Event-to-skill routing within flows

When an event arrives at an agent, the platform evaluates all event bindings across all of the agent's flows to find a match. The matching process checks three criteria:

  1. Event idn -- Does the event identifier match the binding's idn?
  2. Integration -- Does the source integration match integration_idn? (A null value matches any integration.)
  3. Connector -- Does the source connector match connector_idn? (A null value matches any connector.)

The same event identifier can appear in multiple bindings across different flows, differentiated by integration_idn and connector_idn. For example, CAMainFlow contains seven separate user_message bindings, each targeting a different integration/connector pair:

IntegrationConnectorSkill
twilio_messengersms_connectorUserSMSReplySkill
newo_chatnewo_chatUserNewoChatReplySkill
sandboxconvo_agent_sandboxUserSandboxReplySkill
vapivapi_callerUserPhoneReplySkill
newo_voicenewo_voice_connector(resolved from state)
telegramtelegram_connectorUserTelegramReplySkill
apiwebhookUserAPIReplySkill

This design allows a single agent to handle the same logical event differently depending on which channel it originated from.

Flow lifecycle and execution

Flows follow a predictable lifecycle within the platform:

  1. Loading -- When an agent starts (or a project is published), all flows defined in the agent's YAML directory are loaded. Skills are registered, event bindings are indexed, and state fields are initialized with their default values.

  2. Event reception -- The platform receives an event (from a user message, a timer, an integration callback, or another agent). It evaluates the event against all registered bindings.

  3. Skill resolution -- The matching binding's skill_selector determines the target skill. For skill_idn, the named skill is selected directly. For skill_idn_from_state, the platform reads the state field to obtain the skill identifier.

  4. Skill execution -- The selected skill's prompt script is executed using its configured runner_type and model. Parameters are populated from the event payload, other skills' outputs, or default values.

  5. State mutation -- During execution, the skill may read or write state fields. These mutations persist (at the user or agent scope) and affect future event handling.

  6. Result propagation -- The skill's output may trigger additional events (such as sending a message, calling another flow, or emitting a result_success event), continuing the flow lifecycle.

ConvoAgent flows

The ConvoAgent is the primary user-facing agent and contains 30 flows covering message handling, voice actions, scheduling, analytics, and more. These flows are built into the platform and managed by Newo — partners configure agent behavior through the Builder UI and NSL skill scripts rather than creating or modifying these flows directly.

Flow idnPurpose
CAMainFlowCore conversation handler. Routes user_message, conversation_started, and conversation_ended events across all channels (chat, voice, SMS, Telegram, API, sandbox). Contains the largest number of skills and event bindings of any flow, including prompt compilation, RAG context preparation, and voice-to-voice (v2v) logic.
CAMessageFlowMessage delivery. Handles the convoagent_send_notification_message event to compose and send messages, including text generation, user email/phone retrieval, and timezone-aware formatting.
CAObserverFlowMid-conversation analysis. Triggered by broadcast_analyze_conversation to evaluate conversation quality, extract user information, detect working-hours status, and define user phone numbers during a live session.
CANewoToolCallerTool invocation engine. Resolves which Newo tools to call based on agent output, handles webhooks, events, persona attribute updates, and prompt section modifications. Triggered by broadcast_analyze_conversation and result_success from the HTTP connector.
CAThinkFlowPre-response reasoning. Performs product/service availability checks and area-served validations before the agent responds. Triggered by check_product_or_service_availability and check_zip_code_served_tool events.
CARagFlowRetrieval-augmented generation. Prepares RAG context by fetching memory, generating structured queries, and assembling context documents for the main prompt. Triggered by prepare_rag_context_command.
CADataInjectionFlowExternal data integration. Fetches external data on a timer, builds daily schedules, calculates working hours, and injects custom prompt sections. Handles timer, new_data_to_inject, set_prompt_custom_section, and remove_prompt_custom_section events.
CABookingManagementFlowBooking lifecycle management. Cancels bookings, sends management URLs, and processes cancellation results from both user-initiated and system-initiated requests.
CAScheduleFlowAppointment and meeting scheduling. Creates bookings and Google Calendar meetings, processes booking results and errors, and confirms schedule details with users.
CACalculatorFlowNumeric computation. Performs calculations requested during conversations, such as pricing estimates or availability math.
CACheckingAvailabilityFlowAvailability checking. Queries availability systems to determine open time slots for scheduling.
CABroadcastConversationFlowConversation broadcasting. Retrieves full conversation history and broadcasts analysis results to other flows and agents.
CAAssessmentFlowConversation quality assessment. Collects quality metrics, checks user contact detail completeness, and evaluates conversation outcomes against defined criteria.
CAUserManagementFlowUser record management. Handles user creation, updates, and contact information management during conversations.
CAExecuteExternalTasksFlowExternal task execution. Dispatches tasks to external systems (such as browser automation via the MagicWorker) and processes their results.
CAActionCallTransferFlowVoice call transfer action. Executes the call transfer process when the agent decides to connect the user to a human operator or another phone number.
CAActionCallHangUpFlowVoice call hang-up action. Terminates the active phone call when the conversation is complete or the agent determines the call should end.
CAActionCallDefineVoiceMailFlowVoicemail action. Configures and activates voicemail when the agent cannot continue the live conversation.
CAActionCallSendDialpadDigitsFlowDTMF digit sending. Sends dialpad digits during a call, used for navigating IVR menus or entering extensions after a call transfer.
CAActionSendEmailInformationFlowEmail information action. Sends email-based information to the user during or after a conversation, such as booking confirmations or follow-up details.
CAActionSendSMSInformationFlowSMS information action. Sends SMS-based information to the user, triggered by conversation events that require text message delivery.
CAEndSessionFlowSession teardown and analytics. Runs after a conversation ends to summarize the transcript, classify the conversation, extract common values, calculate potential revenue, identify disasters, collect metrics, and send HITL (human-in-the-loop) events. Contains the most skills of any single flow (35+).
CAFollowUpFlowFollow-up management. Enables and disables follow-up timers, activates waiting mode, and sends follow-up messages when users become unresponsive.
CAThoughtsFlowInternal reasoning trace. Captures and processes the agent's internal thought process, used for debugging, analytics, and quality evaluation.
CAReportFlowReport generation. Prepares and formats conversation reports for business stakeholders.
CASearchBookingFlowBooking search. Queries existing bookings to help users check, modify, or reference their scheduled appointments.
CATimezoneFlowTimezone resolution. Determines and sets the correct timezone for a user session, ensuring time-sensitive operations (scheduling, working hours) use the right local time.
CAExternalReplyExternal reply processing. Handles reply messages that originate from external systems rather than from direct user input.
CAGen2SendAgentMessageFlowGen2 agent message sending. Sends agent-generated messages through the Gen2 voice pipeline.
CAGen2SendUserMessageFlowGen2 user message injection. Injects user messages into the Gen2 voice pipeline for processing.

GeneralManagerAgent flows

The GeneralManagerAgent orchestrates project-level operations: initialization, publishing, tool configuration, report generation, and canvas-based instruction building. Like ConvoAgent flows, these are platform-built flows managed internally by Newo.

Flow idnPurpose
GMmainFlowProject lifecycle management. Handles project_init, project_publish_finish, sa_init_started, sa_init_finished, and run_tests events. Manages migrations, phone number attachment, RAG web search responses, and project import/export. Contains the largest number of skills in any GM flow, including versioned migration scripts.
GMNewoToolSetupFlowTool configuration. Processes generalmanageragent_update_newo_tools events to validate and update the set of Newo tools available to the ConvoAgent.
GMPrepareITMFlowIntent-type map (ITM) preparation. Builds industry-specific intent-type maps that the ConvoAgent uses for intent classification. Generates working-hours and non-working-hours variants for each industry vertical (beauty, catering, cleaning, dental, home service, hospitality, restaurant, sales).
GMPrepareReportsFlowReport content generation. Prepares structured report content using industry-specific templates. Handles gm_add_additional_report_criteria and gm_itm_built events. Includes customer attribute compilation and JSON-based report formatting.
GMcanvasBuilderFlowCanvas and instruction building. Manages the visual canvas editor's backend operations: adding, saving, deleting, and reordering canvas items and library items. Compiles canvas content into agent instructions via the gm_build_instructions and gm_prepare_instructions events.

How flows relate to other concepts

  • Agents -- Every agent contains one or more flows. The agent is the container; flows are the behavioral units inside it. See Agents and the multi-agent system for details on agent types and the NAF hierarchy.
  • Skills -- Skills are the executable units within a flow. Each skill has a prompt script and configuration. Flows organize skills and connect them to events.
  • Events -- Events are the triggers that activate flows. They originate from user actions, integrations, timers, or other agents. The flow's event bindings determine which skill handles each event.
  • Integrations and connectors -- Event bindings filter by integration_idn and connector_idn to route the same event type to different skills depending on the channel. See Integrations and connectors for details on available integrations.
  • Attributes -- State fields within flows are closely related to the broader attributes system. Agent-scoped state persists across all users, while user-scoped state is private to individual sessions. See Attributes system for the full attribute taxonomy.