Documentation
Built by Maven

The BPMN AI Agent

Dynamixs.AI provides a powerful AI Agent that integrates seamlessly into the BPMN processing life cycle. The agent runs in an autonomous loop — calling the LLM, evaluating responses, executing tools if requested — and continues until it either produces a plain-text answer or completes a workflow action on behalf of the user.

See also How to Model BPMN AI Agents.


Autonomous Agents

The Imixs-AI adapter classes — OpenAIAPIAdapter, ImixsAIAssistantAdapter and ConditionalAIAdapter — enable powerful LLM-driven automation into BPMN workflow processes. This kind of integration is a model-driven deterministic approach for classifying documents, drafting content, extracting data, or routing decisions.

BPMN AI Agents extend the concept of LLM integration into BPMN in a more autonomous way. Instead of a workflow driving the LLM, the user drives the agent — in natural language — and the agent decides what to do next inside the system. This covers the flexible, conversational entry point that brings users into the right workflow in the first place. Concretely, the BPMN AI Agent can:

  • Understand what the user wants — across languages and phrasings
  • Select the right workflow process from those available to the current user
  • Collect all required form field values from the conversation
  • Create a new workflow instance, fill in the data, and submit it — in one turn
  • Ask the user for any missing required fields and save a draft in the meantime
  • Hand the user directly over to the completed workitem

Both approaches complement each other and can be combined freely within the same BPMN model: the agent handles the natural-language entry point, and the existing LLM adapters take over once the process is running.


Architecture Overview: The AI-Task Micro-Model

The agent is not a standalone component — it is itself embedded in a small BPMN model, the AI-Task Micro-Model. This is the key architectural decision that makes the agent scalable, transactional, and production-ready.

When a user wants to interact with the agent, they start a dedicated workflow process — the AI-Task — just like any other workflow in the system.

The micro-model has the following tasks:

Task Name Description
100 Ask User enters a natural-language prompt and optionally attaches files
200 Thinking Agent is running asynchronously; the task must be associated with a System Prompt instructing the agent
300 Completed Agent completed; user is redirected to the started workflow or sees the agent response
800 Error Agent loop stopped because of an internal error

This approach has several important advantages over a session-scoped chat widget:

  • Every agent run is a persisted workflow instance — nothing is lost on server restart or session timeout
  • Multiple users can run agents in parallel without any shared state
  • The standard Imixs security model applies — the agent only ever acts within the permissions of the current user
  • Retry and error handling are built in via standard BPMN error events

Asynchronous Processing

The central challenge of integrating an AI agent into a workflow processing cycle is latency. A normal workflow event is processed and persisted within milliseconds. An agent loop calling an external LLM may take seconds to minutes.

The solution is the Imixs EventLog Service, which implements the Change Data Capture (CDC) pattern. Instead of running the agent synchronously inside the transaction, the Submit event does two things:

  1. Persists the workitem in Task 200 (“Thinking”) — fast and transactional
  2. Creates an EventLog entry with the topic ai.agent.process — also within the same transaction

Only after the transaction commits successfully does the EventLog entry become visible to the AIAgentOperator. This guarantees that the agent never starts before the workitem is safely stored in the database.

User clicks Submit
        │
        ▼
WorkflowEngine.processWorkItem()        ← Transaction A, synchronous, milliseconds
  → BPMNAgentProcessingHandler
      → builds skill snapshot (with user ACL)
      → writes agent.skills + agent.status = "PENDING" into workitem
  → EventLogPlugin
      → creates EventLog entry "ai.agent.process"  ← CDC: only visible after commit
  → Workitem persisted in Task 200
        │
        ▼
Response to browser                     ← user sees Task 200 with progress indicator
        │
        ▼  (after commit, asynchronous)
AIAgentScheduler (EJB Timer, every second)
  → releases deadlocks
  → delegates to AIAgentOperator
        │
        ▼
