Connecting an agent to the Business Central nervous system: Tasks AL API in practice

jarmestoBusiness Central4 hours ago30 Views

The HR Absence Agent can already say no. Now it needs to listen without being told to.

In the previous article we left the HR Absence Agent with a complete repertoire: it detects conflicts between colleagues in the same department, escalates to the manager when needed, and sends no notification without human review. All correct. But it has a fundamental problem: someone has to go to Agent Tasks, manually create a task, and type «review Juan’s request.» That is not automation. It is bureaucracy under a different name.

The real value leap in a Business Central agent appears when you connect it to the ERP’s nervous system: EventSubscribers. Having the agent react automatically when an email arrives at the configured mailbox, when a record is inserted in a table, or when a document is posted. No human intervention to launch the task. That is today’s topic.

What you need to understand first

The Tasks AL API in Business Central consists of two main pieces: the Agent Task Builder codeunit, which creates new tasks, and the Agent Task Message Builder codeunit, which composes messages with context. Both work with a fluent API where you chain calls until the final .Create().

The fundamental pattern is always the same: Detect → Compose → Create. You detect a business event with an EventSubscriber. You compose the message injecting relevant context with Agent Task Message Builder. And you create the task assigning it to the agent with Agent Task Builder. Three steps, always in that order.

al

// Base pattern: Detect → Compose → Create
AgentTask := AgentTaskBuilder
.Initialize(AgentUserSecurityId, 'Review Absence Request')
.SetExternalId('ABS-' + Format(Rec."Entry No."))
.AddTaskMessage('HR System', 'New absence request from ' +
Rec."Employee Name" + ' for ' + Format(Rec."From Date") +
' to ' + Format(Rec."To Date"))
.Create();

SetExternalId deserves special attention. It is the mechanism that allows correlating agent tasks with external business entities. If the absence request arrives by email, the ExternalId can be the email thread’s conversation ID. If it comes from a record, it can be the table’s Entry No. What matters is that it is unique and traceable.

Three integration patterns

The official Microsoft documentation describes three ways to create tasks programmatically, and all three are complementary.

From page actions. The simplest case: a «Send to Agent» button in a page action. The user sees a sales order, clicks the button, and the agent receives a task with the order’s context. Useful for scenarios where the user decides when to involve the agent.

From business events. This is where things get interesting. An EventSubscriber reacts to a system event — an invoice is posted, a vendor is inserted, an order is modified — and automatically creates a task for the agent with relevant context. No human intervention.

Simulating email triggers. For scenarios where the agent processes incoming emails, you can simulate the email structure in the task message. This is especially useful during prototyping: you format the message with email metadata (FROM, SUBJECT, body) and use the EmailThreadId as ExternalId to maintain conversation traceability.

In the HR Absence Agent, real email task creation (via the mailbox monitor) follows this pattern, which includes SetMessageExternalID for per-message traceability:

al

AgentTaskMsgBuilder
.Initialize(CopyStr(DisplaySender, 1, 250), MessageText)
.SetMessageExternalID(
CopyStr(EmailInbox."External Message Id", 1, 2048));
if HAAgentSetup."Analyze Attachments" then
AddEmailAttachmentsToMessage(EmailMessage, AgentTaskMsgBuilder);
AgentTaskBuilder
.Initialize(HAAgentSetup."User Security ID", TaskTitle)
.SetExternalId(
CopyStr(EmailInbox."Conversation Id", 1, 2048))
.AddTaskMessage(AgentTaskMsgBuilder)
.Create();

The email’s Conversation Id serves as the task’s ExternalId (grouping all messages in the same thread), while the External Message Id is associated with each individual message within the task. This two-layer identification enables both multi-turn conversations and deduplication.

Attachments: when the truth is in the PDF

Often the context the agent needs is not in the ERP. It is in an attached PDF, a scanned medical certificate, a purchase order that arrived by email. The Tasks AL API allows passing files directly into the agent’s context with AddAttachment() in the Agent Task Message Builder.

Multi-turn conversations

A task is not always resolved in a single step. The API allows adding messages to existing tasks and reactivating them.

Before adding a message, you need to know if the task already exists. The TaskExists method on Agent Task Builder checks whether a task with a given ExternalId exists for a specific agent:

