Agents and the multi-agent system
Newo.ai uses a multi-agent architecture in which specialized agents collaborate within a shared project to handle conversations, tasks, email, SMS, browser automation, and more. This article explains what an agent is, how agents are organized into a project hierarchy, and how they coordinate through events and shared attributes.
What is an agent?
An agent is the fundamental unit of intelligence on the Newo platform. Each agent is an abstraction that encapsulates a persona (its voice and tone), one or more flows (grouped sets of logic), and the skills within those flows (the individual steps that execute). Agents are defined by three core properties:
| Property | Description |
|---|---|
idn | A unique, machine-readable identifier for the agent (e.g., ConvoAgent, EmailWorker). The idn is immutable once created and is used in event routing, API calls, and YAML configuration. |
title | A human-readable display name. Often matches the idn, but can be customized. |
description | A plain-text summary of the agent's purpose and responsibilities. |
Each agent is linked to a persona that defines its voice, tone, and behavioral characteristics, and belongs to exactly one project.
Agent types in the NAF
The NAF (Newo Agent Framework) is the default multi-agent project that ships with every Newo account. It defines a team of specialized agents, each responsible for a distinct domain. The table below describes every agent type included in the NAF.
Agent idn | Role | Description |
|---|---|---|
ConvoAgent | Primary conversational agent | The main user-facing agent. It processes messages and responds across all conversational channels: phone, chat, Telegram, WhatsApp, and others. Contains the largest number of flows (message handling, booking, follow-up, scheduling, voice actions, and more). |
GeneralManagerAgent | Project manager and orchestrator | The keeper of task objects, task instructions, and business context. Handles project initialization, publishing, migrations, report generation, and tool setup. |
TaskManager | Task lifecycle manager | Manages the creation, assignment, tracking, and completion of tasks across the agent team. |
EmailWorker | Email specialist | Sends email messages on behalf of the agent team. Triggered by other agents via system events when email delivery is required. |
SmsWorker | SMS specialist | Sends SMS messages to users. Like the EmailWorker, it is triggered by inter-agent events rather than direct user interaction. |
MagicWorker | Browser automation worker | Simulates keyboard and mouse actions within a browser, behaving like a human when interacting with web applications that lack APIs. Commonly used for booking tables at restaurants, scheduling spa appointments, and similar tasks. |
MultiLocationAgent | Location routing controller | Controls the target location of a session. Used by businesses with multiple physical locations to route conversations and tasks to the correct branch. |
ScenarioWriter | Conversation scenario generator | Generates and writes conversation scenarios, providing structured scripts that other agents can follow during interactions. |
AgentCreator | Account initialization agent | Handles automated agent creation and the account initialization process, including callback and incoming-event processing. |
VibeAgent | AI-powered agent builder | Provides a conversational interface for building and configuring agents. Handles canvas operations (add, edit, delete, reorder items), attribute management, knowledge base updates, project publishing, and checkpoint/transaction history. Enables building agents through natural language instructions rather than direct configuration. |
Project hierarchy
Agents do not exist in isolation. They operate within a strict organizational hierarchy that governs scope, ownership, and resource sharing.
flowchart TD
Org[Organization] --> Proj[Project]
Proj --> Agents[Agents]
Proj --> Libs[Libraries]
Agents --> Flows[Flows]
Flows --> Skills[Skills]
Libs --> LibSkills[Library Skills]
Organization
The top-level entity. An organization represents a Newo account and contains one or more projects.
Project
A project is a versioned collection of agents, libraries, and shared attributes. The NAF is one example of a project. Each project is defined by a YAML file at its root:
project:
idn: naf
name: NAF (Newo AI Employee Framework)
version: 4.1.0
description: ""
is_auto_update_enabled: trueKey project properties include:
| Property | Description |
|---|---|
idn | Unique identifier for the project. |
version | Semantic version string. The platform uses this for auto-update management. |
is_auto_update_enabled | When true, the project automatically receives updates from the registry. |
Agent
An agent belongs to exactly one project. It contains flows and is linked to a persona. See What is an agent? above for details.
Flow
A flow is a collection of skills grouped around a specific workflow or capability. Each agent can have many flows. For example, the ConvoAgent includes flows such as CAMainFlow, CABookingManagementFlow, CAFollowUpFlow, CAScheduleFlow, and many others.
A flow is defined by a YAML file that lists its skills and event subscriptions:
title: CAMainFlow
idn: CAMainFlow
description: null
agent_id: null
skills:
- title: ""
idn: CommonConversationStartedSkill
prompt_script: flows/CAMainFlow/skills/CommonConversationStartedSkill.nsl
runner_type: nsl
model:
model_idn: gemini25_flash
provider_idn: google
parameters: []
# ... additional skills
events:
- idn: conversation_started
skill_selector: skill_idn
skill_idn: ConversationStartedSkill
state_idn: null
integration_idn: newo_chat
connector_idn: null
interrupt_mode: queue
# ... additional event subscriptionsSkill
A skill is the atomic logic unit. Each skill contains a prompt script written in either NSL (Newo Scripting Language, Jinja2-based) or Guidance (Handlebars-based, legacy). Skills are where LLM calls, action invocations, and data transformations happen.
Library
A library is a collection of reusable library skills that are shared across all agents within a project. Any flow skill can call a library skill using the syntax {{ LibraryName.SkillName() }}.
Agent coordination via events and shared attributes
In a multi-agent system, no single agent handles everything. Agents communicate with each other through two primary mechanisms: events and shared attributes.
Event-driven communication
Agents subscribe to events through their flow YAML configuration. When an event fires, the platform routes it to the subscribed skill within the appropriate agent. Events can originate from:
- Integrations -- External channels like
newo_chat,newo_voice,telegram, ortwilio_messenger - System events -- Internal platform events with
integration_idn: systemandconnector_idn: system - API/webhook events -- Events from external systems via
integration_idn: apiandconnector_idn: webhook
Each event subscription in a flow specifies:
- idn: conversation_started # The event identifier
skill_selector: skill_idn # How to select the skill (by idn or from state)
skill_idn: ConversationStartedSkill # The skill to execute
integration_idn: newo_chat # Which integration this event comes from
connector_idn: null # Optional connector filter
interrupt_mode: queue # How to handle concurrent executionThe interrupt_mode field controls what happens when a new event arrives while a skill is already running:
| Mode | Behavior |
|---|---|
queue | The new event waits until the current skill finishes, then executes. |
interrupt | The current skill is interrupted and the new event's skill starts immediately. |
cancel | The new event is discarded if a skill is already running. |
Cross-agent events with SendSystemEvent
SendSystemEventAgents trigger behavior in other agents by firing system events using the SendSystemEvent action. Skills use NSL syntax — double-brace {{ }} expressions that invoke actions and call functions. For example, when the ConvoAgent needs to send an SMS, it fires an event that the SmsWorker is subscribed to:
{{SendSystemEvent(eventIdn="sms_send_requested", connectorIdn="system", message_text=...)}}
The SmsWorker picks this up through its event subscription and executes the appropriate skill. This pattern keeps agents loosely coupled -- the ConvoAgent does not need to know how SMS delivery works; it simply emits an event.
Shared attributes
Agents within the same project share access to project attributes and customer attributes. These are key-value pairs (named slots that each store a single piece of data, like customer_name: "Jane") stored at the project or customer level that any agent can read or write.
- Project attributes -- Configuration and state shared across all sessions (e.g., chat links, feature flags, initialization settings). Accessed via
GetProjectAttributeandSetProjectAttribute. - Customer attributes -- Per-customer data that persists across conversations (e.g., name, preferences, booking history). Accessed via
GetCustomerAttributeandSetCustomerAttribute.
Project attributes are defined in the project's attributes.yaml:
attributes:
- idn: project_attributes_chat_link_demo
value: ""
title: "6-01. Chat - Demo Link (URL) [B]"
description: "Link to the Chat widget (demo mode)."
group: "6. Support"
is_hidden: false
possible_values: []
value_type: !enum "ValueType.STRING":::
⚠️ CAUTION
For developers writing NSL scripts: GetCustomerAttribute and GetProjectAttribute never return null or undefined. An unset attribute returns an empty string "" or a single space " " (a legacy behavior). Always use .strip() when checking attribute values in NSL scripts to avoid treating a placeholder space as a truthy value.
:::
How agents work together: a practical example
Consider a customer chatting through a web widget who asks to book a restaurant table:
- The platform receives the message through the
newo_chatintegration and fires aconversation_startedevent. - The
ConvoAgentpicks up the event in itsCAMainFlowand engages the customer in conversation, gathering booking details. - The
ConvoAgentdetermines that browser-based booking is required and fires a system event to theMagicWorker. - The
MagicWorkerreceives the event, opens the restaurant's booking website in a headless browser (a browser with no visible UI, controlled programmatically), and simulates the reservation process. - When the booking completes, the
MagicWorkerfires a result event back to theConvoAgent. - The
ConvoAgentconfirms the booking with the customer and fires events to theEmailWorkerandSmsWorkerto send confirmation messages. - Throughout this process, customer details are read from and written to customer attributes, ensuring all agents share a consistent view of the customer's data.
sequenceDiagram
participant User as Customer (web widget)
participant Conv as ConvoAgent
participant Magic as MagicWorker
participant Email as EmailWorker
participant SMS as SmsWorker
User->>Conv: Chat message (newo_chat → conversation_started)
Conv->>User: Gather booking details
Conv->>Magic: SendSystemEvent (browser booking required)
Magic->>Magic: Automate restaurant booking website
Magic->>Conv: Result event (booking complete)
Conv->>User: Booking confirmed
Conv->>Email: SendSystemEvent (send confirmation email)
Conv->>SMS: SendSystemEvent (send confirmation SMS)
Note over Conv,SMS: Customer attributes shared across all agents throughout
This flow demonstrates the core principle of the multi-agent system: each agent handles what it does best, and coordination happens through events and shared state rather than direct coupling.
Related topics
- See Naming conventions and identifiers for rules on
idnformatting and reserved identifiers - See Platform architecture overview for a higher-level view of the Newo platform
- See Event Identifier List for a complete reference of available event identifiers
- See Integration Identifier List for all supported integration identifiers
Updated about 4 hours ago
