Skip to content

Commit fbfc2c5

Browse files
committed
test: verify hierarchical outputs scope / agentic case
1 parent 0a1c60b commit fbfc2c5

File tree

2 files changed

+221
-0
lines changed

2 files changed

+221
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_18jxukq" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.44.0-dev" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.9.0">
3+
<bpmn:process id="ai-agent-chat-with-tools" name="AI Agent Chat With Tools" isExecutable="true">
4+
<bpmn:adHocSubProcess id="AI_Agent" name="AI Agent">
5+
<bpmn:extensionElements>
6+
<zeebe:adHoc outputCollection="toolCallResults" outputElement="={&#10; id: toolCall._meta.id,&#10; name: toolCall._meta.name,&#10; content: toolCallResult&#10;}" />
7+
<zeebe:taskDefinition type="io.camunda.agenticai:aiagent-job-worker:1" retries="3" />
8+
<zeebe:ioMapping>
9+
<zeebe:input source="bedrock" target="provider.type" />
10+
<zeebe:input target="toolCallResult" />
11+
<zeebe:input target="toolCallResults" />
12+
<zeebe:input source="eu-central-1" target="provider.bedrock.region" />
13+
<zeebe:input source="credentials" target="provider.bedrock.authentication.type" />
14+
<zeebe:input source="{{secrets.AWS_BEDROCK_ACCESS_KEY}}" target="provider.bedrock.authentication.accessKey" />
15+
<zeebe:input source="{{secrets.AWS_BEDROCK_SECRET_KEY}}" target="provider.bedrock.authentication.secretKey" />
16+
<zeebe:input source="eu.anthropic.claude-sonnet-4-5-20250929-v1:0" target="provider.bedrock.model.model" />
17+
<zeebe:input source="=&#34;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;`&#34;" target="data.systemPrompt.prompt" />
18+
<zeebe:input source="=if (is defined(followUpInput)) then followUpInput else inputText" target="data.userPrompt.prompt" />
19+
<zeebe:input source="=if (is defined(followUpInput) or is defined(followUpDocuments)) then followUpDocuments else inputDocuments" target="data.userPrompt.documents" />
20+
<zeebe:input source="=agent.context" target="agentContext" />
21+
<zeebe:input source="in-process" target="data.memory.storage.type" />
22+
<zeebe:input source="=20" target="data.memory.contextWindowSize" />
23+
<zeebe:input source="=20" target="data.limits.maxModelCalls" />
24+
<zeebe:input source="WAIT_FOR_TOOL_CALL_RESULTS" target="data.events.behavior" />
25+
<zeebe:input source="text" target="data.response.format.type" />
26+
<zeebe:input source="=false" target="data.response.format.parseJson" />
27+
<zeebe:input source="=false" target="data.response.includeAssistantMessage" />
28+
<zeebe:input source="=true" target="data.response.includeAgentContext" />
29+
<zeebe:output source="=agent" target="agent" />
30+
</zeebe:ioMapping>
31+
<zeebe:taskHeaders>
32+
<zeebe:header key="elementTemplateVersion" value="6" />
33+
<zeebe:header key="elementTemplateId" value="io.camunda.connectors.agenticai.aiagent.jobworker.v1" />
34+
<zeebe:header key="retryBackoff" value="PT0S" />
35+
</zeebe:taskHeaders>
36+
</bpmn:extensionElements>
37+
<bpmn:scriptTask id="GetDateAndTime" name="Get Date and Time">
38+
<bpmn:documentation>Returns the current date and time including the timezone.</bpmn:documentation>
39+
<bpmn:extensionElements>
40+
<zeebe:script expression="=now()" resultVariable="toolCallResult" />
41+
</bpmn:extensionElements>
42+
</bpmn:scriptTask>
43+
<bpmn:userTask id="AskHumanToSendEmail" name="Ask human to send email">
44+
<bpmn:documentation>Ask a human to send an email for you</bpmn:documentation>
45+
<bpmn:extensionElements>
46+
<zeebe:userTask />
47+
<zeebe:formDefinition formId="ai-agent-chat-human-send-email-request" />
48+
<zeebe:ioMapping>
49+
<zeebe:input source="=fromAi(toolCall.instructions, &#34;Instructions for the human to follow when sending the email, including background of the email.&#34;)" target="instructions" />
50+
<zeebe:input source="=fromAi(toolCall.recipient_name, &#34;The recipient&#39;s full name.&#34;)" target="recipient_name" />
51+
<zeebe:input source="=fromAi(toolCall.recipient_email, &#34;The the recipient&#39;s email address.&#34;)" target="recipient_email" />
52+
<zeebe:input source="=fromAi(toolCall.email_subject, &#34;The subject of the email.&#34;)" target="email_subject" />
53+
<zeebe:input source="=fromAi(toolCall.email_body, &#34;The body of the email.&#34;)" target="email_body" />
54+
<zeebe:output source="={&#10; operatorFeedback: operatorFeedback,&#10; emailOk: emailOk&#10;}" target="toolCallResult" />
55+
</zeebe:ioMapping>
56+
</bpmn:extensionElements>
57+
<bpmn:outgoing>Flow_0demz1g</bpmn:outgoing>
58+
</bpmn:userTask>
59+
<bpmn:sequenceFlow id="Flow_0demz1g" sourceRef="AskHumanToSendEmail" targetRef="Gateway_1lux75t" />
60+
<bpmn:exclusiveGateway id="Gateway_1lux75t" name="OK to send email?">
61+
<bpmn:incoming>Flow_0demz1g</bpmn:incoming>
62+
<bpmn:outgoing>Flow_0uqjclh</bpmn:outgoing>
63+
<bpmn:outgoing>Flow_1l2ws6w</bpmn:outgoing>
64+
</bpmn:exclusiveGateway>
65+
<bpmn:sequenceFlow id="Flow_0uqjclh" name="yes" sourceRef="Gateway_1lux75t" targetRef="SendEmail">
66+
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=toolCallResult.emailOk</bpmn:conditionExpression>
67+
</bpmn:sequenceFlow>
68+
<bpmn:sequenceFlow id="Flow_1l2ws6w" name="no" sourceRef="Gateway_1lux75t" targetRef="Event_1wxfv4u">
69+
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=toolCallResult.emailOk != true</bpmn:conditionExpression>
70+
</bpmn:sequenceFlow>
71+
<bpmn:intermediateThrowEvent id="Event_1wxfv4u" name="loop back with feedback">
72+
<bpmn:incoming>Flow_1l2ws6w</bpmn:incoming>
73+
</bpmn:intermediateThrowEvent>
74+
<bpmn:scriptTask id="SendEmail" name="Send email">
75+
<bpmn:extensionElements>
76+
<zeebe:script expression="=true" resultVariable="emailSent" />
77+
<zeebe:ioMapping>
78+
<zeebe:output source="=emailSent" target="toolCallResult.emailSent" />
79+
</zeebe:ioMapping>
80+
</bpmn:extensionElements>
81+
<bpmn:incoming>Flow_0uqjclh</bpmn:incoming>
82+
</bpmn:scriptTask>
83+
<bpmn:subProcess id="Event_Sub_Process" triggeredByEvent="true">
84+
<bpmn:scriptTask id="Handle_Message" name="Handle message">
85+
<bpmn:extensionElements>
86+
<zeebe:script expression="=&#34;Updated message from event: &#34; + messageFromEvent" resultVariable="toolCallResult" />
87+
</bpmn:extensionElements>
88+
<bpmn:incoming>Flow_0kd4go1</bpmn:incoming>
89+
</bpmn:scriptTask>
90+
<bpmn:sequenceFlow id="Flow_0kd4go1" sourceRef="On_Message" targetRef="Handle_Message" />
91+
<bpmn:startEvent id="On_Message" isInterrupting="false">
92+
<bpmn:outgoing>Flow_0kd4go1</bpmn:outgoing>
93+
<bpmn:messageEventDefinition id="MessageEventDefinition_0l1ft5s" messageRef="Message_3mpc025" />
94+
</bpmn:startEvent>
95+
</bpmn:subProcess>
96+
</bpmn:adHocSubProcess>
97+
</bpmn:process>
98+
<bpmn:message id="Message_3mpc025" name="ai-agent-message">
99+
<bpmn:extensionElements>
100+
<zeebe:subscription correlationKey="=&#34;ai-agent-message&#34;" />
101+
</bpmn:extensionElements>
102+
</bpmn:message>
103+
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
104+
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ai-agent-chat-with-tools">
105+
<bpmndi:BPMNShape id="Activity_03yngb7_di" bpmnElement="AI_Agent" isExpanded="true">
106+
<dc:Bounds x="160" y="80" width="400" height="550" />
107+
<bpmndi:BPMNLabel />
108+
</bpmndi:BPMNShape>
109+
<bpmndi:BPMNShape id="Activity_1sbkoqq_di" bpmnElement="GetDateAndTime">
110+
<dc:Bounds x="190" y="120" width="100" height="80" />
111+
<bpmndi:BPMNLabel />
112+
</bpmndi:BPMNShape>
113+
<bpmndi:BPMNShape id="Activity_16uhg8o_di" bpmnElement="AskHumanToSendEmail">
114+
<dc:Bounds x="190" y="250" width="100" height="80" />
115+
<bpmndi:BPMNLabel />
116+
</bpmndi:BPMNShape>
117+
<bpmndi:BPMNShape id="Gateway_1lux75t_di" bpmnElement="Gateway_1lux75t" isMarkerVisible="true">
118+
<dc:Bounds x="335" y="265" width="50" height="50" />
119+
<bpmndi:BPMNLabel>
120+
<dc:Bounds x="333" y="236" width="55" height="27" />
121+
</bpmndi:BPMNLabel>
122+
</bpmndi:BPMNShape>
123+
<bpmndi:BPMNShape id="Event_1ny5xkz_di" bpmnElement="Event_1wxfv4u">
124+
<dc:Bounds x="342" y="352" width="36" height="36" />
125+
<bpmndi:BPMNLabel>
126+
<dc:Bounds x="325" y="395" width="70" height="27" />
127+
</bpmndi:BPMNLabel>
128+
</bpmndi:BPMNShape>
129+
<bpmndi:BPMNShape id="Activity_1sddc2g_di" bpmnElement="SendEmail">
130+
<dc:Bounds x="430" y="250" width="100" height="80" />
131+
</bpmndi:BPMNShape>
132+
<bpmndi:BPMNShape id="Activity_0ixs5a4_di" bpmnElement="Event_Sub_Process" isExpanded="true">
133+
<dc:Bounds x="185" y="450" width="350" height="130" />
134+
</bpmndi:BPMNShape>
135+
<bpmndi:BPMNShape id="Activity_0bsqv5x_di" bpmnElement="Handle_Message">
136+
<dc:Bounds x="410" y="470" width="100" height="80" />
137+
<bpmndi:BPMNLabel />
138+
</bpmndi:BPMNShape>
139+
<bpmndi:BPMNShape id="Event_031hxyb_di" bpmnElement="On_Message">
140+
<dc:Bounds x="212" y="492" width="36" height="36" />
141+
</bpmndi:BPMNShape>
142+
<bpmndi:BPMNEdge id="Flow_0kd4go1_di" bpmnElement="Flow_0kd4go1">
143+
<di:waypoint x="248" y="510" />
144+
<di:waypoint x="410" y="510" />
145+
</bpmndi:BPMNEdge>
146+
<bpmndi:BPMNEdge id="Flow_0demz1g_di" bpmnElement="Flow_0demz1g">
147+
<di:waypoint x="290" y="290" />
148+
<di:waypoint x="335" y="290" />
149+
</bpmndi:BPMNEdge>
150+
<bpmndi:BPMNEdge id="Flow_0uqjclh_di" bpmnElement="Flow_0uqjclh">
151+
<di:waypoint x="385" y="290" />
152+
<di:waypoint x="430" y="290" />
153+
<bpmndi:BPMNLabel>
154+
<dc:Bounds x="399" y="272" width="18" height="14" />
155+
</bpmndi:BPMNLabel>
156+
</bpmndi:BPMNEdge>
157+
<bpmndi:BPMNEdge id="Flow_1l2ws6w_di" bpmnElement="Flow_1l2ws6w">
158+
<di:waypoint x="360" y="315" />
159+
<di:waypoint x="360" y="352" />
160+
<bpmndi:BPMNLabel>
161+
<dc:Bounds x="369" y="323" width="13" height="14" />
162+
</bpmndi:BPMNLabel>
163+
</bpmndi:BPMNEdge>
164+
</bpmndi:BPMNPlane>
165+
</bpmndi:BPMNDiagram>
166+
</bpmn:definitions>