AIAgentOperator (@Stateless, REQUIRES_NEW)
  → finds EventLog entry "ai.agent.process"
  → acquires optimistic lock
  → reads agent config from EventLog data field
  → reads skill snapshot + user prompt from workitem
  → fires ImixsAIToolRegistrationEvent → collects tool definitions from all handlers
  → runs the Agent Loop
        │
        ├── agent.status = "RUNNING"
        ├── agent.progress = "Calling LLM (iteration 1)..."
        │
        ├── Agent Loop completes...
        │
        └── workflowService.processWorkItem(successEvent or errorEvent)

The AIAgentOperator uses the optimistic locking built into the EventLog Service to prevent concurrent processing. Multiple server instances can run in parallel without risk of handling the same workitem twice.


Agent Configuration via the EventLog Plugin

The EventLog entry is created by the standard EventLogPlugin, configured directly in the BPMN model. The <document> element of the plugin becomes the configuration payload for the AIAgentOperator. The BPMNAgentProcessingHandler validates this configuration during the Submit transaction and rejects invalid models early — before the EventLog entry is even created.

<eventlog name="ai.agent.process">
    <ref><itemvalue>$uniqueid</itemvalue></ref>
    <document>
        <agent.context.item>bpmn.agent.context</agent.context.item>
        <agent.user.item>bpmn.agent.user.input</agent.user.item>
        <agent.endpoint>my-llm</agent.endpoint>
        <agent.timeout>120000</agent.timeout>
        <agent.max-iterations>10</agent.max-iterations>
        <agent.event.success>200</agent.event.success>
        <agent.event.error>280</agent.event.error>
    </document>
</eventlog>
Parameter Description
agent.context.item Item name in the workitem that holds the agent context. This indirection allows different AI-Tasks to use different context data without code changes.
agent.user.item Item name in the workitem that holds the user's natural-language prompt. This indirection allows different AI-Task forms to use different input fields without code changes.
agent.endpoint Logical LLM endpoint ID as registered in imixs-llm.xml — never a URL
agent.timeout Maximum wall-clock time in milliseconds before the agent is aborted
agent.max-iterations Maximum number of LLM calls in one agent run to prevent runaway loops
agent.event.success BPMN event ID to trigger when the agent completes successfully
agent.event.error BPMN event ID to trigger when the agent fails or times out

The BPMNAgentProcessingHandler

The BPMNAgentProcessingHandler is a CDI observer (@ApplicationScoped) that reacts on the BEFORE_PROCESS event of the workflow engine.

It detects AI-Agent tasks by reading the BPMN event definition from the model and checking whether the workflow result contains an <eventlog name="ai.agent.process"> configuration — exactly the same signal the EventLogPlugin reacts on. No additional flag or item is required.

When an AI-Agent task is detected the handler:

  1. Validates the agent configuration (endpoint and user.input must be present)
  2. Builds the skill snapshot via BPMNSkillController — within the active user session context, so ACL filtering applies correctly
  3. Writes agent.skills and agent.status = "PENDING" into the workitem

The skill snapshot is a point-in-time copy of what the current user is allowed to start. It is stored directly in the workitem and read later by the AIAgentOperator — which runs without any user session context.


How the Agent Loop Works

Once the AIAgentOperator picks up the EventLog entry, it runs the agent loop:

EventLog entry consumed
        │
        ▼
┌───────────────────────────────────────────────────┐
│  Load workitem + agent config                     │
│  Restore conversation context from workitem       │
│  Fire ImixsAIToolRegistrationEvent                │
│    → each handler registers its tool definition  │
│  Add user prompt to context                       │
└───────────────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────┐
│  Call LLM                       │
└─────────────────────────────────┘
        │
        ├── Tool call? → ImixsAIToolCallEvent fired
        │     → create_workitem  : stores new workitem in AIAgentCache
        │     → update_workitem  : writes field values into cached workitem
        │     → submit_workitem  : processes workitem via WorkflowService
        │     → on error: event.setError() → PluginException → errorEvent
        │     → on success: result written into context → back to "Call LLM"
        │
        └── Text response? ──► write result to workitem
                                └── trigger successEvent

Each iteration either executes a tool and feeds the result back into the next LLM call, or ends the loop with a result written to the workitem. The successEvent or errorEvent then drives the workitem forward through the BPMN model via the standard workflow engine.


Skills: The Agent's Knowledge of What Is Possible