al

IsExisting := AgentTaskBuilder.TaskExists(
HAAgentSetup."User Security ID",
EmailInbox."Conversation Id");
if IsExisting then
AddMessageToExistingTask(HAAgentSetup, EmailInbox)
else
CreateNewAgentTask(HAAgentSetup, EmailInbox);

To add a message to an existing task, the HR Agent uses SetAgentTask to bind the message to the task, and SetMessageExternalID for per-message deduplication:

al

// Find the task by its ExternalId (email Conversation Id)
AgentTaskRec.SetRange("External ID", EmailInbox."Conversation Id");
if not AgentTaskRec.FindFirst() then
exit;
// Deduplication: skip if this specific email was already added
AgentTaskMessage.SetRange("Task ID", AgentTaskRec.ID);
AgentTaskMessage.SetRange("External ID",
CopyStr(EmailInbox."External Message Id", 1, 2048));
if AgentTaskMessage.Count() >= 1 then
exit;
// Add the message to the existing task
AgentTaskMsgBuilder
.Initialize(CopyStr(DisplaySender, 1, 250), MessageText)
.SetMessageExternalID(
CopyStr(EmailInbox."External Message Id", 1, 2048))
.SetAgentTask(AgentTaskRec);
AgentTaskMsgBuilder.Create();

This pattern is key for email threads: each reply is added as a message to the existing task (identified by the Conversation Id as ExternalId), the agent runtime detects the new message, and the agent resumes work with all accumulated context.

Detecting agent sessions

There is an advanced pattern that changes how you think about interaction: detecting whether your AL code is running inside an agent session. The Agent Session codeunit exposes IsAgentSession(), which tells you if the current session belongs to an agent and which metadata provider is running.

The recommended pattern by Microsoft is to bind EventSubscribers only during the agent session, using BindSubscription during OnAfterInitialization. This is more efficient than having global subscribers that check relevance on every invocation.

Traceability: ExternalId vs. tracking table

The official documentation presents two strategies for correlating agent tasks with business entities. The ExternalId is sufficient for simple integrations with one-to-one relationships. For more complex scenarios — multiple related entities per task, additional metadata, many-to-many relationships — it is better to store the Task ID in your own table alongside your business entity records.

Scheduled agents: Job Queue + Tasks AL API

A pattern with great practical potential: combining the Tasks AL API with Business Central’s Job Queue to create agents with scheduled activation. Configure a Job Queue Entry that runs a codeunit daily, and the agent receives a task every morning to review pending items.

What to keep in mind

Each agent task runs in a separate session, with the agent as the user. Effective permissions are the intersection of the task-creating user’s permissions and the agent’s permissions. Tasks execute asynchronously and in parallel. Multiple tasks for the same agent can run simultaneously, each in its own transaction. If your agent works on the same records from multiple tasks, you need to design for concurrency.

From HR Absence Agent to the complete pattern

Coming back to the starting point: connecting the HR Absence Agent to the Tasks AL API means subscribing to the insertion event on the absence table, composing the message with the request context, and creating the task. Three lines of pattern, but the change is qualitative: the agent goes from reactive to proactive. From waiting for instructions to listening to the system.

And that fundamentally changes the value proposition. An agent that needs a human to say «work» is an assistant. An agent that detects, evaluates, and acts (always with human-in-the-loop for critical decisions) is a digital coworker.

In the next article we will explore how the Agent SDK evolves in BC 28.0 with the 2026 Release Wave 1 news, including MCP Server access enabled by default and the implications for custom agent architecture.

Are you experimenting with the Tasks AL API? I would love to know what activation patterns you are using. Comments and questions welcome.

References:

🟦 This article is part of the series on AI Development Toolkit in Business Central.

Original Post https://techspheredynamics.com/2026/03/24/connecting-an-agent-to-the-business-central-nervous-system-tasks-al-api-in-practice/

0 Votes: 0 Upvotes, 0 Downvotes (0 Points)

Leave a reply

Follow
Search
Popular Now
Loading

Signing-in 3 seconds...

Signing-up 3 seconds...

Discover more from 365 Community Online

Subscribe now to keep reading and get access to the full archive.

Continue reading