@camunda/e2e-test-suite 0.0.1098 → 0.0.1100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,10 @@ declare class TaskProcessesPage {
6
6
  readonly processes: Locator;
7
7
  readonly availableTasks: Locator;
8
8
  readonly waitingForTasksText: Locator;
9
+ readonly searchProcessesSearchbox: Locator;
10
+ readonly processesTab: Locator;
9
11
  constructor(page: Page);
12
+ searchForProcess(name: string): Promise<void>;
10
13
  clickpopupContinueButton(): Promise<void>;
11
14
  startProcess(name: string): Promise<void>;
12
15
  }
@@ -11,6 +11,8 @@ class TaskProcessesPage {
11
11
  processes;
12
12
  availableTasks;
13
13
  waitingForTasksText;
14
+ searchProcessesSearchbox;
15
+ processesTab;
14
16
  constructor(page) {
15
17
  this.page = page;
16
18
  this.popupContinueButton = page.getByRole('button', { name: 'Continue' });
@@ -18,6 +20,49 @@ class TaskProcessesPage {
18
20
  this.processes = page.locator('[data-testid="process-tile"]');
19
21
  this.availableTasks = page.getByTitle('Available tasks').first();
20
22
  this.waitingForTasksText = this.page.getByText('Waiting for tasks...');
23
+ this.searchProcessesSearchbox = page.getByRole('searchbox', {
24
+ name: 'Search processes',
25
+ });
26
+ this.processesTab = page.getByRole('link', { name: 'Processes' });
27
+ }
28
+ // Tasklist's process list is an infinite list that asks for only 12 process
29
+ // definitions at a time (`PROCESS_DEFINITIONS_PAGE_SIZE` in the
30
+ // orchestration-cluster webapp) and reveals the rest behind "Load more".
31
+ // The RBA clusters these flows run against are long-lived and gain two more
32
+ // definitions every night, so the one deployed seconds ago sits at the far
33
+ // end of that list: walking to it costs a round trip per 12 entries and the
34
+ // assertion's budget runs out first, which is why raising the retry count
35
+ // never made a difference. Filter the list instead -- the field is sent as
36
+ // `processDefinitionId: {$like: *name*}`, so the process comes back on the
37
+ // first page and the assertion is about the process rather than about how
38
+ // far pagination got. The filter lives in the URL query, so it survives the
39
+ // reloads the retry helpers do between attempts.
40
+ async searchForProcess(name) {
41
+ const maxAttempts = 3;
42
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
43
+ try {
44
+ await (0, test_1.expect)(this.searchProcessesSearchbox).toBeVisible({
45
+ timeout: 60000,
46
+ });
47
+ await this.searchProcessesSearchbox.fill(name, { timeout: 30000 });
48
+ await (0, test_1.expect)(this.searchProcessesSearchbox).toHaveValue(name, {
49
+ timeout: 30000,
50
+ });
51
+ return;
52
+ }
53
+ catch (error) {
54
+ if (attempt === maxAttempts) {
55
+ throw error;
56
+ }
57
+ // Tasklist sends the tab back to Tasks whenever a new task arrives,
58
+ // which can happen at any point here -- the Processes view, and with
59
+ // it this searchbox, is then simply gone. Re-open Processes and try
60
+ // again rather than trusting we are still on it.
61
+ console.warn(`Attempt ${attempt} failed to filter the process list; ` +
62
+ 're-opening the Processes tab and retrying.');
63
+ await this.processesTab.click({ timeout: 60000 });
64
+ }
65
+ }
21
66
  }
22
67
  async clickpopupContinueButton() {
23
68
  await this.page.waitForTimeout(3000);
@@ -28,6 +73,7 @@ class TaskProcessesPage {
28
73
  }
29
74
  async startProcess(name) {
30
75
  if (process.env.TASKLIST_VERSION === 'v2') {
76
+ await this.searchForProcess(name);
31
77
  await (0, expectTextWithPagination_1.expectTextWithPagination)(this.page, name);
32
78
  const container = this.page
33
79
  .locator('div')
@@ -0,0 +1,446 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
3
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
4
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
5
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
6
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
7
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
+ xmlns:bioc="http://bpmn.io/schema/bpmn/biocolor/1.0"
9
+ xmlns:color="http://www.omg.org/spec/BPMN/non-normative/color/1.0"
10
+ xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_18jxukq"
11
+ targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler"
12
+ exporterVersion="2de5b0b" modeler:executionPlatform="Camunda Cloud"
13
+ modeler:executionPlatformVersion="8.9.0">
14
+ <bpmn:process id="ai-agent-chat-with-tools-gemini-vertex" name="AI Agent Chat With Tools Gemini Vertex"
15
+ isExecutable="true">
16
+ <bpmn:startEvent id="StartEvent_1">
17
+ <bpmn:extensionElements>
18
+ <zeebe:formDefinition formId="ai-agent-chat-initial-request" />
19
+ </bpmn:extensionElements>
20
+ <bpmn:outgoing>Flow_0pbzrme</bpmn:outgoing>
21
+ </bpmn:startEvent>
22
+ <bpmn:sequenceFlow id="Flow_0pbzrme" sourceRef="StartEvent_1" targetRef="Gateway_0z6ctwk" />
23
+ <bpmn:serviceTask id="AI_Agent" name="AI Agent"
24
+ zeebe:modelerTemplate="io.camunda.connectors.agenticai.ai-agent-task.v2"
25
+ zeebe:modelerTemplateVersion="1"
26
+ zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNBNTZFRkYiLz4KPG1hc2sgaWQ9InBhdGgtMi1vdXRzaWRlLTFfMTg1XzYiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjQiIHk9IjQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0iYmxhY2siPgo8cmVjdCBmaWxsPSJ3aGl0ZSIgeD0iNCIgeT0iNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjAuMDEwNSAxMi4wOTg3QzE4LjQ5IDEwLjU4OTQgMTcuMTU5NCA4LjEwODE0IDE2LjE3OTkgNi4wMTEwM0MxNi4xNTIgNi4wMDQ1MSAxNi4xMTc2IDYgMTYuMDc5NCA2QzE2LjA0MTEgNiAxNi4wMDY2IDYuMDA0NTEgMTUuOTc4OCA2LjAxMTA0QzE0Ljk5OTQgOC4xMDgxNCAxMy42Njk3IDEwLjU4ODkgMTIuMTQ4MSAxMi4wOTgxQzEwLjYyNjkgMTMuNjA3MSA4LjEyNTY4IDE0LjkyNjQgNi4wMTE1NyAxNS44OTgxQzYuMDA0NzQgMTUuOTI2MSA2IDE1Ljk2MTEgNiAxNkM2IDE2LjAzODcgNi4wMDQ2OCAxNi4wNzM2IDYuMDExNDQgMTYuMTAxNEM4LjEyNTE5IDE3LjA3MjkgMTAuNjI2MiAxOC4zOTE5IDEyLjE0NzcgMTkuOTAxNkMxMy42Njk3IDIxLjQxMDcgMTQuOTk5NiAyMy44OTIgMTUuOTc5MSAyNS45ODlDMTYuMDA2OCAyNS45OTU2IDE2LjA0MTEgMjYgMTYuMDc5MyAyNkMxNi4xMTc1IDI2IDE2LjE1MTkgMjUuOTk1NCAxNi4xNzk2IDI1Ljk4OUMxNy4xNTkxIDIzLjg5MiAxOC40ODg4IDIxLjQxMSAyMC4wMDk5IDE5LjkwMjFNMjAuMDA5OSAxOS45MDIxQzIxLjUyNTMgMTguMzk4NyAyMy45NDY1IDE3LjA2NjkgMjUuOTkxNSAxNi4wODI0QzI1Ljk5NjUgMTYuMDU5MyAyNiAxNi4wMzEgMjYgMTUuOTk5N0MyNiAxNS45Njg0IDI1Ljk5NjUgMTUuOTQwMyAyNS45OTE1IDE1LjkxNzFDMjMuOTQ3NCAxNC45MzI3IDIxLjUyNTkgMTMuNjAxIDIwLjAxMDUgMTIuMDk4NyIvPgo8L21hc2s+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjAuMDEwNSAxMi4wOTg3QzE4LjQ5IDEwLjU4OTQgMTcuMTU5NCA4LjEwODE0IDE2LjE3OTkgNi4wMTEwM0MxNi4xNTIgNi4wMDQ1MSAxNi4xMTc2IDYgMTYuMDc5NCA2QzE2LjA0MTEgNiAxNi4wMDY2IDYuMDA0NTEgMTUuOTc4OCA2LjAxMTA0QzE0Ljk5OTQgOC4xMDgxNCAxMy42Njk3IDEwLjU4ODkgMTIuMTQ4MSAxMi4wOTgxQzEwLjYyNjkgMTMuNjA3MSA4LjEyNTY4IDE0LjkyNjQgNi4wMTE1NyAxNS44OTgxQzYuMDA0NzQgMTUuOTI2MSA2IDE1Ljk2MTEgNiAxNkM2IDE2LjAzODcgNi4wMDQ2OCAxNi4wNzM2IDYuMDExNDQgMTYuMTAxNEM4LjEyNTE5IDE3LjA3MjkgMTAuNjI2MiAxOC4zOTE5IDEyLjE0NzcgMTkuOTAxNkMxMy42Njk3IDIxLjQxMDcgMTQuOTk5NiAyMy44OTIgMTUuOTc5MSAyNS45ODlDMTYuMDA2OCAyNS45OTU2IDE2LjA0MTEgMjYgMTYuMDc5MyAyNkMxNi4xMTc1IDI2IDE2LjE1MTkgMjUuOTk1NCAxNi4xNzk2IDI1Ljk4OUMxNy4xNTkxIDIzLjg5MiAxOC40ODg4IDIxLjQxMSAyMC4wMDk5IDE5LjkwMjFNMjAuMDA5OSAxOS45MDIxQzIxLjUyNTMgMTguMzk4NyAyMy45NDY1IDE3LjA2NjkgMjUuOTkxNSAxNi4wODI0QzI1Ljk5NjUgMTYuMDU5MyAyNiAxNi4wMzEgMjYgMTUuOTk5N0MyNiAxNS45Njg0IDI1Ljk5NjUgMTUuOTQwMyAyNS45OTE1IDE1LjkxNzFDMjMuOTQ3NCAxNC45MzI3IDIxLjUyNTkgMTMuNjAxIDIwLjAxMDUgMTIuMDk4NyIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMC4wMTA1IDEyLjA5ODdDMTguNDkgMTAuNTg5NCAxNy4xNTk0IDguMTA4MTQgMTYuMTc5OSA2LjAxMTAzQzE2LjE1MiA2LjAwNDUxIDE2LjExNzYgNiAxNi4wNzk0IDZDMTYuMDQxMSA2IDE2LjAwNjYgNi4wMDQ1MSAxNS45Nzg4IDYuMDExMDRDMTQuOTk5NCA4LjEwODE0IDEzLjY2OTcgMTAuNTg4OSAxMi4xNDgxIDEyLjA5ODFDMTAuNjI2OSAxMy42MDcxIDguMTI1NjggMTQuOTI2NCA2LjAxMTU3IDE1Ljg5ODFDNi4wMDQ3NCAxNS45MjYxIDYgMTUuOTYxMSA2IDE2QzYgMTYuMDM4NyA2LjAwNDY4IDE2LjA3MzYgNi4wMTE0NCAxNi4xMDE0QzguMTI1MTkgMTcuMDcyOSAxMC42MjYyIDE4LjM5MTkgMTIuMTQ3NyAxOS45MDE2QzEzLjY2OTcgMjEuNDEwNyAxNC45OTk2IDIzLjg5MiAxNS45NzkxIDI1Ljk4OUMxNi4wMDY4IDI1Ljk5NTYgMTYuMDQxMSAyNiAxNi4wNzkzIDI2QzE2LjExNzUgMjYgMTYuMTUxOSAyNS45OTU0IDE2LjE3OTYgMjUuOTg5QzE3LjE1OTEgMjMuODkyIDE4LjQ4ODggMjEuNDExIDIwLjAwOTkgMTkuOTAyMU0yMC4wMDk5IDE5LjkwMjFDMjEuNTI1MyAxOC4zOTg3IDIzLjk0NjUgMTcuMDY2OSAyNS45OTE1IDE2LjA4MjRDMjUuOTk2NSAxNi4wNTkzIDI2IDE2LjAzMSAyNiAxNS45OTk3QzI2IDE1Ljk2ODQgMjUuOTk2NSAxNS45NDAzIDI1Ljk5MTUgMTUuOTE3MUMyMy45NDc0IDE0LjkzMjcgMjEuNTI1OSAxMy42MDEgMjAuMDEwNSAxMi4wOTg3IiBzdHJva2U9IiM0OTFEOEIiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgbWFzaz0idXJsKCNwYXRoLTItb3V0c2lkZS0xXzE4NV82KSIvPgo8L3N2Zz4K">
27
+ <bpmn:extensionElements>
28
+ <zeebe:taskDefinition type="io.camunda.agenticai:aiagent:task:2" retries="3" />
29
+ <zeebe:ioMapping>
30
+ <zeebe:input source="google-gemini" target="provider.type" />
31
+ <zeebe:input source="google-vertex-ai" target="provider.googleGemini.backend.type" />
32
+ <zeebe:input source="{{secrets.IDP_GCP_VERTEX_PROJECT_ID}}"
33
+ target="provider.googleGemini.backend.googleVertexAi.projectId" />
34
+ <zeebe:input source="{{secrets.IDP_GCP_VERTEX_REGION}}"
35
+ target="provider.googleGemini.backend.googleVertexAi.region" />
36
+ <zeebe:input source="serviceAccountCredentials"
37
+ target="provider.googleGemini.backend.googleVertexAi.authentication.type" />
38
+ <zeebe:input source="{{secrets.IDP_GCP_SERVICE_ACCOUNT}}"
39
+ target="provider.googleGemini.backend.googleVertexAi.authentication.jsonKey" />
40
+ <zeebe:input source="gemini-2.5-pro"
41
+ target="provider.googleGemini.model.model" />
42
+ <zeebe:input
43
+ source="You are a helpful, generic chat agent which can answer a wide amount of questions based on your knowledge and an optional set of available tools.&#10;&#10;If tools are provided, you should prefer them instead of guessing an answer. You can call the same tool multiple times by providing different input values. Don&#39;t guess any tools which were not explicitely configured. If no tool matches the request, try to generate an answer. If you&#39;re not able to find a good answer, return with a message stating why you&#39;re not able to.&#10;&#10;If you are prompted to interact with a person, never guess contact details, but use available user/person lookup tools instead and return with an error if you&#39;re not able to look up appropriate data.&#10;&#10;Thinking, step by step, before you execute your tools, you think using the template `&#60;thinking&#62;&#60;context&#62;&#60;/context&#62;&#60;reflection&#62;&#60;/reflection&#62;&#60;/thinking&#62;`"
44
+ target="data.systemPrompt.prompt" />
45
+ <zeebe:input
46
+ source="=&#34;Generate a single sentence in the following exact format, using Paris, France as the city and country:&#10;&#10;The current date and time in {City, Country}, is approximately {h:mm AM/PM} on {Month day, year}.&#10;&#10;But only with the sentence/format as above, nothing else&#34;"
47
+ target="data.userPrompt.prompt" />
48
+ <zeebe:input
49
+ source="=if (is defined(followUpInput) or is defined(followUpDocuments)) then followUpDocuments else inputDocuments"
50
+ target="data.userPrompt.documents" />
51
+ <zeebe:input source="Agent_Tools" target="data.tools.containerElementId" />
52
+ <zeebe:input source="=toolCallResults" target="data.tools.toolCallResults" />
53
+ <zeebe:input source="=agent.context" target="data.context" />
54
+ <zeebe:input source="in-process" target="data.memory.storage.type" />
55
+ <zeebe:input source="=20" target="data.memory.contextWindowSize" />
56
+ <zeebe:input source="=10" target="data.limits.maxModelCalls" />
57
+ <zeebe:input source="text" target="data.response.format.type" />
58
+ <zeebe:input source="=false" target="data.response.format.parseJson" />
59
+ <zeebe:input source="=false" target="data.response.includeAssistantMessage" />
60
+ </zeebe:ioMapping>
61
+ <zeebe:taskHeaders>
62
+ <zeebe:header key="elementTemplateVersion" value="1" />
63
+ <zeebe:header key="elementTemplateId" value="io.camunda.connectors.agenticai.ai-agent-task.v2" />
64
+ <zeebe:header key="resultVariable" value="agent" />
65
+ <zeebe:header key="retryBackoff" value="PT2S" />
66
+ </zeebe:taskHeaders>
67
+ </bpmn:extensionElements>
68
+ <bpmn:incoming>Flow_050377t</bpmn:incoming>
69
+ <bpmn:outgoing>Flow_041ffce</bpmn:outgoing>
70
+ </bpmn:serviceTask>
71
+ <bpmn:exclusiveGateway id="Gateway_0z6ctwk">
72
+ <bpmn:incoming>Flow_0pbzrme</bpmn:incoming>
73
+ <bpmn:incoming>Flow_01k9dy1</bpmn:incoming>
74
+ <bpmn:incoming>Flow_19gp461</bpmn:incoming>
75
+ <bpmn:outgoing>Flow_050377t</bpmn:outgoing>
76
+ </bpmn:exclusiveGateway>
77
+ <bpmn:userTask id="User_Feedback" name="User Feedback">
78
+ <bpmn:extensionElements>
79
+ <zeebe:userTask />
80
+ <zeebe:formDefinition formId="ai-agent-chat-user-feedback" />
81
+ </bpmn:extensionElements>
82
+ <bpmn:incoming>Flow_11y3kim</bpmn:incoming>
83
+ <bpmn:outgoing>Flow_09y08ef</bpmn:outgoing>
84
+ </bpmn:userTask>
85
+ <bpmn:exclusiveGateway id="Gateway_1dcg4ha" name="User satisfied?">
86
+ <bpmn:incoming>Flow_09y08ef</bpmn:incoming>
87
+ <bpmn:outgoing>Flow_19gp461</bpmn:outgoing>
88
+ <bpmn:outgoing>Flow_16c9bwj</bpmn:outgoing>
89
+ </bpmn:exclusiveGateway>
90
+ <bpmn:sequenceFlow id="Flow_09y08ef" sourceRef="User_Feedback" targetRef="Gateway_1dcg4ha" />
91
+ <bpmn:sequenceFlow id="Flow_19gp461" name="no - we follow up" sourceRef="Gateway_1dcg4ha"
92
+ targetRef="Gateway_0z6ctwk">
93
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=userSatisfied = null or
94
+ userSatisfied = false</bpmn:conditionExpression>
95
+ </bpmn:sequenceFlow>
96
+ <bpmn:endEvent id="Event_0i39jej">
97
+ <bpmn:incoming>Flow_16c9bwj</bpmn:incoming>
98
+ </bpmn:endEvent>
99
+ <bpmn:sequenceFlow id="Flow_16c9bwj" name="yes" sourceRef="Gateway_1dcg4ha"
100
+ targetRef="Event_0i39jej">
101
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=userSatisfied</bpmn:conditionExpression>
102
+ </bpmn:sequenceFlow>
103
+ <bpmn:sequenceFlow id="Flow_041ffce" sourceRef="AI_Agent" targetRef="Gateway_0bukj01" />
104
+ <bpmn:exclusiveGateway id="Gateway_0bukj01" name="Includes tool calls?">
105
+ <bpmn:incoming>Flow_041ffce</bpmn:incoming>
106
+ <bpmn:outgoing>Flow_00lg7l2</bpmn:outgoing>
107
+ <bpmn:outgoing>Flow_11y3kim</bpmn:outgoing>
108
+ </bpmn:exclusiveGateway>
109
+ <bpmn:adHocSubProcess id="Agent_Tools" name="Agent Tools">
110
+ <bpmn:extensionElements>
111
+ <zeebe:adHoc activeElementsCollection="=[toolCall._meta.name]" />
112
+ </bpmn:extensionElements>
113
+ <bpmn:incoming>Flow_00lg7l2</bpmn:incoming>
114
+ <bpmn:outgoing>Flow_01k9dy1</bpmn:outgoing>
115
+ <bpmn:multiInstanceLoopCharacteristics>
116
+ <bpmn:extensionElements>
117
+ <zeebe:loopCharacteristics inputCollection="=agent.toolCalls" inputElement="toolCall"
118
+ outputCollection="toolCallResults"
119
+ outputElement="={&#10; id: toolCall._meta.id,&#10; name: toolCall._meta.name,&#10; content: toolCallResult&#10;}" />
120
+ </bpmn:extensionElements>
121
+ </bpmn:multiInstanceLoopCharacteristics>
122
+ <bpmn:scriptTask id="GetDateAndTime" name="Get Date and Time">
123
+ <bpmn:documentation>Returns the current date and time including the timezone.</bpmn:documentation>
124
+ <bpmn:extensionElements>
125
+ <zeebe:script expression="=now()" resultVariable="toolCallResult" />
126
+ </bpmn:extensionElements>
127
+ </bpmn:scriptTask>
128
+ <bpmn:serviceTask id="Search_Recipe" name="Search recipe"
129
+ zeebe:modelerTemplate="io.camunda.connectors.HttpJson.v2" zeebe:modelerTemplateVersion="10"
130
+ zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHZpZXdCb3g9IjAgMCAxOCAxOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE3LjAzMzUgOC45OTk5N0MxNy4wMzM1IDEzLjQ0NzUgMTMuNDI4MSAxNy4wNTI5IDguOTgwNjUgMTcuMDUyOUM0LjUzMzE2IDE3LjA1MjkgMC45Mjc3NjUgMTMuNDQ3NSAwLjkyNzc2NSA4Ljk5OTk3QzAuOTI3NzY1IDQuNTUyNDggNC41MzMxNiAwLjk0NzA4MyA4Ljk4MDY1IDAuOTQ3MDgzQzEzLjQyODEgMC45NDcwODMgMTcuMDMzNSA0LjU1MjQ4IDE3LjAzMzUgOC45OTk5N1oiIGZpbGw9IiM1MDU1NjIiLz4KPHBhdGggZD0iTTQuOTMxMjYgMTQuMTU3MUw2Ljc4MTA2IDMuNzE0NzFIMTAuMTM3NUMxMS4xOTE3IDMuNzE0NzEgMTEuOTgyNCAzLjk4MzIzIDEyLjUwOTUgNC41MjAyN0MxMy4wNDY1IDUuMDQ3MzYgMTMuMzE1IDUuNzMzNTggMTMuMzE1IDYuNTc4OTJDMTMuMzE1IDcuNDQ0MTQgMTMuMDcxNCA4LjE1NTIyIDEyLjU4NDEgOC43MTIxNUMxMi4xMDY3IDkuMjU5MTMgMTEuNDU1MyA5LjYzNzA1IDEwLjYyOTggOS44NDU5TDEyLjA2MTkgMTQuMTU3MUgxMC4zMzE1TDkuMDMzNjQgMTAuMDI0OUg3LjI0MzUxTDYuNTEyNTQgMTQuMTU3MUg0LjkzMTI2Wk03LjQ5NzExIDguNTkyODFIOS4yNDI0OEM5Ljk5ODMyIDguNTkyODEgMTAuNTkwMSA4LjQyMzc0IDExLjAxNzcgOC4wODU2MUMxMS40NTUzIDcuNzM3NTMgMTEuNjc0MSA3LjI2NTEzIDExLjY3NDEgNi42Njg0MkMxMS42NzQxIDYuMTkxMDYgMTEuNTI0OSA1LjgxODExIDExLjIyNjUgNS41NDk1OUMxMC45MjgyIDUuMjcxMTMgMTAuNDU1OCA1LjEzMTkgOS44MDkzNiA1LjEzMTlIOC4xMDg3NEw3LjQ5NzExIDguNTkyODFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K">
131
+ <bpmn:documentation>Searches a recipe given a search query</bpmn:documentation>
132
+ <bpmn:extensionElements>
133
+ <zeebe:taskDefinition type="io.camunda:http-json:1" retries="3" />
134
+ <zeebe:ioMapping>
135
+ <zeebe:input source="noAuth" target="authentication.type" />
136
+ <zeebe:input source="GET" target="method" />
137
+ <zeebe:input source="https://dummyjson.com/recipes/search" target="url" />
138
+ <zeebe:input
139
+ source="={&#10; q: fromAi(toolCall.searchQuery, &#34;The query describing which recipe to search (e.g. a specific dish or the cuisine).&#34;)&#10;}"
140
+ target="queryParameters" />
141
+ <zeebe:input source="=false" target="storeResponse" />
142
+ <zeebe:input source="20" target="connectionTimeoutInSeconds" />
143
+ <zeebe:input source="20" target="readTimeoutInSeconds" />
144
+ <zeebe:input source="=false" target="ignoreNullValues" />
145
+ </zeebe:ioMapping>
146
+ <zeebe:taskHeaders>
147
+ <zeebe:header key="resultExpression"
148
+ value="={&#10; toolCallResult: if (count(response.body.recipes) &#62; 0) then response.body.recipes else &#34;No result found.&#34;&#10;}" />
149
+ <zeebe:header key="retryBackoff" value="PT0S" />
150
+ </zeebe:taskHeaders>
151
+ </bpmn:extensionElements>
152
+ </bpmn:serviceTask>
153
+ <bpmn:scriptTask id="SuperfluxProduct" name="Superflux Product Calculation">
154
+ <bpmn:documentation>Calculates the superflux product (a very complicated method only this
155
+ tool can do) given two input numbers</bpmn:documentation>
156
+ <bpmn:extensionElements>
157
+ <zeebe:script expression="=3 * (inputA + inputB)" resultVariable="toolCallResult" />
158
+ <zeebe:ioMapping>
159
+ <zeebe:input
160
+ source="=fromAi(toolCall.a, &#34;The first number to be superflux calculated.&#34;, &#34;number&#34;)"
161
+ target="inputA" />
162
+ <zeebe:input
163
+ source="=fromAi(toolCall.b, &#34;The second number to be superflux calculated.&#34;, &#34;number&#34;)"
164
+ target="inputB" />
165
+ </zeebe:ioMapping>
166
+ </bpmn:extensionElements>
167
+ </bpmn:scriptTask>
168
+ <bpmn:userTask id="AskHumanToSendEmail" name="Ask human to send email">
169
+ <bpmn:documentation>Ask a human to send an email for you</bpmn:documentation>
170
+ <bpmn:extensionElements>
171
+ <zeebe:userTask />
172
+ <zeebe:formDefinition formId="ai-agent-chat-human-send-email-request" />
173
+ <zeebe:ioMapping>
174
+ <zeebe:input
175
+ source="=fromAi(toolCall.instructions, &#34;Instructions for the human to follow when sending the email, including background of the email.&#34;)"
176
+ target="instructions" />
177
+ <zeebe:input
178
+ source="=fromAi(toolCall.recipient_name, &#34;The recipient&#39;s full name.&#34;)"
179
+ target="recipient_name" />
180
+ <zeebe:input
181
+ source="=fromAi(toolCall.recipient_email, &#34;The the recipient&#39;s email address.&#34;)"
182
+ target="recipient_email" />
183
+ <zeebe:input
184
+ source="=fromAi(toolCall.email_subject, &#34;The subject of the email.&#34;)"
185
+ target="email_subject" />
186
+ <zeebe:input source="=fromAi(toolCall.email_body, &#34;The body of the email.&#34;)"
187
+ target="email_body" />
188
+ <zeebe:output
189
+ source="={&#10; operatorFeedback: operatorFeedback,&#10; emailOk: emailOk&#10;}"
190
+ target="toolCallResult" />
191
+ </zeebe:ioMapping>
192
+ </bpmn:extensionElements>
193
+ <bpmn:outgoing>Flow_0demz1g</bpmn:outgoing>
194
+ </bpmn:userTask>
195
+ <bpmn:sequenceFlow id="Flow_0demz1g" sourceRef="AskHumanToSendEmail"
196
+ targetRef="Gateway_1lux75t" />
197
+ <bpmn:exclusiveGateway id="Gateway_1lux75t" name="OK to send email?">
198
+ <bpmn:incoming>Flow_0demz1g</bpmn:incoming>
199
+ <bpmn:outgoing>Flow_0uqjclh</bpmn:outgoing>
200
+ <bpmn:outgoing>Flow_1l2ws6w</bpmn:outgoing>
201
+ </bpmn:exclusiveGateway>
202
+ <bpmn:sequenceFlow id="Flow_0uqjclh" name="yes" sourceRef="Gateway_1lux75t"
203
+ targetRef="SendEmail">
204
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=toolCallResult.emailOk</bpmn:conditionExpression>
205
+ </bpmn:sequenceFlow>
206
+ <bpmn:sequenceFlow id="Flow_1l2ws6w" name="no" sourceRef="Gateway_1lux75t"
207
+ targetRef="Event_1wxfv4u">
208
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=toolCallResult.emailOk != true</bpmn:conditionExpression>
209
+ </bpmn:sequenceFlow>
210
+ <bpmn:intermediateThrowEvent id="Event_1wxfv4u" name="loop back with feedback">
211
+ <bpmn:incoming>Flow_1l2ws6w</bpmn:incoming>
212
+ </bpmn:intermediateThrowEvent>
213
+ <bpmn:scriptTask id="SendEmail" name="Send email">
214
+ <bpmn:extensionElements>
215
+ <zeebe:script expression="=true" resultVariable="emailSent" />
216
+ <zeebe:ioMapping>
217
+ <zeebe:output source="=emailSent" target="toolCallResult.emailSent" />
218
+ </zeebe:ioMapping>
219
+ </bpmn:extensionElements>
220
+ <bpmn:incoming>Flow_0uqjclh</bpmn:incoming>
221
+ </bpmn:scriptTask>
222
+ </bpmn:adHocSubProcess>
223
+ <bpmn:sequenceFlow id="Flow_00lg7l2" name="yes" sourceRef="Gateway_0bukj01"
224
+ targetRef="Agent_Tools">
225
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=not(is empty(agent.toolCalls))</bpmn:conditionExpression>
226
+ </bpmn:sequenceFlow>
227
+ <bpmn:sequenceFlow id="Flow_11y3kim" name="no" sourceRef="Gateway_0bukj01"
228
+ targetRef="User_Feedback">
229
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=is empty(agent.toolCalls)</bpmn:conditionExpression>
230
+ </bpmn:sequenceFlow>
231
+ <bpmn:sequenceFlow id="Flow_050377t" sourceRef="Gateway_0z6ctwk" targetRef="AI_Agent" />
232
+ <bpmn:sequenceFlow id="Flow_01k9dy1" sourceRef="Agent_Tools" targetRef="Gateway_0z6ctwk" />
233
+ <bpmn:textAnnotation id="TextAnnotation_0rg9ar3">
234
+ <bpmn:text>Rough outline of the functionality
235
+
236
+ - Loads previous agent context (conversation, metrics, ...)
237
+ - Loads available tool information from ad-hoc sub-process definition
238
+ - Resolves tool information from gateway tool definitions such as MCP
239
+ - Checks limits (e.g. maximum LLM model calls)
240
+ - Merges the current request (either a user message or a tool call response) into the memory
241
+ - Calls the LLM, including previous/edited memory (limited to max amount of messages) +
242
+ available tools schema
243
+ - Returns last response as text or JSON format, depending on the configuration
244
+ - Returns tools to call, including their parameters</bpmn:text>
245
+ </bpmn:textAnnotation>
246
+ <bpmn:association id="Association_0ic98nl" associationDirection="None" sourceRef="AI_Agent"
247
+ targetRef="TextAnnotation_0rg9ar3" />
248
+ <bpmn:textAnnotation id="TextAnnotation_1keavvi">
249
+ <bpmn:text>For every tool call in &lt;agent.toolCalls&gt;</bpmn:text>
250
+ </bpmn:textAnnotation>
251
+ <bpmn:association id="Association_0q5n90x" associationDirection="None" sourceRef="Agent_Tools"
252
+ targetRef="TextAnnotation_1keavvi" />
253
+ <bpmn:textAnnotation id="TextAnnotation_1cvjkfu">
254
+ <bpmn:text>Every execution (flow node or sequence of flow nodes) MUST write
255
+ &lt;toolCallResult&gt; variable</bpmn:text>
256
+ </bpmn:textAnnotation>
257
+ <bpmn:textAnnotation id="TextAnnotation_1tvejhg">
258
+ <bpmn:text>Every task inside of an execution MAY query for external inputs provided by the
259
+ model through the fromAI helper:
260
+
261
+ fromAi(toolCall.id, "The user ID", "number")
262
+
263
+ The outside brain &lt;AI Agent&gt; will take that information to instruct the model which
264
+ data to provide in which format.</bpmn:text>
265
+ </bpmn:textAnnotation>
266
+ <bpmn:textAnnotation id="TextAnnotation_0xt28ql">
267
+ <bpmn:text>Must produce output as &lt;toolCallResults=[ { id, name, content } ]&gt;</bpmn:text>
268
+ </bpmn:textAnnotation>
269
+ <bpmn:association id="Association_14t02ll" associationDirection="None" sourceRef="Agent_Tools"
270
+ targetRef="TextAnnotation_0xt28ql" />
271
+ </bpmn:process>
272
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
273
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ai-agent-chat-with-tools-gemini-vertex">
274
+ <bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
275
+ <dc:Bounds x="152" y="442" width="36" height="36" />
276
+ </bpmndi:BPMNShape>
277
+ <bpmndi:BPMNShape id="Activity_0xj2598_di" bpmnElement="AI_Agent" bioc:stroke="#205022"
278
+ bioc:fill="#c8e6c9" color:background-color="#c8e6c9" color:border-color="#205022">
279
+ <dc:Bounds x="340" y="420" width="100" height="80" />
280
+ <bpmndi:BPMNLabel />
281
+ </bpmndi:BPMNShape>
282
+ <bpmndi:BPMNShape id="Gateway_0z6ctwk_di" bpmnElement="Gateway_0z6ctwk" isMarkerVisible="true">
283
+ <dc:Bounds x="245" y="435" width="50" height="50" />
284
+ </bpmndi:BPMNShape>
285
+ <bpmndi:BPMNShape id="Activity_1fam9db_di" bpmnElement="User_Feedback">
286
+ <dc:Bounds x="640" y="420" width="100" height="80" />
287
+ <bpmndi:BPMNLabel />
288
+ </bpmndi:BPMNShape>
289
+ <bpmndi:BPMNShape id="Gateway_1dcg4ha_di" bpmnElement="Gateway_1dcg4ha" isMarkerVisible="true">
290
+ <dc:Bounds x="805" y="435" width="50" height="50" />
291
+ <bpmndi:BPMNLabel>
292
+ <dc:Bounds x="794" y="492" width="73" height="14" />
293
+ </bpmndi:BPMNLabel>
294
+ </bpmndi:BPMNShape>
295
+ <bpmndi:BPMNShape id="Event_0i39jej_di" bpmnElement="Event_0i39jej">
296
+ <dc:Bounds x="912" y="442" width="36" height="36" />
297
+ </bpmndi:BPMNShape>
298
+ <bpmndi:BPMNShape id="Gateway_0bukj01_di" bpmnElement="Gateway_0bukj01" isMarkerVisible="true">
299
+ <dc:Bounds x="505" y="435" width="50" height="50" />
300
+ <bpmndi:BPMNLabel>
301
+ <dc:Bounds x="499" y="406" width="62" height="27" />
302
+ </bpmndi:BPMNLabel>
303
+ </bpmndi:BPMNShape>
304
+ <bpmndi:BPMNShape id="Activity_03yngb7_di" bpmnElement="Agent_Tools" isExpanded="true"
305
+ bioc:stroke="#6b3c00" bioc:fill="#ffe0b2" color:background-color="#ffe0b2"
306
+ color:border-color="#6b3c00">
307
+ <dc:Bounds x="640" y="560" width="400" height="360" />
308
+ </bpmndi:BPMNShape>
309
+ <bpmndi:BPMNShape id="Activity_1sbkoqq_di" bpmnElement="GetDateAndTime">
310
+ <dc:Bounds x="670" y="600" width="100" height="80" />
311
+ <bpmndi:BPMNLabel />
312
+ </bpmndi:BPMNShape>
313
+ <bpmndi:BPMNShape id="Activity_0d8luif_di" bpmnElement="Search_Recipe">
314
+ <dc:Bounds x="920" y="600" width="100" height="80" />
315
+ <bpmndi:BPMNLabel />
316
+ </bpmndi:BPMNShape>
317
+ <bpmndi:BPMNShape id="BPMNShape_0x0a1hy" bpmnElement="SuperfluxProduct">
318
+ <dc:Bounds x="790" y="600" width="100" height="80" />
319
+ <bpmndi:BPMNLabel />
320
+ </bpmndi:BPMNShape>
321
+ <bpmndi:BPMNShape id="Activity_16uhg8o_di" bpmnElement="AskHumanToSendEmail">
322
+ <dc:Bounds x="670" y="730" width="100" height="80" />
323
+ <bpmndi:BPMNLabel />
324
+ </bpmndi:BPMNShape>
325
+ <bpmndi:BPMNShape id="Gateway_1lux75t_di" bpmnElement="Gateway_1lux75t" isMarkerVisible="true">
326
+ <dc:Bounds x="815" y="745" width="50" height="50" />
327
+ <bpmndi:BPMNLabel>
328
+ <dc:Bounds x="812" y="716" width="56" height="27" />
329
+ </bpmndi:BPMNLabel>
330
+ </bpmndi:BPMNShape>
331
+ <bpmndi:BPMNShape id="Event_1ny5xkz_di" bpmnElement="Event_1wxfv4u">
332
+ <dc:Bounds x="822" y="832" width="36" height="36" />
333
+ <bpmndi:BPMNLabel>
334
+ <dc:Bounds x="805" y="875" width="70" height="27" />
335
+ </bpmndi:BPMNLabel>
336
+ </bpmndi:BPMNShape>
337
+ <bpmndi:BPMNShape id="Activity_1sddc2g_di" bpmnElement="SendEmail">
338
+ <dc:Bounds x="910" y="730" width="100" height="80" />
339
+ </bpmndi:BPMNShape>
340
+ <bpmndi:BPMNEdge id="Flow_0demz1g_di" bpmnElement="Flow_0demz1g">
341
+ <di:waypoint x="770" y="770" />
342
+ <di:waypoint x="815" y="770" />
343
+ </bpmndi:BPMNEdge>
344
+ <bpmndi:BPMNEdge id="Flow_0uqjclh_di" bpmnElement="Flow_0uqjclh">
345
+ <di:waypoint x="865" y="770" />
346
+ <di:waypoint x="910" y="770" />
347
+ <bpmndi:BPMNLabel>
348
+ <dc:Bounds x="879" y="752" width="18" height="14" />
349
+ </bpmndi:BPMNLabel>
350
+ </bpmndi:BPMNEdge>
351
+ <bpmndi:BPMNEdge id="Flow_1l2ws6w_di" bpmnElement="Flow_1l2ws6w">
352
+ <di:waypoint x="840" y="795" />
353
+ <di:waypoint x="840" y="832" />
354
+ <bpmndi:BPMNLabel>
355
+ <dc:Bounds x="849" y="803" width="13" height="14" />
356
+ </bpmndi:BPMNLabel>
357
+ </bpmndi:BPMNEdge>
358
+ <bpmndi:BPMNShape id="TextAnnotation_0rg9ar3_di" bpmnElement="TextAnnotation_0rg9ar3">
359
+ <dc:Bounds x="401" y="80" width="578" height="170" />
360
+ <bpmndi:BPMNLabel />
361
+ </bpmndi:BPMNShape>
362
+ <bpmndi:BPMNShape id="TextAnnotation_1keavvi_di" bpmnElement="TextAnnotation_1keavvi">
363
+ <dc:Bounds x="1080" y="510" width="240" height="26" />
364
+ <bpmndi:BPMNLabel />
365
+ </bpmndi:BPMNShape>
366
+ <bpmndi:BPMNShape id="TextAnnotation_1cvjkfu_di" bpmnElement="TextAnnotation_1cvjkfu">
367
+ <dc:Bounds x="1210" y="660" width="260" height="60" />
368
+ <bpmndi:BPMNLabel />
369
+ </bpmndi:BPMNShape>
370
+ <bpmndi:BPMNShape id="TextAnnotation_1tvejhg_di" bpmnElement="TextAnnotation_1tvejhg">
371
+ <dc:Bounds x="1210" y="740" width="286" height="142" />
372
+ <bpmndi:BPMNLabel />
373
+ </bpmndi:BPMNShape>
374
+ <bpmndi:BPMNShape id="TextAnnotation_0xt28ql_di" bpmnElement="TextAnnotation_0xt28ql">
375
+ <dc:Bounds x="1168" y="920" width="370" height="26" />
376
+ <bpmndi:BPMNLabel />
377
+ </bpmndi:BPMNShape>
378
+ <bpmndi:BPMNEdge id="Flow_0pbzrme_di" bpmnElement="Flow_0pbzrme">
379
+ <di:waypoint x="188" y="460" />
380
+ <di:waypoint x="245" y="460" />
381
+ </bpmndi:BPMNEdge>
382
+ <bpmndi:BPMNEdge id="Flow_09y08ef_di" bpmnElement="Flow_09y08ef">
383
+ <di:waypoint x="740" y="460" />
384
+ <di:waypoint x="805" y="460" />
385
+ </bpmndi:BPMNEdge>
386
+ <bpmndi:BPMNEdge id="Flow_19gp461_di" bpmnElement="Flow_19gp461">
387
+ <di:waypoint x="830" y="435" />
388
+ <di:waypoint x="830" y="350" />
389
+ <di:waypoint x="270" y="350" />
390
+ <di:waypoint x="270" y="435" />
391
+ <bpmndi:BPMNLabel>
392
+ <dc:Bounds x="748" y="333" width="83" height="14" />
393
+ </bpmndi:BPMNLabel>
394
+ </bpmndi:BPMNEdge>
395
+ <bpmndi:BPMNEdge id="Flow_16c9bwj_di" bpmnElement="Flow_16c9bwj">
396
+ <di:waypoint x="855" y="460" />
397
+ <di:waypoint x="912" y="460" />
398
+ <bpmndi:BPMNLabel>
399
+ <dc:Bounds x="875" y="442" width="18" height="14" />
400
+ </bpmndi:BPMNLabel>
401
+ </bpmndi:BPMNEdge>
402
+ <bpmndi:BPMNEdge id="Flow_041ffce_di" bpmnElement="Flow_041ffce">
403
+ <di:waypoint x="440" y="460" />
404
+ <di:waypoint x="505" y="460" />
405
+ </bpmndi:BPMNEdge>
406
+ <bpmndi:BPMNEdge id="Flow_00lg7l2_di" bpmnElement="Flow_00lg7l2">
407
+ <di:waypoint x="530" y="485" />
408
+ <di:waypoint x="530" y="850" />
409
+ <di:waypoint x="640" y="850" />
410
+ <bpmndi:BPMNLabel>
411
+ <dc:Bounds x="541" y="492" width="18" height="14" />
412
+ </bpmndi:BPMNLabel>
413
+ </bpmndi:BPMNEdge>
414
+ <bpmndi:BPMNEdge id="Flow_11y3kim_di" bpmnElement="Flow_11y3kim">
415
+ <di:waypoint x="555" y="460" />
416
+ <di:waypoint x="640" y="460" />
417
+ <bpmndi:BPMNLabel>
418
+ <dc:Bounds x="591" y="442" width="13" height="14" />
419
+ </bpmndi:BPMNLabel>
420
+ </bpmndi:BPMNEdge>
421
+ <bpmndi:BPMNEdge id="Flow_050377t_di" bpmnElement="Flow_050377t">
422
+ <di:waypoint x="295" y="460" />
423
+ <di:waypoint x="340" y="460" />
424
+ </bpmndi:BPMNEdge>
425
+ <bpmndi:BPMNEdge id="Flow_01k9dy1_di" bpmnElement="Flow_01k9dy1">
426
+ <di:waypoint x="1040" y="850" />
427
+ <di:waypoint x="1150" y="850" />
428
+ <di:waypoint x="1150" y="950" />
429
+ <di:waypoint x="270" y="950" />
430
+ <di:waypoint x="270" y="485" />
431
+ </bpmndi:BPMNEdge>
432
+ <bpmndi:BPMNEdge id="Association_0ic98nl_di" bpmnElement="Association_0ic98nl">
433
+ <di:waypoint x="410" y="420" />
434
+ <di:waypoint x="495" y="250" />
435
+ </bpmndi:BPMNEdge>
436
+ <bpmndi:BPMNEdge id="Association_0q5n90x_di" bpmnElement="Association_0q5n90x">
437
+ <di:waypoint x="1040" y="620" />
438
+ <di:waypoint x="1120" y="536" />
439
+ </bpmndi:BPMNEdge>
440
+ <bpmndi:BPMNEdge id="Association_14t02ll_di" bpmnElement="Association_14t02ll">
441
+ <di:waypoint x="1040" y="902" />
442
+ <di:waypoint x="1160" y="933" />
443
+ </bpmndi:BPMNEdge>
444
+ </bpmndi:BPMNPlane>
445
+ </bpmndi:BPMNDiagram>
446
+ </bpmn:definitions>
@@ -29,6 +29,10 @@ const aiAgentTestCases = [
29
29
  provider: 'AWS V1',
30
30
  bpmnPath: './resources/agentic_ai/ai-agent-chat-with-tools_aws_v1.bpmn',
31
31
  },
32
+ {
33
+ provider: 'Gemini Vertex',
34
+ bpmnPath: './resources/agentic_ai/ai-agent-chat-with-tools_gemini_vertex.bpmn',
35
+ },
32
36
  ];
33
37
  const dbVectorTestCases = [
34
38
  //Skipped due to bug 1208: https://github.com/camunda/c8-cross-component-e2e-tests/issues/1208
@@ -303,11 +303,15 @@ _8_10_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () =>
303
303
  await ocIdentityAuthorizationsPage.assertAuthorization('ROLEadmin*');
304
304
  });
305
305
  await _8_10_1.test.step('Navigate to Web Modeler', async () => {
306
- await appsPage.clickCamundaApps();
307
- await appsPage.clickModeler();
308
- await (0, test_1.expect)(modelerHomePage.modelerPageBanner).toBeVisible({
309
- timeout: 30000,
310
- });
306
+ // The hand-off into Modeler goes through `modeler.<host>/login`, which
307
+ // runs an invisible reCAPTCHA before it even reaches the IdP, so the tab
308
+ // regularly sits on a loading shell well past 30s -- and it can stall
309
+ // there for good, which a plain wait cannot recover from. Use the shared
310
+ // helper the other 8.10 specs already use for this exact stall: it waits
311
+ // a full window, grants a hand-off that is still in transit a second
312
+ // one, and otherwise re-enters through the apps menu for a fresh
313
+ // handshake.
314
+ await appsPage.openModelerWithRetry(modelerHomePage.modelerPageBanner);
311
315
  });
312
316
  await _8_10_1.test.step('Navigate to Cross Component Test Project', async () => {
313
317
  await modelerHomePage.clickCrossComponentProjectFolder();
@@ -326,7 +330,14 @@ _8_10_1.test.describe.parallel('RBA Enabled User Flows Test @tasklistV2', () =>
326
330
  });
327
331
  await taskPanelPage.clickProcessesTab();
328
332
  await taskProcessesPage.clickpopupContinueButton();
333
+ // Tasklist only fetches 12 process definitions per request and hides the
334
+ // rest behind "Load more", so on these long-lived RBA clusters a process
335
+ // deployed seconds ago is many pages down. Narrow the list to the
336
+ // process under test before asserting it is there -- the assertion
337
+ // itself is unchanged.
338
+ await taskProcessesPage.searchForProcess(process1);
329
339
  await (0, expectTextWithPagination_1.expectTextWithPagination)(page, process1);
340
+ await taskProcessesPage.searchForProcess(process2);
330
341
  await (0, expectTextWithPagination_1.expectTextWithPagination)(page, process2);
331
342
  });
332
343
  await _8_10_1.test.step('Assert First Process Can Be Started From Tasklist', async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1098",
3
+ "version": "0.0.1100",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,446 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
3
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
4
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
5
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
6
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
7
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
+ xmlns:bioc="http://bpmn.io/schema/bpmn/biocolor/1.0"
9
+ xmlns:color="http://www.omg.org/spec/BPMN/non-normative/color/1.0"
10
+ xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_18jxukq"
11
+ targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler"
12
+ exporterVersion="2de5b0b" modeler:executionPlatform="Camunda Cloud"
13
+ modeler:executionPlatformVersion="8.9.0">
14
+ <bpmn:process id="ai-agent-chat-with-tools-gemini-vertex" name="AI Agent Chat With Tools Gemini Vertex"
15
+ isExecutable="true">
16
+ <bpmn:startEvent id="StartEvent_1">
17
+ <bpmn:extensionElements>
18
+ <zeebe:formDefinition formId="ai-agent-chat-initial-request" />
19
+ </bpmn:extensionElements>
20
+ <bpmn:outgoing>Flow_0pbzrme</bpmn:outgoing>
21
+ </bpmn:startEvent>
22
+ <bpmn:sequenceFlow id="Flow_0pbzrme" sourceRef="StartEvent_1" targetRef="Gateway_0z6ctwk" />
23
+ <bpmn:serviceTask id="AI_Agent" name="AI Agent"
24
+ zeebe:modelerTemplate="io.camunda.connectors.agenticai.ai-agent-task.v2"
25
+ zeebe:modelerTemplateVersion="1"
26
+ zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNBNTZFRkYiLz4KPG1hc2sgaWQ9InBhdGgtMi1vdXRzaWRlLTFfMTg1XzYiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjQiIHk9IjQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0iYmxhY2siPgo8cmVjdCBmaWxsPSJ3aGl0ZSIgeD0iNCIgeT0iNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjAuMDEwNSAxMi4wOTg3QzE4LjQ5IDEwLjU4OTQgMTcuMTU5NCA4LjEwODE0IDE2LjE3OTkgNi4wMTEwM0MxNi4xNTIgNi4wMDQ1MSAxNi4xMTc2IDYgMTYuMDc5NCA2QzE2LjA0MTEgNiAxNi4wMDY2IDYuMDA0NTEgMTUuOTc4OCA2LjAxMTA0QzE0Ljk5OTQgOC4xMDgxNCAxMy42Njk3IDEwLjU4ODkgMTIuMTQ4MSAxMi4wOTgxQzEwLjYyNjkgMTMuNjA3MSA4LjEyNTY4IDE0LjkyNjQgNi4wMTE1NyAxNS44OTgxQzYuMDA0NzQgMTUuOTI2MSA2IDE1Ljk2MTEgNiAxNkM2IDE2LjAzODcgNi4wMDQ2OCAxNi4wNzM2IDYuMDExNDQgMTYuMTAxNEM4LjEyNTE5IDE3LjA3MjkgMTAuNjI2MiAxOC4zOTE5IDEyLjE0NzcgMTkuOTAxNkMxMy42Njk3IDIxLjQxMDcgMTQuOTk5NiAyMy44OTIgMTUuOTc5MSAyNS45ODlDMTYuMDA2OCAyNS45OTU2IDE2LjA0MTEgMjYgMTYuMDc5MyAyNkMxNi4xMTc1IDI2IDE2LjE1MTkgMjUuOTk1NCAxNi4xNzk2IDI1Ljk4OUMxNy4xNTkxIDIzLjg5MiAxOC40ODg4IDIxLjQxMSAyMC4wMDk5IDE5LjkwMjFNMjAuMDA5OSAxOS45MDIxQzIxLjUyNTMgMTguMzk4NyAyMy45NDY1IDE3LjA2NjkgMjUuOTkxNSAxNi4wODI0QzI1Ljk5NjUgMTYuMDU5MyAyNiAxNi4wMzEgMjYgMTUuOTk5N0MyNiAxNS45Njg0IDI1Ljk5NjUgMTUuOTQwMyAyNS45OTE1IDE1LjkxNzFDMjMuOTQ3NCAxNC45MzI3IDIxLjUyNTkgMTMuNjAxIDIwLjAxMDUgMTIuMDk4NyIvPgo8L21hc2s+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjAuMDEwNSAxMi4wOTg3QzE4LjQ5IDEwLjU4OTQgMTcuMTU5NCA4LjEwODE0IDE2LjE3OTkgNi4wMTEwM0MxNi4xNTIgNi4wMDQ1MSAxNi4xMTc2IDYgMTYuMDc5NCA2QzE2LjA0MTEgNiAxNi4wMDY2IDYuMDA0NTEgMTUuOTc4OCA2LjAxMTA0QzE0Ljk5OTQgOC4xMDgxNCAxMy42Njk3IDEwLjU4ODkgMTIuMTQ4MSAxMi4wOTgxQzEwLjYyNjkgMTMuNjA3MSA4LjEyNTY4IDE0LjkyNjQgNi4wMTE1NyAxNS44OTgxQzYuMDA0NzQgMTUuOTI2MSA2IDE1Ljk2MTEgNiAxNkM2IDE2LjAzODcgNi4wMDQ2OCAxNi4wNzM2IDYuMDExNDQgMTYuMTAxNEM4LjEyNTE5IDE3LjA3MjkgMTAuNjI2MiAxOC4zOTE5IDEyLjE0NzcgMTkuOTAxNkMxMy42Njk3IDIxLjQxMDcgMTQuOTk5NiAyMy44OTIgMTUuOTc5MSAyNS45ODlDMTYuMDA2OCAyNS45OTU2IDE2LjA0MTEgMjYgMTYuMDc5MyAyNkMxNi4xMTc1IDI2IDE2LjE1MTkgMjUuOTk1NCAxNi4xNzk2IDI1Ljk4OUMxNy4xNTkxIDIzLjg5MiAxOC40ODg4IDIxLjQxMSAyMC4wMDk5IDE5LjkwMjFNMjAuMDA5OSAxOS45MDIxQzIxLjUyNTMgMTguMzk4NyAyMy45NDY1IDE3LjA2NjkgMjUuOTkxNSAxNi4wODI0QzI1Ljk5NjUgMTYuMDU5MyAyNiAxNi4wMzEgMjYgMTUuOTk5N0MyNiAxNS45Njg0IDI1Ljk5NjUgMTUuOTQwMyAyNS45OTE1IDE1LjkxNzFDMjMuOTQ3NCAxNC45MzI3IDIxLjUyNTkgMTMuNjAxIDIwLjAxMDUgMTIuMDk4NyIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMC4wMTA1IDEyLjA5ODdDMTguNDkgMTAuNTg5NCAxNy4xNTk0IDguMTA4MTQgMTYuMTc5OSA2LjAxMTAzQzE2LjE1MiA2LjAwNDUxIDE2LjExNzYgNiAxNi4wNzk0IDZDMTYuMDQxMSA2IDE2LjAwNjYgNi4wMDQ1MSAxNS45Nzg4IDYuMDExMDRDMTQuOTk5NCA4LjEwODE0IDEzLjY2OTcgMTAuNTg4OSAxMi4xNDgxIDEyLjA5ODFDMTAuNjI2OSAxMy42MDcxIDguMTI1NjggMTQuOTI2NCA2LjAxMTU3IDE1Ljg5ODFDNi4wMDQ3NCAxNS45MjYxIDYgMTUuOTYxMSA2IDE2QzYgMTYuMDM4NyA2LjAwNDY4IDE2LjA3MzYgNi4wMTE0NCAxNi4xMDE0QzguMTI1MTkgMTcuMDcyOSAxMC42MjYyIDE4LjM5MTkgMTIuMTQ3NyAxOS45MDE2QzEzLjY2OTcgMjEuNDEwNyAxNC45OTk2IDIzLjg5MiAxNS45NzkxIDI1Ljk4OUMxNi4wMDY4IDI1Ljk5NTYgMTYuMDQxMSAyNiAxNi4wNzkzIDI2QzE2LjExNzUgMjYgMTYuMTUxOSAyNS45OTU0IDE2LjE3OTYgMjUuOTg5QzE3LjE1OTEgMjMuODkyIDE4LjQ4ODggMjEuNDExIDIwLjAwOTkgMTkuOTAyMU0yMC4wMDk5IDE5LjkwMjFDMjEuNTI1MyAxOC4zOTg3IDIzLjk0NjUgMTcuMDY2OSAyNS45OTE1IDE2LjA4MjRDMjUuOTk2NSAxNi4wNTkzIDI2IDE2LjAzMSAyNiAxNS45OTk3QzI2IDE1Ljk2ODQgMjUuOTk2NSAxNS45NDAzIDI1Ljk5MTUgMTUuOTE3MUMyMy45NDc0IDE0LjkzMjcgMjEuNTI1OSAxMy42MDEgMjAuMDEwNSAxMi4wOTg3IiBzdHJva2U9IiM0OTFEOEIiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgbWFzaz0idXJsKCNwYXRoLTItb3V0c2lkZS0xXzE4NV82KSIvPgo8L3N2Zz4K">
27
+ <bpmn:extensionElements>
28
+ <zeebe:taskDefinition type="io.camunda.agenticai:aiagent:task:2" retries="3" />
29
+ <zeebe:ioMapping>
30
+ <zeebe:input source="google-gemini" target="provider.type" />
31
+ <zeebe:input source="google-vertex-ai" target="provider.googleGemini.backend.type" />
32
+ <zeebe:input source="{{secrets.IDP_GCP_VERTEX_PROJECT_ID}}"
33
+ target="provider.googleGemini.backend.googleVertexAi.projectId" />
34
+ <zeebe:input source="{{secrets.IDP_GCP_VERTEX_REGION}}"
35
+ target="provider.googleGemini.backend.googleVertexAi.region" />
36
+ <zeebe:input source="serviceAccountCredentials"
37
+ target="provider.googleGemini.backend.googleVertexAi.authentication.type" />
38
+ <zeebe:input source="{{secrets.IDP_GCP_SERVICE_ACCOUNT}}"
39
+ target="provider.googleGemini.backend.googleVertexAi.authentication.jsonKey" />
40
+ <zeebe:input source="gemini-2.5-pro"
41
+ target="provider.googleGemini.model.model" />
42
+ <zeebe:input
43
+ source="You are a helpful, generic chat agent which can answer a wide amount of questions based on your knowledge and an optional set of available tools.&#10;&#10;If tools are provided, you should prefer them instead of guessing an answer. You can call the same tool multiple times by providing different input values. Don&#39;t guess any tools which were not explicitely configured. If no tool matches the request, try to generate an answer. If you&#39;re not able to find a good answer, return with a message stating why you&#39;re not able to.&#10;&#10;If you are prompted to interact with a person, never guess contact details, but use available user/person lookup tools instead and return with an error if you&#39;re not able to look up appropriate data.&#10;&#10;Thinking, step by step, before you execute your tools, you think using the template `&#60;thinking&#62;&#60;context&#62;&#60;/context&#62;&#60;reflection&#62;&#60;/reflection&#62;&#60;/thinking&#62;`"
44
+ target="data.systemPrompt.prompt" />
45
+ <zeebe:input
46
+ source="=&#34;Generate a single sentence in the following exact format, using Paris, France as the city and country:&#10;&#10;The current date and time in {City, Country}, is approximately {h:mm AM/PM} on {Month day, year}.&#10;&#10;But only with the sentence/format as above, nothing else&#34;"
47
+ target="data.userPrompt.prompt" />
48
+ <zeebe:input
49
+ source="=if (is defined(followUpInput) or is defined(followUpDocuments)) then followUpDocuments else inputDocuments"
50
+ target="data.userPrompt.documents" />
51
+ <zeebe:input source="Agent_Tools" target="data.tools.containerElementId" />
52
+ <zeebe:input source="=toolCallResults" target="data.tools.toolCallResults" />
53
+ <zeebe:input source="=agent.context" target="data.context" />
54
+ <zeebe:input source="in-process" target="data.memory.storage.type" />
55
+ <zeebe:input source="=20" target="data.memory.contextWindowSize" />
56
+ <zeebe:input source="=10" target="data.limits.maxModelCalls" />
57
+ <zeebe:input source="text" target="data.response.format.type" />
58
+ <zeebe:input source="=false" target="data.response.format.parseJson" />
59
+ <zeebe:input source="=false" target="data.response.includeAssistantMessage" />
60
+ </zeebe:ioMapping>
61
+ <zeebe:taskHeaders>
62
+ <zeebe:header key="elementTemplateVersion" value="1" />
63
+ <zeebe:header key="elementTemplateId" value="io.camunda.connectors.agenticai.ai-agent-task.v2" />
64
+ <zeebe:header key="resultVariable" value="agent" />
65
+ <zeebe:header key="retryBackoff" value="PT2S" />
66
+ </zeebe:taskHeaders>
67
+ </bpmn:extensionElements>
68
+ <bpmn:incoming>Flow_050377t</bpmn:incoming>
69
+ <bpmn:outgoing>Flow_041ffce</bpmn:outgoing>
70
+ </bpmn:serviceTask>
71
+ <bpmn:exclusiveGateway id="Gateway_0z6ctwk">
72
+ <bpmn:incoming>Flow_0pbzrme</bpmn:incoming>
73
+ <bpmn:incoming>Flow_01k9dy1</bpmn:incoming>
74
+ <bpmn:incoming>Flow_19gp461</bpmn:incoming>
75
+ <bpmn:outgoing>Flow_050377t</bpmn:outgoing>
76
+ </bpmn:exclusiveGateway>
77
+ <bpmn:userTask id="User_Feedback" name="User Feedback">
78
+ <bpmn:extensionElements>
79
+ <zeebe:userTask />
80
+ <zeebe:formDefinition formId="ai-agent-chat-user-feedback" />
81
+ </bpmn:extensionElements>
82
+ <bpmn:incoming>Flow_11y3kim</bpmn:incoming>
83
+ <bpmn:outgoing>Flow_09y08ef</bpmn:outgoing>
84
+ </bpmn:userTask>
85
+ <bpmn:exclusiveGateway id="Gateway_1dcg4ha" name="User satisfied?">
86
+ <bpmn:incoming>Flow_09y08ef</bpmn:incoming>
87
+ <bpmn:outgoing>Flow_19gp461</bpmn:outgoing>
88
+ <bpmn:outgoing>Flow_16c9bwj</bpmn:outgoing>
89
+ </bpmn:exclusiveGateway>
90
+ <bpmn:sequenceFlow id="Flow_09y08ef" sourceRef="User_Feedback" targetRef="Gateway_1dcg4ha" />
91
+ <bpmn:sequenceFlow id="Flow_19gp461" name="no - we follow up" sourceRef="Gateway_1dcg4ha"
92
+ targetRef="Gateway_0z6ctwk">
93
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=userSatisfied = null or
94
+ userSatisfied = false</bpmn:conditionExpression>
95
+ </bpmn:sequenceFlow>
96
+ <bpmn:endEvent id="Event_0i39jej">
97
+ <bpmn:incoming>Flow_16c9bwj</bpmn:incoming>
98
+ </bpmn:endEvent>
99
+ <bpmn:sequenceFlow id="Flow_16c9bwj" name="yes" sourceRef="Gateway_1dcg4ha"
100
+ targetRef="Event_0i39jej">
101
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=userSatisfied</bpmn:conditionExpression>
102
+ </bpmn:sequenceFlow>
103
+ <bpmn:sequenceFlow id="Flow_041ffce" sourceRef="AI_Agent" targetRef="Gateway_0bukj01" />
104
+ <bpmn:exclusiveGateway id="Gateway_0bukj01" name="Includes tool calls?">
105
+ <bpmn:incoming>Flow_041ffce</bpmn:incoming>
106
+ <bpmn:outgoing>Flow_00lg7l2</bpmn:outgoing>
107
+ <bpmn:outgoing>Flow_11y3kim</bpmn:outgoing>
108
+ </bpmn:exclusiveGateway>
109
+ <bpmn:adHocSubProcess id="Agent_Tools" name="Agent Tools">
110
+ <bpmn:extensionElements>
111
+ <zeebe:adHoc activeElementsCollection="=[toolCall._meta.name]" />
112
+ </bpmn:extensionElements>
113
+ <bpmn:incoming>Flow_00lg7l2</bpmn:incoming>
114
+ <bpmn:outgoing>Flow_01k9dy1</bpmn:outgoing>
115
+ <bpmn:multiInstanceLoopCharacteristics>
116
+ <bpmn:extensionElements>
117
+ <zeebe:loopCharacteristics inputCollection="=agent.toolCalls" inputElement="toolCall"
118
+ outputCollection="toolCallResults"
119
+ outputElement="={&#10; id: toolCall._meta.id,&#10; name: toolCall._meta.name,&#10; content: toolCallResult&#10;}" />
120
+ </bpmn:extensionElements>
121
+ </bpmn:multiInstanceLoopCharacteristics>
122
+ <bpmn:scriptTask id="GetDateAndTime" name="Get Date and Time">
123
+ <bpmn:documentation>Returns the current date and time including the timezone.</bpmn:documentation>
124
+ <bpmn:extensionElements>
125
+ <zeebe:script expression="=now()" resultVariable="toolCallResult" />
126
+ </bpmn:extensionElements>
127
+ </bpmn:scriptTask>
128
+ <bpmn:serviceTask id="Search_Recipe" name="Search recipe"
129
+ zeebe:modelerTemplate="io.camunda.connectors.HttpJson.v2" zeebe:modelerTemplateVersion="10"
130
+ zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHZpZXdCb3g9IjAgMCAxOCAxOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE3LjAzMzUgOC45OTk5N0MxNy4wMzM1IDEzLjQ0NzUgMTMuNDI4MSAxNy4wNTI5IDguOTgwNjUgMTcuMDUyOUM0LjUzMzE2IDE3LjA1MjkgMC45Mjc3NjUgMTMuNDQ3NSAwLjkyNzc2NSA4Ljk5OTk3QzAuOTI3NzY1IDQuNTUyNDggNC41MzMxNiAwLjk0NzA4MyA4Ljk4MDY1IDAuOTQ3MDgzQzEzLjQyODEgMC45NDcwODMgMTcuMDMzNSA0LjU1MjQ4IDE3LjAzMzUgOC45OTk5N1oiIGZpbGw9IiM1MDU1NjIiLz4KPHBhdGggZD0iTTQuOTMxMjYgMTQuMTU3MUw2Ljc4MTA2IDMuNzE0NzFIMTAuMTM3NUMxMS4xOTE3IDMuNzE0NzEgMTEuOTgyNCAzLjk4MzIzIDEyLjUwOTUgNC41MjAyN0MxMy4wNDY1IDUuMDQ3MzYgMTMuMzE1IDUuNzMzNTggMTMuMzE1IDYuNTc4OTJDMTMuMzE1IDcuNDQ0MTQgMTMuMDcxNCA4LjE1NTIyIDEyLjU4NDEgOC43MTIxNUMxMi4xMDY3IDkuMjU5MTMgMTEuNDU1MyA5LjYzNzA1IDEwLjYyOTggOS44NDU5TDEyLjA2MTkgMTQuMTU3MUgxMC4zMzE1TDkuMDMzNjQgMTAuMDI0OUg3LjI0MzUxTDYuNTEyNTQgMTQuMTU3MUg0LjkzMTI2Wk03LjQ5NzExIDguNTkyODFIOS4yNDI0OEM5Ljk5ODMyIDguNTkyODEgMTAuNTkwMSA4LjQyMzc0IDExLjAxNzcgOC4wODU2MUMxMS40NTUzIDcuNzM3NTMgMTEuNjc0MSA3LjI2NTEzIDExLjY3NDEgNi42Njg0MkMxMS42NzQxIDYuMTkxMDYgMTEuNTI0OSA1LjgxODExIDExLjIyNjUgNS41NDk1OUMxMC45MjgyIDUuMjcxMTMgMTAuNDU1OCA1LjEzMTkgOS44MDkzNiA1LjEzMTlIOC4xMDg3NEw3LjQ5NzExIDguNTkyODFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K">
131
+ <bpmn:documentation>Searches a recipe given a search query</bpmn:documentation>
132
+ <bpmn:extensionElements>
133
+ <zeebe:taskDefinition type="io.camunda:http-json:1" retries="3" />
134
+ <zeebe:ioMapping>
135
+ <zeebe:input source="noAuth" target="authentication.type" />
136
+ <zeebe:input source="GET" target="method" />
137
+ <zeebe:input source="https://dummyjson.com/recipes/search" target="url" />
138
+ <zeebe:input
139
+ source="={&#10; q: fromAi(toolCall.searchQuery, &#34;The query describing which recipe to search (e.g. a specific dish or the cuisine).&#34;)&#10;}"
140
+ target="queryParameters" />
141
+ <zeebe:input source="=false" target="storeResponse" />
142
+ <zeebe:input source="20" target="connectionTimeoutInSeconds" />
143
+ <zeebe:input source="20" target="readTimeoutInSeconds" />
144
+ <zeebe:input source="=false" target="ignoreNullValues" />
145
+ </zeebe:ioMapping>
146
+ <zeebe:taskHeaders>
147
+ <zeebe:header key="resultExpression"
148
+ value="={&#10; toolCallResult: if (count(response.body.recipes) &#62; 0) then response.body.recipes else &#34;No result found.&#34;&#10;}" />
149
+ <zeebe:header key="retryBackoff" value="PT0S" />
150
+ </zeebe:taskHeaders>
151
+ </bpmn:extensionElements>
152
+ </bpmn:serviceTask>
153
+ <bpmn:scriptTask id="SuperfluxProduct" name="Superflux Product Calculation">
154
+ <bpmn:documentation>Calculates the superflux product (a very complicated method only this
155
+ tool can do) given two input numbers</bpmn:documentation>
156
+ <bpmn:extensionElements>
157
+ <zeebe:script expression="=3 * (inputA + inputB)" resultVariable="toolCallResult" />
158
+ <zeebe:ioMapping>
159
+ <zeebe:input
160
+ source="=fromAi(toolCall.a, &#34;The first number to be superflux calculated.&#34;, &#34;number&#34;)"
161
+ target="inputA" />
162
+ <zeebe:input
163
+ source="=fromAi(toolCall.b, &#34;The second number to be superflux calculated.&#34;, &#34;number&#34;)"
164
+ target="inputB" />
165
+ </zeebe:ioMapping>
166
+ </bpmn:extensionElements>
167
+ </bpmn:scriptTask>
168
+ <bpmn:userTask id="AskHumanToSendEmail" name="Ask human to send email">
169
+ <bpmn:documentation>Ask a human to send an email for you</bpmn:documentation>
170
+ <bpmn:extensionElements>
171
+ <zeebe:userTask />
172
+ <zeebe:formDefinition formId="ai-agent-chat-human-send-email-request" />
173
+ <zeebe:ioMapping>
174
+ <zeebe:input
175
+ source="=fromAi(toolCall.instructions, &#34;Instructions for the human to follow when sending the email, including background of the email.&#34;)"
176
+ target="instructions" />
177
+ <zeebe:input
178
+ source="=fromAi(toolCall.recipient_name, &#34;The recipient&#39;s full name.&#34;)"
179
+ target="recipient_name" />
180
+ <zeebe:input
181
+ source="=fromAi(toolCall.recipient_email, &#34;The the recipient&#39;s email address.&#34;)"
182
+ target="recipient_email" />
183
+ <zeebe:input
184
+ source="=fromAi(toolCall.email_subject, &#34;The subject of the email.&#34;)"
185
+ target="email_subject" />
186
+ <zeebe:input source="=fromAi(toolCall.email_body, &#34;The body of the email.&#34;)"
187
+ target="email_body" />
188
+ <zeebe:output
189
+ source="={&#10; operatorFeedback: operatorFeedback,&#10; emailOk: emailOk&#10;}"
190
+ target="toolCallResult" />
191
+ </zeebe:ioMapping>
192
+ </bpmn:extensionElements>
193
+ <bpmn:outgoing>Flow_0demz1g</bpmn:outgoing>
194
+ </bpmn:userTask>
195
+ <bpmn:sequenceFlow id="Flow_0demz1g" sourceRef="AskHumanToSendEmail"
196
+ targetRef="Gateway_1lux75t" />
197
+ <bpmn:exclusiveGateway id="Gateway_1lux75t" name="OK to send email?">
198
+ <bpmn:incoming>Flow_0demz1g</bpmn:incoming>
199
+ <bpmn:outgoing>Flow_0uqjclh</bpmn:outgoing>
200
+ <bpmn:outgoing>Flow_1l2ws6w</bpmn:outgoing>
201
+ </bpmn:exclusiveGateway>
202
+ <bpmn:sequenceFlow id="Flow_0uqjclh" name="yes" sourceRef="Gateway_1lux75t"
203
+ targetRef="SendEmail">
204
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=toolCallResult.emailOk</bpmn:conditionExpression>
205
+ </bpmn:sequenceFlow>
206
+ <bpmn:sequenceFlow id="Flow_1l2ws6w" name="no" sourceRef="Gateway_1lux75t"
207
+ targetRef="Event_1wxfv4u">
208
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=toolCallResult.emailOk != true</bpmn:conditionExpression>
209
+ </bpmn:sequenceFlow>
210
+ <bpmn:intermediateThrowEvent id="Event_1wxfv4u" name="loop back with feedback">
211
+ <bpmn:incoming>Flow_1l2ws6w</bpmn:incoming>
212
+ </bpmn:intermediateThrowEvent>
213
+ <bpmn:scriptTask id="SendEmail" name="Send email">
214
+ <bpmn:extensionElements>
215
+ <zeebe:script expression="=true" resultVariable="emailSent" />
216
+ <zeebe:ioMapping>
217
+ <zeebe:output source="=emailSent" target="toolCallResult.emailSent" />
218
+ </zeebe:ioMapping>
219
+ </bpmn:extensionElements>
220
+ <bpmn:incoming>Flow_0uqjclh</bpmn:incoming>
221
+ </bpmn:scriptTask>
222
+ </bpmn:adHocSubProcess>
223
+ <bpmn:sequenceFlow id="Flow_00lg7l2" name="yes" sourceRef="Gateway_0bukj01"
224
+ targetRef="Agent_Tools">
225
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=not(is empty(agent.toolCalls))</bpmn:conditionExpression>
226
+ </bpmn:sequenceFlow>
227
+ <bpmn:sequenceFlow id="Flow_11y3kim" name="no" sourceRef="Gateway_0bukj01"
228
+ targetRef="User_Feedback">
229
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=is empty(agent.toolCalls)</bpmn:conditionExpression>
230
+ </bpmn:sequenceFlow>
231
+ <bpmn:sequenceFlow id="Flow_050377t" sourceRef="Gateway_0z6ctwk" targetRef="AI_Agent" />
232
+ <bpmn:sequenceFlow id="Flow_01k9dy1" sourceRef="Agent_Tools" targetRef="Gateway_0z6ctwk" />
233
+ <bpmn:textAnnotation id="TextAnnotation_0rg9ar3">
234
+ <bpmn:text>Rough outline of the functionality
235
+
236
+ - Loads previous agent context (conversation, metrics, ...)
237
+ - Loads available tool information from ad-hoc sub-process definition
238
+ - Resolves tool information from gateway tool definitions such as MCP
239
+ - Checks limits (e.g. maximum LLM model calls)
240
+ - Merges the current request (either a user message or a tool call response) into the memory
241
+ - Calls the LLM, including previous/edited memory (limited to max amount of messages) +
242
+ available tools schema
243
+ - Returns last response as text or JSON format, depending on the configuration
244
+ - Returns tools to call, including their parameters</bpmn:text>
245
+ </bpmn:textAnnotation>
246
+ <bpmn:association id="Association_0ic98nl" associationDirection="None" sourceRef="AI_Agent"
247
+ targetRef="TextAnnotation_0rg9ar3" />
248
+ <bpmn:textAnnotation id="TextAnnotation_1keavvi">
249
+ <bpmn:text>For every tool call in &lt;agent.toolCalls&gt;</bpmn:text>
250
+ </bpmn:textAnnotation>
251
+ <bpmn:association id="Association_0q5n90x" associationDirection="None" sourceRef="Agent_Tools"
252
+ targetRef="TextAnnotation_1keavvi" />
253
+ <bpmn:textAnnotation id="TextAnnotation_1cvjkfu">
254
+ <bpmn:text>Every execution (flow node or sequence of flow nodes) MUST write
255
+ &lt;toolCallResult&gt; variable</bpmn:text>
256
+ </bpmn:textAnnotation>
257
+ <bpmn:textAnnotation id="TextAnnotation_1tvejhg">
258
+ <bpmn:text>Every task inside of an execution MAY query for external inputs provided by the
259
+ model through the fromAI helper:
260
+
261
+ fromAi(toolCall.id, "The user ID", "number")
262
+
263
+ The outside brain &lt;AI Agent&gt; will take that information to instruct the model which
264
+ data to provide in which format.</bpmn:text>
265
+ </bpmn:textAnnotation>
266
+ <bpmn:textAnnotation id="TextAnnotation_0xt28ql">
267
+ <bpmn:text>Must produce output as &lt;toolCallResults=[ { id, name, content } ]&gt;</bpmn:text>
268
+ </bpmn:textAnnotation>
269
+ <bpmn:association id="Association_14t02ll" associationDirection="None" sourceRef="Agent_Tools"
270
+ targetRef="TextAnnotation_0xt28ql" />
271
+ </bpmn:process>
272
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
273
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ai-agent-chat-with-tools-gemini-vertex">
274
+ <bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
275
+ <dc:Bounds x="152" y="442" width="36" height="36" />
276
+ </bpmndi:BPMNShape>
277
+ <bpmndi:BPMNShape id="Activity_0xj2598_di" bpmnElement="AI_Agent" bioc:stroke="#205022"
278
+ bioc:fill="#c8e6c9" color:background-color="#c8e6c9" color:border-color="#205022">
279
+ <dc:Bounds x="340" y="420" width="100" height="80" />
280
+ <bpmndi:BPMNLabel />
281
+ </bpmndi:BPMNShape>
282
+ <bpmndi:BPMNShape id="Gateway_0z6ctwk_di" bpmnElement="Gateway_0z6ctwk" isMarkerVisible="true">
283
+ <dc:Bounds x="245" y="435" width="50" height="50" />
284
+ </bpmndi:BPMNShape>
285
+ <bpmndi:BPMNShape id="Activity_1fam9db_di" bpmnElement="User_Feedback">
286
+ <dc:Bounds x="640" y="420" width="100" height="80" />
287
+ <bpmndi:BPMNLabel />
288
+ </bpmndi:BPMNShape>
289
+ <bpmndi:BPMNShape id="Gateway_1dcg4ha_di" bpmnElement="Gateway_1dcg4ha" isMarkerVisible="true">
290
+ <dc:Bounds x="805" y="435" width="50" height="50" />
291
+ <bpmndi:BPMNLabel>
292
+ <dc:Bounds x="794" y="492" width="73" height="14" />
293
+ </bpmndi:BPMNLabel>
294
+ </bpmndi:BPMNShape>
295
+ <bpmndi:BPMNShape id="Event_0i39jej_di" bpmnElement="Event_0i39jej">
296
+ <dc:Bounds x="912" y="442" width="36" height="36" />
297
+ </bpmndi:BPMNShape>
298
+ <bpmndi:BPMNShape id="Gateway_0bukj01_di" bpmnElement="Gateway_0bukj01" isMarkerVisible="true">
299
+ <dc:Bounds x="505" y="435" width="50" height="50" />
300
+ <bpmndi:BPMNLabel>
301
+ <dc:Bounds x="499" y="406" width="62" height="27" />
302
+ </bpmndi:BPMNLabel>
303
+ </bpmndi:BPMNShape>
304
+ <bpmndi:BPMNShape id="Activity_03yngb7_di" bpmnElement="Agent_Tools" isExpanded="true"
305
+ bioc:stroke="#6b3c00" bioc:fill="#ffe0b2" color:background-color="#ffe0b2"
306
+ color:border-color="#6b3c00">
307
+ <dc:Bounds x="640" y="560" width="400" height="360" />
308
+ </bpmndi:BPMNShape>
309
+ <bpmndi:BPMNShape id="Activity_1sbkoqq_di" bpmnElement="GetDateAndTime">
310
+ <dc:Bounds x="670" y="600" width="100" height="80" />
311
+ <bpmndi:BPMNLabel />
312
+ </bpmndi:BPMNShape>
313
+ <bpmndi:BPMNShape id="Activity_0d8luif_di" bpmnElement="Search_Recipe">
314
+ <dc:Bounds x="920" y="600" width="100" height="80" />
315
+ <bpmndi:BPMNLabel />
316
+ </bpmndi:BPMNShape>
317
+ <bpmndi:BPMNShape id="BPMNShape_0x0a1hy" bpmnElement="SuperfluxProduct">
318
+ <dc:Bounds x="790" y="600" width="100" height="80" />
319
+ <bpmndi:BPMNLabel />
320
+ </bpmndi:BPMNShape>
321
+ <bpmndi:BPMNShape id="Activity_16uhg8o_di" bpmnElement="AskHumanToSendEmail">
322
+ <dc:Bounds x="670" y="730" width="100" height="80" />
323
+ <bpmndi:BPMNLabel />
324
+ </bpmndi:BPMNShape>
325
+ <bpmndi:BPMNShape id="Gateway_1lux75t_di" bpmnElement="Gateway_1lux75t" isMarkerVisible="true">
326
+ <dc:Bounds x="815" y="745" width="50" height="50" />
327
+ <bpmndi:BPMNLabel>
328
+ <dc:Bounds x="812" y="716" width="56" height="27" />
329
+ </bpmndi:BPMNLabel>
330
+ </bpmndi:BPMNShape>
331
+ <bpmndi:BPMNShape id="Event_1ny5xkz_di" bpmnElement="Event_1wxfv4u">
332
+ <dc:Bounds x="822" y="832" width="36" height="36" />
333
+ <bpmndi:BPMNLabel>
334
+ <dc:Bounds x="805" y="875" width="70" height="27" />
335
+ </bpmndi:BPMNLabel>
336
+ </bpmndi:BPMNShape>
337
+ <bpmndi:BPMNShape id="Activity_1sddc2g_di" bpmnElement="SendEmail">
338
+ <dc:Bounds x="910" y="730" width="100" height="80" />
339
+ </bpmndi:BPMNShape>
340
+ <bpmndi:BPMNEdge id="Flow_0demz1g_di" bpmnElement="Flow_0demz1g">
341
+ <di:waypoint x="770" y="770" />
342
+ <di:waypoint x="815" y="770" />
343
+ </bpmndi:BPMNEdge>
344
+ <bpmndi:BPMNEdge id="Flow_0uqjclh_di" bpmnElement="Flow_0uqjclh">
345
+ <di:waypoint x="865" y="770" />
346
+ <di:waypoint x="910" y="770" />
347
+ <bpmndi:BPMNLabel>
348
+ <dc:Bounds x="879" y="752" width="18" height="14" />
349
+ </bpmndi:BPMNLabel>
350
+ </bpmndi:BPMNEdge>
351
+ <bpmndi:BPMNEdge id="Flow_1l2ws6w_di" bpmnElement="Flow_1l2ws6w">
352
+ <di:waypoint x="840" y="795" />
353
+ <di:waypoint x="840" y="832" />
354
+ <bpmndi:BPMNLabel>
355
+ <dc:Bounds x="849" y="803" width="13" height="14" />
356
+ </bpmndi:BPMNLabel>
357
+ </bpmndi:BPMNEdge>
358
+ <bpmndi:BPMNShape id="TextAnnotation_0rg9ar3_di" bpmnElement="TextAnnotation_0rg9ar3">
359
+ <dc:Bounds x="401" y="80" width="578" height="170" />
360
+ <bpmndi:BPMNLabel />
361
+ </bpmndi:BPMNShape>
362
+ <bpmndi:BPMNShape id="TextAnnotation_1keavvi_di" bpmnElement="TextAnnotation_1keavvi">
363
+ <dc:Bounds x="1080" y="510" width="240" height="26" />
364
+ <bpmndi:BPMNLabel />
365
+ </bpmndi:BPMNShape>
366
+ <bpmndi:BPMNShape id="TextAnnotation_1cvjkfu_di" bpmnElement="TextAnnotation_1cvjkfu">
367
+ <dc:Bounds x="1210" y="660" width="260" height="60" />
368
+ <bpmndi:BPMNLabel />
369
+ </bpmndi:BPMNShape>
370
+ <bpmndi:BPMNShape id="TextAnnotation_1tvejhg_di" bpmnElement="TextAnnotation_1tvejhg">
371
+ <dc:Bounds x="1210" y="740" width="286" height="142" />
372
+ <bpmndi:BPMNLabel />
373
+ </bpmndi:BPMNShape>
374
+ <bpmndi:BPMNShape id="TextAnnotation_0xt28ql_di" bpmnElement="TextAnnotation_0xt28ql">
375
+ <dc:Bounds x="1168" y="920" width="370" height="26" />
376
+ <bpmndi:BPMNLabel />
377
+ </bpmndi:BPMNShape>
378
+ <bpmndi:BPMNEdge id="Flow_0pbzrme_di" bpmnElement="Flow_0pbzrme">
379
+ <di:waypoint x="188" y="460" />
380
+ <di:waypoint x="245" y="460" />
381
+ </bpmndi:BPMNEdge>
382
+ <bpmndi:BPMNEdge id="Flow_09y08ef_di" bpmnElement="Flow_09y08ef">
383
+ <di:waypoint x="740" y="460" />
384
+ <di:waypoint x="805" y="460" />
385
+ </bpmndi:BPMNEdge>
386
+ <bpmndi:BPMNEdge id="Flow_19gp461_di" bpmnElement="Flow_19gp461">
387
+ <di:waypoint x="830" y="435" />
388
+ <di:waypoint x="830" y="350" />
389
+ <di:waypoint x="270" y="350" />
390
+ <di:waypoint x="270" y="435" />
391
+ <bpmndi:BPMNLabel>
392
+ <dc:Bounds x="748" y="333" width="83" height="14" />
393
+ </bpmndi:BPMNLabel>
394
+ </bpmndi:BPMNEdge>
395
+ <bpmndi:BPMNEdge id="Flow_16c9bwj_di" bpmnElement="Flow_16c9bwj">
396
+ <di:waypoint x="855" y="460" />
397
+ <di:waypoint x="912" y="460" />
398
+ <bpmndi:BPMNLabel>
399
+ <dc:Bounds x="875" y="442" width="18" height="14" />
400
+ </bpmndi:BPMNLabel>
401
+ </bpmndi:BPMNEdge>
402
+ <bpmndi:BPMNEdge id="Flow_041ffce_di" bpmnElement="Flow_041ffce">
403
+ <di:waypoint x="440" y="460" />
404
+ <di:waypoint x="505" y="460" />
405
+ </bpmndi:BPMNEdge>
406
+ <bpmndi:BPMNEdge id="Flow_00lg7l2_di" bpmnElement="Flow_00lg7l2">
407
+ <di:waypoint x="530" y="485" />
408
+ <di:waypoint x="530" y="850" />
409
+ <di:waypoint x="640" y="850" />
410
+ <bpmndi:BPMNLabel>
411
+ <dc:Bounds x="541" y="492" width="18" height="14" />
412
+ </bpmndi:BPMNLabel>
413
+ </bpmndi:BPMNEdge>
414
+ <bpmndi:BPMNEdge id="Flow_11y3kim_di" bpmnElement="Flow_11y3kim">
415
+ <di:waypoint x="555" y="460" />
416
+ <di:waypoint x="640" y="460" />
417
+ <bpmndi:BPMNLabel>
418
+ <dc:Bounds x="591" y="442" width="13" height="14" />
419
+ </bpmndi:BPMNLabel>
420
+ </bpmndi:BPMNEdge>
421
+ <bpmndi:BPMNEdge id="Flow_050377t_di" bpmnElement="Flow_050377t">
422
+ <di:waypoint x="295" y="460" />
423
+ <di:waypoint x="340" y="460" />
424
+ </bpmndi:BPMNEdge>
425
+ <bpmndi:BPMNEdge id="Flow_01k9dy1_di" bpmnElement="Flow_01k9dy1">
426
+ <di:waypoint x="1040" y="850" />
427
+ <di:waypoint x="1150" y="850" />
428
+ <di:waypoint x="1150" y="950" />
429
+ <di:waypoint x="270" y="950" />
430
+ <di:waypoint x="270" y="485" />
431
+ </bpmndi:BPMNEdge>
432
+ <bpmndi:BPMNEdge id="Association_0ic98nl_di" bpmnElement="Association_0ic98nl">
433
+ <di:waypoint x="410" y="420" />
434
+ <di:waypoint x="495" y="250" />
435
+ </bpmndi:BPMNEdge>
436
+ <bpmndi:BPMNEdge id="Association_0q5n90x_di" bpmnElement="Association_0q5n90x">
437
+ <di:waypoint x="1040" y="620" />
438
+ <di:waypoint x="1120" y="536" />
439
+ </bpmndi:BPMNEdge>
440
+ <bpmndi:BPMNEdge id="Association_14t02ll_di" bpmnElement="Association_14t02ll">
441
+ <di:waypoint x="1040" y="902" />
442
+ <di:waypoint x="1160" y="933" />
443
+ </bpmndi:BPMNEdge>
444
+ </bpmndi:BPMNPlane>
445
+ </bpmndi:BPMNDiagram>
446
+ </bpmn:definitions>