The central concept of the Dynamixs.AI BPMNAgent are Skills. A skill describes a workflow action that the agent can invoke on behalf of the user — for example starting a new workflow process and filling in its form data.

Skills are not hardcoded. They are derived entirely from the BPMN models deployed in the system and the process configuration. This means the agent's capabilities grow automatically as new workflows are deployed — without any changes to the agent itself.

The Five Skill Levels

Skills are organised in a five-level hierarchy that mirrors the structure of Imixs-Office-Workflow:

ProcessSkill
    └── ModelSkill
            └── WorkflowGroupSkill
                    └── TaskSkill
                            ├── EventSkill
                            └── ItemSkill (Form Fields)

ProcessSkill — the top level, corresponding to the Process Layer. The process layer is an organisational unit that groups related workflows and defines which users have access. The ProcessSkill serves as the access control boundary — the agent only includes skills that the current user is authorised to see.

ModelSkill — corresponds to a deployed BPMN model file. The ModelSkill carries the model version and its documentation, which gives the agent the domain context for all workflows within that model.

WorkflowGroupSkill — corresponds to a BPMN Pool (Workflow Group). The WorkflowGroupSkill carries the pool-level documentation, which describes the business purpose of that specific process.

TaskSkill — corresponds to the initial BPMN Task of a workflow group. The TaskSkill carries the task name and description, which is the most specific description of what the process is about.

EventSkill — corresponds to a BPMN Event on the initial task. A task can have multiple events, each representing a different way to start the process. The EventSkill carries the event name and documentation, which gives the LLM the semantic context to select the correct event — for example distinguishing between saving a draft and submitting for approval.

ItemSkill (Form Fields) — derived from the optional form definition attached to the initial task. Each ItemSkill carries the field name, type, label and whether the field is required. The agent uses this to know which data it needs to collect from the user before submitting the workflow.

How the Skill Hierarchy Becomes the System Prompt

Before the first LLM call, the BPMNSkillController traverses the skill hierarchy and renders it as a structured Markdown document — the skill headers. This document is injected into the agent's system prompt:

# Available Workflow Processes:

## Human Resources

### vacation-request-en-1.0

This model covers all HR-related processes for employees and managers.

#### New Vacation Request

A new vacation request has been submitted by an employee.
The request needs to be reviewed and approved by the manager.
(model: vacation-request-en-1.0, taskid: 1000, process.ref: 6d0f...)

- **Submit** (eventid: 20)
  Submit for approval. Use this event only when ALL required fields are filled.
  The request will be forwarded to the manager for review.

- **[init]** (eventid: 10)
  Save as draft. Use this event when required fields are still missing.
  The process is saved but not yet submitted for approval.

**Form Fields:**

- `vacation.date` (html5date, required): From
- `vacation.due` (html5date, required): To
- `employee.department` (text, required): Department
- `vacation.description` (textarea, required): Description

The LLM reads this document and matches the user's natural-language input against it — across languages, phrasings and levels of abstraction. A user typing “Ich brauche Urlaub” will reliably match “A new vacation request has been submitted by an employee” because a modern LLM understands the semantic equivalence between the two. It also reads the form fields and extracts matching values directly from the conversation — without asking the user for data they have already provided.

Skill Quality and Filtering

The agent only includes a workflow in the skill headers if at least one of the three description levels — model, pool, or task — contains meaningful content. Workflows without any description are silently skipped and logged as a warning. This keeps the system prompt compact and prevents the agent from presenting options it cannot explain.

This filtering also serves as a continuous quality signal: every warning in the log is a workflow that needs better documentation before the agent can use it reliably.

How to write effective BPMN descriptions that give the agent a reliable semantic foundation is covered in Modelling BPMN AI Agents.


Tool Calling: The Three-Phase Workflow

The agent registers three tools with the LLM. Together they implement a clean create → fill → submit lifecycle that avoids premature database writes and gives the agent full control over when a workflow instance is actually persisted.

create_workitem

Creates a new workflow instance in memory only — no database write occurs at this stage. Returns a $uniqueid that the agent uses in all subsequent calls.

