Skip to Content
Agentlang is open source now!
ConceptsDeclarative Workflows

Declarative Workflows

In Agentlang, custom business logic comes alive through workflows. Think of a workflow as a blueprint for how your application interacts with data and orchestrates actions. Each workflow is made up of patterns — declarative statements that express operations on your domain, such as creating or updating entity instances, evaluating functions, or triggering events. The beauty of workflows in Agentlang is that they focus on what should happen, rather than how it happens.

Workflows are written in a data-oriented syntax, making them both readable and intuitive. In the Design Studio, each workflow pattern appears as a distinct block, visually guiding you through the steps of your business logic.

Most workflow patterns produce a result — this could be a single entity instance, a list of instances, or some other value. Often, subsequent patterns in the workflow will depend on the output of earlier patterns. To make this connection clear, you can assign a result to an alias using the @as keyword. Future patterns can then reference the alias instead of repeating the logic.

For example, suppose we want to create a new person and immediately send them a welcome email:

workflow createPerson { { acme.core/Person { email "jj@fractl.io", name "J Joe" } } @as p; { acme.util/sendEmail { to p.email body p.name + ", welcome to Acme!" } } }

Here, the first pattern creates a new Person and assigns it the alias p. The next pattern can directly reference p to send the welcome email — no need to query or look it up again.


Destructuring Results

Sometimes, a workflow pattern returns multiple instances — for example, a query that fetches all employees with a salary above a threshold. Often, you only care about a subset: the first result, the last one, or a few specific entries. Agentlang makes this easy with destructuring.

Destructuring allows you to pick and name the relevant elements from a result set:

// Query all employees with salary > 5000 { acme.core/Employee { salary?> 5000 } } @as employees; // Bind only the first result to `e1` { acme.core/Employee { salary?> 5000 } } @as [e1]; // Bind the first and third employees, ignore the second, and bind the rest to `es` { acme.core/Employee { salary?> 5000 } } @as [e1, _, e2, __, es];

With destructuring, your workflows become precise, concise, and expressive. You can focus on the data that matters and let Agentlang handle the rest.

Last updated on