test/spec/zeebe/ZeebeVariableResolver.spec.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import complexXML from 'test/fixtures/zeebe/complex.bpmn';
1616
import errorsXML from 'test/fixtures/zeebe/errors.bpmn';
1717
import complexSubProcessMappingConflictingXML from 'test/fixtures/zeebe/complex.sub-process-mapping-conflict.bpmn';
1818
import agenticAdHocSubProcessXML from 'test/fixtures/zeebe/ad-hoc-sub-process.agentic.bpmn';
19+
import agenticAdHocSubProcessLocalScopeXML from 'test/fixtures/zeebe/ad-hoc-sub-process.agentic-local-scope.bpmn';
1920
import agenticTaskXML from 'test/fixtures/zeebe/task.agentic.bpmn';
2021
import adHocSubProcessOutputCollectionLeakXML from 'test/fixtures/zeebe/ad-hoc-sub-process.output-collection-leak.bpmn';
2122
import connectorsXML from 'test/fixtures/zeebe/connectors.bpmn';
@@ -1494,6 +1495,60 @@ describe('ZeebeVariableResolver', function() {
14941495
});
14951496

14961497

1498+
describe('agentic - ad-hoc sub-process - local scope', function() {
1499+
1500+
beforeEach(
1501+
bootstrapModeler(agenticAdHocSubProcessLocalScopeXML, {
1502+
additionalModules: [
1503+
ZeebeVariableResolverModule
1504+
],
1505+
moddleExtensions: {
1506+
zeebe: ZeebeModdle
1507+
}
1508+
})
1509+
);
1510+
1511+
1512+
it('should expose only <agent> to process', inject(async function(variableResolver, elementRegistry) {
1513+
1514+
// given
1515+
const root = elementRegistry.get('ai-agent-chat-with-tools');
1516+
1517+
// when
1518+
const variables = await variableResolver.getVariablesForElement(root);
1519+
1520+
// then
1521+
expect(variables).to.variableEqual([
1522+
{ name: 'agent', origin: [ 'AI_Agent' ], scope: 'ai-agent-chat-with-tools' }
1523+
]);
1524+
}));
1525+
1526+
1527+
it('should capture <toolCallResult> providers in AI_Agent', inject(async function(variableResolver, elementRegistry) {
1528+
1529+
// given
1530+
const root = elementRegistry.get('AI_Agent');
1531+
1532+
// when
1533+
const variables = await variableResolver.getVariablesForElement(root);
1534+
1535+
// then
1536+
expect(variables).to.variableInclude({
1537+
name: 'toolCallResult',
1538+
origin: [
1539+
'AI_Agent',
1540+
'AskHumanToSendEmail',
1541+
'GetDateAndTime',
1542+
'Handle_Message',
1543+
'SendEmail'
1544+
],
1545+
scope: 'AI_Agent'
1546+
});
1547+
}));
1548+
1549+
});
1550+
1551+
14971552
describe('agentic - agent task', function() {
14981553

14991554
beforeEach(

0 commit comments

Comments
 (0)