Argument Description
$modelversion The BPMN model version to use
$taskid The initial task ID within that model
process.ref The unique ID of the target process entity

update_workitem

Writes field values into the cached workitem. Can be called multiple times. No database write occurs.

Argument Description
$uniqueid The ID returned by create_workitem
data Key-value pairs of field names and their values

submit_workitem

The single database write in the entire flow. Loads the workitem from the in-memory cache, sets the workflow event, and calls workflowService.processWorkItem(). The workitem is removed from the cache after successful processing.

Argument Description
$uniqueid The ID returned by create_workitem
$eventid The workflow event ID to trigger (draft or submit event)

The choice of $eventid is driven by the event descriptions in the skill headers. If required fields are still missing, the agent uses the event described as “draft” or “save” — which persists the workitem in an intermediate state and allows the conversation to continue. Only when all required fields are filled does the agent use the event described as “submit” or “approval”.

The AIAgentCache

The in-memory workitem store is provided by the AIAgentCache — an @ApplicationScoped singleton EJB. Workitems live in the cache from create_workitem until submit_workitem removes them after successful processing. A configurable TTL (default 30 minutes) evicts abandoned entries automatically, preventing memory leaks from aborted agent loops.

Tool Registration

Tool definitions are not hardcoded in the AIAgentOperator. Before the first LLM call, the operator fires an ImixsAIToolRegistrationEvent. Each tool handler observes this event and registers its own function definition. This makes the tool set fully extensible — new tools are added by deploying a new handler class, without touching the agent loop itself.


The System Prompt

The system prompt for an AI-Agent task is defined directly in the BPMN model as a prompt definition XML attached to the Thinking task. The <BPMNSKILLS/> placeholder is replaced at runtime with the rendered skill headers for the current user.

<?xml version="1.0" encoding="UTF-8"?>
<PromptDefinition>
    <prompt_options>{"n_predict": 4096, "temperature": 0}</prompt_options>
    <prompt role="system"><![CDATA[
You are a workflow assistant.

Follow these rules strictly:

1. When a user wants to start a process, call create_workitem with the matching
   modelversion, taskid and process.ref from the list below.

2. Immediately after create_workitem, call update_workitem with the $uniqueid
   returned by create_workitem and all field values you already know from the
   conversation.

3. If required form fields are still missing after update_workitem, ask the user
   for exactly those missing values. Then call update_workitem again with the
   new values.

4. After update_workitem, ALWAYS call submit_workitem immediately — even if
   required fields are still missing. Choose the eventid based on the event
   descriptions:
   - Required fields still missing → use the event described as "draft" or "save"
   - ALL required fields filled → use the event described as "submit" or "approval"

5. Only AFTER submit_workitem, ask the user for any still-missing required fields.

6. Do NOT explain what you are doing. Just call the tools directly.

<BPMNSKILLS/>
]]>
    </prompt>
</PromptDefinition>

The rules are intentionally generic — no process-specific logic is hardcoded. The agent derives everything it needs from the skill headers injected via <BPMNSKILLS/>.


Progress Feedback in the UI

While the agent runs asynchronously, the user sees Task 200 — the “Processing” view. This view polls a lightweight REST endpoint every few seconds that returns the current values of two technical fields written directly to the workitem by the AIAgentOperator:

Field Values
agent.status PENDING / RUNNING / DONE / ERROR
agent.progress Human-readable status message, e.g. "Calling LLM (iteration 1)..."

When the poll detects agent.status = "DONE", the frontend performs a full-page reload — the workflow engine has already moved the workitem to its next state and the user lands directly on the result or the newly started target workflow.


When to Use the BPMN AI Agent

Use the BPMN AI Agent when the user interaction requires the AI to take a concrete action within the system, not just generate text. The primary use cases are:

  • Process initiation from natural language — allowing users to start any workflow they have access to without navigating menus or knowing process names in advance
  • Conversational data collection — the agent gathers all required form fields from the conversation, asks only for what is missing, and submits when complete

For pure text generation tasks within a running workflow process — such as drafting content, summarising documents, or classifying data — the OpenAIAPIAdapter or ImixsAIAssistantAdapter remain the appropriate choice.