cpee-llm 1.1.0 → 1.2.2
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.
- checksums.yaml +4 -4
- data/LICENSE +668 -159
- data/cpee-llm.gemspec +3 -3
- data/lib/cpee/llm/dataflow.rb +3 -3
- data/lib/cpee/llm/functions.rb +16 -16
- data/lib/cpee/llm/implementation.rb +4 -4
- data/lib/cpee/llm/implementation.xml +7 -6
- data/lib/cpee/llm/prompts/system/adapt_mermaid.txt +12 -0
- data/lib/cpee/llm/prompts/system/{adapt_docxml_description.txt → adapt_xml_documentation.txt} +11 -11
- data/lib/cpee/llm/prompts/system/adapt_xml_endpoints.txt +10 -12
- data/lib/cpee/llm/prompts/system/dataflow.txt +13 -25
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/arguments.txt +8 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/color_palette.txt +10 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/description.txt +3 -0
- data/lib/cpee/llm/prompts/system/{cpee_xml_documentation_modelling.txt → fragments/cpee_xml/documentation.txt} +1 -1
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/exclusive_gateway.txt +7 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/finalize.txt +2 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/inclusive_gateway.txt +2 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/loop.txt +7 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/method.txt +6 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/parallel_gateway.txt +6 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/pause.txt +4 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/pause_insertion.txt +3 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/script_task.txt +5 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/sequence.txt +2 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/service_task.txt +20 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml/variables.txt +3 -0
- data/lib/cpee/llm/prompts/system/fragments/cpee_xml.txt +15 -0
- data/lib/cpee/llm/prompts/system/fragments/data_references.txt +14 -0
- data/lib/cpee/llm/prompts/system/fragments/endpoint_naming.txt +1 -0
- data/lib/cpee/llm/prompts/system/fragments/mermaid/structure_rules.txt +29 -0
- data/lib/cpee/llm/prompts/system/fragments/mermaid/syntax.txt +22 -0
- data/lib/cpee/llm/prompts/system/fragments/numeric_conversion.txt +5 -0
- data/lib/cpee/llm/prompts/system/fragments/service_registry.txt +6 -0
- data/lib/cpee/llm/prompts/system/fragments/unmatched_tasks.txt +4 -0
- data/lib/cpee/llm/prompts/system/generate_mermaid.txt +40 -0
- data/lib/cpee/llm/prompts/system/generate_mermaid_endpoints.txt +82 -0
- data/lib/cpee/llm/prompts/system/intent.txt +3 -3
- data/lib/cpee/llm/prompts/system/validate_xml.txt +15 -0
- data/lib/cpee/llm/prompts/user/describe_text.txt +4 -0
- data/lib/cpee/llm/prompts/user/intent.txt +3 -3
- data/lib/cpee/llm/prompts/user/validate_xml.txt +5 -0
- data/lib/cpee/llm/rubyllm_requests.rb +13 -9
- data/server/{cpee-llm → llm} +4 -3
- data/tools/cpee-llm +3 -3
- data/tools/cpee-llm-tool +3 -3
- metadata +39 -23
- data/lib/cpee/llm/prompts/system/apply.txt +0 -32
- data/lib/cpee/llm/prompts/system/cpee_xml.txt +0 -99
- data/lib/cpee/llm/prompts/system/derive.txt +0 -28
- data/lib/cpee/llm/prompts/system/gemini-request.json +0 -18
- data/lib/cpee/llm/prompts/system/generate1.txt +0 -90
- data/lib/cpee/llm/prompts/system/generate_enpoints.txt +0 -132
- data/lib/cpee/llm/prompts/system/generate_enpoints1.txt +0 -155
- data/lib/cpee/llm/prompts/system/identify.txt +0 -25
- data/lib/cpee/llm/prompts/system/validate_mermaid.xml +0 -74
- data/lib/cpee/llm/prompts/user/cpee_repair.txt +0 -5
- data/lib/cpee/llm/prompts/user/process_model_text.txt +0 -4
- data/lib/cpee/llm/prompts/user/repair.txt +0 -5
- /data/lib/cpee/llm/prompts/system/{describe.txt → describe_text.txt} +0 -0
- /data/lib/cpee/llm/prompts/user/{process_model_adapt.txt → adapt.txt} +0 -0
- /data/lib/cpee/llm/prompts/user/{process_model_adapt_api.txt → adapt_xml_endpoints.txt} +0 -0
- /data/lib/cpee/llm/prompts/user/{process_description.txt → generate_mermaid.txt} +0 -0
- /data/lib/cpee/llm/prompts/user/{process_description_endpoints.txt → generate_mermaid_endpoints.txt} +0 -0
- /data/server/{cpee-llm.conf → llm.conf} +0 -0
data/cpee-llm.gemspec
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "cpee-llm"
|
|
3
|
-
s.version = "1.
|
|
3
|
+
s.version = "1.2.2"
|
|
4
4
|
s.platform = Gem::Platform::RUBY
|
|
5
|
-
s.license = "
|
|
5
|
+
s.license = "GPL-3.0-or-later"
|
|
6
6
|
s.summary = "CPEE Conversational Agents"
|
|
7
7
|
|
|
8
8
|
s.description = "see http://cpee.org"
|
|
9
9
|
|
|
10
|
-
s.files = Dir['{server/*,tools/**/*,lib/**/*}'] + %w(LICENSE Rakefile cpee-llm.gemspec README.md AUTHORS)
|
|
10
|
+
s.files = Dir['{server/*,tools/**/*,lib/**/*}'] - Dir['lib/cpee/llm/prompts/legacy{,/**/*}'] + %w(LICENSE Rakefile cpee-llm.gemspec README.md AUTHORS)
|
|
11
11
|
s.require_path = 'lib'
|
|
12
12
|
s.extra_rdoc_files = ['README.md']
|
|
13
13
|
s.bindir = 'tools'
|
data/lib/cpee/llm/dataflow.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# This file is part of CPEE-LLM.
|
|
2
2
|
#
|
|
3
3
|
# CPEE-LLM is free software: you can redistribute it and/or modify it under the
|
|
4
|
-
# terms of the GNU
|
|
4
|
+
# terms of the GNU General Public License as published by the Free
|
|
5
5
|
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
6
6
|
# later version.
|
|
7
7
|
#
|
|
8
8
|
# CPEE-LLM is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
9
9
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
10
|
-
# A PARTICULAR PURPOSE. See the GNU
|
|
10
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
11
11
|
# details.
|
|
12
12
|
#
|
|
13
|
-
# You should have received a copy of the GNU
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
14
|
# along with CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
15
15
|
# <http://www.gnu.org/licenses/>.
|
|
16
16
|
|
data/lib/cpee/llm/functions.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# This file is part of CPEE-LLM.
|
|
2
2
|
#
|
|
3
3
|
# CPEE-LLM is free software: you can redistribute it and/or modify it under the
|
|
4
|
-
# terms of the GNU
|
|
4
|
+
# terms of the GNU General Public License as published by the Free
|
|
5
5
|
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
6
6
|
# later version.
|
|
7
7
|
#
|
|
8
8
|
# CPEE-LLM is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
9
9
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
10
|
-
# A PARTICULAR PURPOSE. See the GNU
|
|
10
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
11
11
|
# details.
|
|
12
12
|
#
|
|
13
|
-
# You should have received a copy of the GNU
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
14
|
# along with CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
15
15
|
# <http://www.gnu.org/licenses/>.
|
|
16
16
|
|
|
@@ -59,8 +59,8 @@ module CPEE
|
|
|
59
59
|
|
|
60
60
|
def generate_model(myllm,user_input,temperature,llms) #{{{
|
|
61
61
|
error_handler do
|
|
62
|
-
system_prompt = build_system_prompt("
|
|
63
|
-
user_prompt = build_user_prompt("
|
|
62
|
+
system_prompt = build_system_prompt("generate_mermaid.txt")
|
|
63
|
+
user_prompt = build_user_prompt("generate_mermaid.txt", user_input:)
|
|
64
64
|
llm_response = generate_content(myllm,system_prompt,user_prompt,4000,temperature,llms)
|
|
65
65
|
# raise exceptions if response is empty for some reason
|
|
66
66
|
if llm_response.nil? || llm_response.empty?
|
|
@@ -75,8 +75,8 @@ module CPEE
|
|
|
75
75
|
input_cpee = doc.to_s()
|
|
76
76
|
input_mermaid = cpee_to_mermaid(doc.to_s())
|
|
77
77
|
error_handler do
|
|
78
|
-
system_prompt = build_system_prompt("
|
|
79
|
-
user_prompt = build_user_prompt("
|
|
78
|
+
system_prompt = build_system_prompt("adapt_mermaid.txt")
|
|
79
|
+
user_prompt = build_user_prompt("adapt.txt", user_input:, process_model: input_mermaid)
|
|
80
80
|
llm_response = generate_content(myllm,system_prompt,user_prompt,4000,0,llms)
|
|
81
81
|
# raise exceptions if response is empty for some reason
|
|
82
82
|
if llm_response.nil? || llm_response.empty?
|
|
@@ -90,8 +90,8 @@ module CPEE
|
|
|
90
90
|
def adapt_doccpee_description(myllm,doc,user_input,llms) #{{{
|
|
91
91
|
input_cpee = doc.to_s()
|
|
92
92
|
error_handler do
|
|
93
|
-
system_prompt = build_system_prompt("
|
|
94
|
-
user_prompt = build_user_prompt("
|
|
93
|
+
system_prompt = build_system_prompt("adapt_xml_documentation.txt")
|
|
94
|
+
user_prompt = build_user_prompt("adapt.txt", user_input:, process_model: input_cpee)
|
|
95
95
|
llm_response = generate_content(myllm,system_prompt,user_prompt,16000,0,llms)
|
|
96
96
|
# raise exceptions if response is empty for some reason
|
|
97
97
|
if llm_response.nil? || llm_response.empty?
|
|
@@ -120,7 +120,7 @@ module CPEE
|
|
|
120
120
|
|
|
121
121
|
error_handler do
|
|
122
122
|
system_prompt = build_system_prompt("adapt_xml_endpoints.txt")
|
|
123
|
-
user_prompt = build_user_prompt("
|
|
123
|
+
user_prompt = build_user_prompt("adapt_xml_endpoints.txt", user_input:, process_model: testset, api_specification: endpoints)
|
|
124
124
|
llm_response = generate_content(myllm,system_prompt,user_prompt,15000,0,llms)
|
|
125
125
|
# raise exceptions if response is empty for some reason
|
|
126
126
|
if llm_response.nil? || llm_response.empty?
|
|
@@ -144,8 +144,8 @@ module CPEE
|
|
|
144
144
|
input_cpee = doc.to_s()
|
|
145
145
|
input_mermaid = cpee_to_mermaid(doc.to_s())
|
|
146
146
|
error_handler do
|
|
147
|
-
system_prompt = build_system_prompt("
|
|
148
|
-
user_prompt = build_user_prompt("
|
|
147
|
+
system_prompt = build_system_prompt("describe_text.txt")
|
|
148
|
+
user_prompt = build_user_prompt("describe_text.txt", user_input: input_mermaid)
|
|
149
149
|
llm_response = generate_content(myllm,system_prompt,user_prompt,4000,0,llms)
|
|
150
150
|
# raise exceptions if response is empty for some reason
|
|
151
151
|
if llm_response.nil? || llm_response.empty?
|
|
@@ -195,8 +195,8 @@ module CPEE
|
|
|
195
195
|
|
|
196
196
|
def generate_endpoint_model(myllm,user_input,endpoints,llms) #{{{
|
|
197
197
|
error_handler do
|
|
198
|
-
system_prompt = build_system_prompt("
|
|
199
|
-
user_prompt = build_user_prompt("
|
|
198
|
+
system_prompt = build_system_prompt("generate_mermaid_endpoints.txt")
|
|
199
|
+
user_prompt = build_user_prompt("generate_mermaid_endpoints.txt", user_input:, endpoints:)
|
|
200
200
|
llm_response = generate_content(myllm,system_prompt,user_prompt,4000,0.1,llms)
|
|
201
201
|
# raise exceptions if response is empty for some reason
|
|
202
202
|
if llm_response.nil? || llm_response.empty?
|
|
@@ -210,7 +210,7 @@ module CPEE
|
|
|
210
210
|
def validate_cpee_model(myllm,cpee_model,llms) #{{{
|
|
211
211
|
error_handler do
|
|
212
212
|
system_prompt = build_system_prompt("validate_xml.txt")
|
|
213
|
-
user_prompt = build_user_prompt("
|
|
213
|
+
user_prompt = build_user_prompt("validate_xml.txt", cpee_model:)
|
|
214
214
|
llm_response = generate_content(myllm,system_prompt,user_prompt,0,0.1,llms)
|
|
215
215
|
if llm_response.nil? || llm_response.empty?
|
|
216
216
|
raise LLMError.new("Something went wrong and your content was not generated!", 500)
|
|
@@ -224,7 +224,7 @@ module CPEE
|
|
|
224
224
|
begin
|
|
225
225
|
XML::Smart.string(llm_response)
|
|
226
226
|
rescue Nokogiri::XML::SyntaxError => e
|
|
227
|
-
raise LLMError.new("Something went wrong and llm was not able to generate valid xml model",
|
|
227
|
+
raise LLMError.new("Something went wrong and llm was not able to generate valid xml model", 500)
|
|
228
228
|
end
|
|
229
229
|
return llm_response
|
|
230
230
|
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# This file is part of CPEE-LLM.
|
|
2
2
|
#
|
|
3
3
|
# CPEE-LLM is free software: you can redistribute it and/or modify it under the
|
|
4
|
-
# terms of the GNU
|
|
4
|
+
# terms of the GNU General Public License as published by the Free
|
|
5
5
|
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
6
6
|
# later version.
|
|
7
7
|
#
|
|
8
8
|
# CPEE-LLM is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
9
9
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
10
|
-
# A PARTICULAR PURPOSE. See the GNU
|
|
10
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
11
11
|
# details.
|
|
12
12
|
#
|
|
13
|
-
# You should have received a copy of the GNU
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
14
|
# along with CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
15
15
|
# <http://www.gnu.org/licenses/>.
|
|
16
16
|
|
|
@@ -199,7 +199,7 @@ module CPEE
|
|
|
199
199
|
llm_response = validate_cpee_model(myllm,input_cpee,llms)
|
|
200
200
|
rescue LLMError => e
|
|
201
201
|
@status = e.http_response
|
|
202
|
-
return Riddl::Parameter::Complex.new("
|
|
202
|
+
return Riddl::Parameter::Complex.new("llm_out","application/json",{:error => e.message}.to_json())
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
return(Riddl::Parameter::Complex.new("llm_out","application/json",{:used_llm => myllm, :output_cpee => llm_response, :status => "Success"}.to_json()))
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
This file is part of CPEE-LLM.
|
|
3
3
|
|
|
4
4
|
CPEE-LLM is free software: you can redistribute it and/or modify it under the
|
|
5
|
-
terms of the GNU General Public License as published by the Free
|
|
6
|
-
Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
-
version.
|
|
5
|
+
terms of the GNU General Public License as published by the Free
|
|
6
|
+
Software Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
later version.
|
|
8
8
|
|
|
9
9
|
CPEE-LLM is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
10
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
11
|
-
A PARTICULAR PURPOSE.
|
|
11
|
+
A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
details.
|
|
12
13
|
|
|
13
|
-
You should have received a copy of the GNU General Public License
|
|
14
|
-
CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
14
|
+
You should have received a copy of the GNU General Public License
|
|
15
|
+
along with CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
15
16
|
<http://www.gnu.org/licenses/>.
|
|
16
17
|
-->
|
|
17
18
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
You are an expert in BPMN modeling, specifically in Mermaid.js format.
|
|
2
|
+
Your task is to validate and transform BPMN models based on user-provided modifications, ensuring compliance with BPMN rules and Mermaid.js syntax.
|
|
3
|
+
You are allowed to adjust only those parts of the process model mentioned in the user-provided modification. Other parts of the model have to stay unchanged.
|
|
4
|
+
|
|
5
|
+
%%%fragments/mermaid/syntax.txt
|
|
6
|
+
|
|
7
|
+
The provided process model may contain nodes whose ids are not integers (e.g., a1, g0s) and nodes of type script (e.g., a3:script:(Compute Total)). Keep these ids and types unchanged. Only new nodes get new unique integer ids.
|
|
8
|
+
|
|
9
|
+
All gateways must have both a split and a merge point.
|
|
10
|
+
Each gateway that initiates a split must be properly closed by a merge gateway of the same type (e.g., an exclusive gateway must be merged by another exclusive gateway).
|
|
11
|
+
|
|
12
|
+
Return only mermaid.js as text without any additional information! Give me just the raw Mermaid.js code without markdown formatting.
|
data/lib/cpee/llm/prompts/system/{adapt_docxml_description.txt → adapt_xml_documentation.txt}
RENAMED
|
@@ -14,17 +14,17 @@ Never introduce additional behavior that was not requested.
|
|
|
14
14
|
Editing Workflow
|
|
15
15
|
Internally perform the following steps:
|
|
16
16
|
1. Parse the existing CPEE XML description.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
2. Parse the workflow contained in the description element.
|
|
18
|
+
3. Understand the user's requested modifications.
|
|
19
|
+
4. Determine which workflow elements are affected.
|
|
20
|
+
5. Apply only the requested changes.
|
|
21
|
+
6. Update documentation flow if necessary.
|
|
22
|
+
7. Generate the complete updated CPEE XML description.
|
|
23
23
|
|
|
24
|
-
%%%cpee_xml.txt
|
|
25
|
-
%%%
|
|
24
|
+
%%%fragments/cpee_xml.txt
|
|
25
|
+
%%%fragments/cpee_xml/documentation.txt
|
|
26
26
|
|
|
27
|
-
For the purpose of modelling, arguments can be ignored and
|
|
27
|
+
For the purpose of modelling, arguments can be ignored and don't have to carry any values. Code also can be left empty. If an argument is given a value that refers to process data, it must use the !data.some_value syntax described above.
|
|
28
28
|
|
|
29
29
|
# Handling Ambiguity
|
|
30
30
|
If the user's request is sufficiently precise, perform the modification directly.
|
|
@@ -34,8 +34,8 @@ If multiple valid interpretations exist and the missing information affects the
|
|
|
34
34
|
If user deletes a single task in a branch, remove task but leave the branch. Use default branch.
|
|
35
35
|
eid attributes are IDs. All eid attributes have to be unique for the whole XML and start with an e followed by a number, e.g., "e1".
|
|
36
36
|
id attributes are IDs. All id attributes have to be unique for the whole XML and start with an a followed by a number, e.g., "a1".
|
|
37
|
-
Don't change ANY existing id's or eid's. Only
|
|
38
|
-
Don't change existing nodes, even when you move them. For example
|
|
37
|
+
Don't change ANY existing id's or eid's. Only generate new unique id's or eid's for new nodes which have id's or eid's.
|
|
38
|
+
Don't change existing nodes, even when you move them. For example don't add documentation if it is not there.
|
|
39
39
|
|
|
40
40
|
# Output Requirements
|
|
41
41
|
Return the complete updated CPEE XML process model.
|
|
@@ -5,12 +5,8 @@ The user will always provide:
|
|
|
5
5
|
* one or more textual modification requests;
|
|
6
6
|
* a list of available API endpoints (service registry).
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- service description
|
|
11
|
-
- service functionality
|
|
12
|
-
- input (RelaxNG schema)
|
|
13
|
-
- optional output
|
|
8
|
+
%%%fragments/service_registry.txt
|
|
9
|
+
The service registry is keyed by service url. Each value lists description, functionality, input and output in this order.
|
|
14
10
|
|
|
15
11
|
Core Objective
|
|
16
12
|
Your task is to produce a modified CPEE XML process model that implements the requested changes.
|
|
@@ -47,24 +43,26 @@ Endpoint Rules:
|
|
|
47
43
|
- URLs are stored only in <endpoints>.
|
|
48
44
|
- Update URLs in <endpoints>; update endpoint attributes only when the endpoint name changes.
|
|
49
45
|
- Do not modify unrelated endpoints.
|
|
46
|
+
%%%fragments/endpoint_naming.txt
|
|
50
47
|
|
|
51
48
|
# Service Registry Usage for Newly Added Tasks
|
|
52
49
|
When the user's modification request introduces one or more new tasks, first determine whether the task exists in the Service Registry.
|
|
53
50
|
If the task exists in the Service Registry:
|
|
54
51
|
- Create a <call> element using the corresponding service specification.
|
|
55
|
-
- Set the endpoint attribute to the endpoint
|
|
56
|
-
- If the endpoint is not already present in the <endpoints> section, add it using the
|
|
52
|
+
- Set the endpoint attribute to the endpoint name derived from the task label (see Endpoint Rules).
|
|
53
|
+
- If the endpoint is not already present in the <endpoints> section, add it using the service url from the Service Registry.
|
|
57
54
|
- Define the task according to the service specification.
|
|
58
55
|
- Define the <arguments> section with the required input parameters, assigning values from the existing process context whenever possible.
|
|
59
56
|
- If the service specification defines outputs, generate the appropriate <finalize> code to store the returned values in workflow variables (data.*) for later use.
|
|
60
57
|
- Integrate the task into the existing workflow without modifying unrelated behavior.
|
|
61
58
|
If the task does not exist in the Service Registry:
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
59
|
+
%%%fragments/unmatched_tasks.txt
|
|
60
|
+
- A script task is a <manipulate> element (see Script Task below).
|
|
61
|
+
- An unconfigured service task is an empty <call> element without endpoint, used as a placeholder. Leave it unconfigured except for information explicitly requested by the user.
|
|
65
62
|
Always use the Service Registry whenever a matching service specification is available.
|
|
66
63
|
|
|
67
|
-
|
|
64
|
+
The CPEE XML model must follow these rules:
|
|
65
|
+
%%%fragments/cpee_xml.txt
|
|
68
66
|
|
|
69
67
|
# Handling Ambiguity
|
|
70
68
|
If the user's request is sufficiently precise, perform the modification directly.
|
|
@@ -9,15 +9,8 @@ INPUT DESCRIPTION
|
|
|
9
9
|
- gateways
|
|
10
10
|
Tasks define process steps.
|
|
11
11
|
Gateways define branching logic based on data produced by tasks.
|
|
12
|
-
2. Service Registry
|
|
13
|
-
|
|
14
|
-
- task id
|
|
15
|
-
- task label
|
|
16
|
-
- service url
|
|
17
|
-
- service description
|
|
18
|
-
- service functionality
|
|
19
|
-
- input (RelaxNG schema)
|
|
20
|
-
- optional output
|
|
12
|
+
2. Service Registry is keyed by the task id from the process model. Each entry contains the task label from the process model (label) and the matching service.
|
|
13
|
+
%%%fragments/service_registry.txt
|
|
21
14
|
|
|
22
15
|
OUTPUT FORMAT
|
|
23
16
|
Return a JSON object with exactly two top-level fields:
|
|
@@ -32,11 +25,10 @@ For each task in the process model include:
|
|
|
32
25
|
- label: original task label from the process model
|
|
33
26
|
|
|
34
27
|
Based on the task types additional information is provided:
|
|
35
|
-
(a) Script tasks
|
|
28
|
+
(a) Script tasks
|
|
29
|
+
%%%fragments/unmatched_tasks.txt
|
|
36
30
|
- url: is always "script"
|
|
37
31
|
- script: <ruby code>
|
|
38
|
-
The script must be generated in simple Ruby. Example: assign from another variable: data.total = data.amount + data.tax
|
|
39
|
-
Script tasks participate in process data flow exactly like service tasks and may create or update data.* variables used by downstream tasks and gateways.
|
|
40
32
|
(b) Service tasks if a matching service exists in the registry:
|
|
41
33
|
- url: service endpoint
|
|
42
34
|
- input: required parameters with concrete values if derivable from process logic
|
|
@@ -44,12 +36,13 @@ Based on the task types additional information is provided:
|
|
|
44
36
|
|
|
45
37
|
INPUT RULES
|
|
46
38
|
Each input value MUST follow exactly one of the following formats:
|
|
47
|
-
1. Literal value (no change)
|
|
39
|
+
1. Literal value (no change, no leading !)
|
|
48
40
|
If the value is constant:
|
|
49
41
|
"intensity": 90
|
|
50
|
-
2. Value from previous task output
|
|
51
|
-
If the value comes from another task’s output:
|
|
52
|
-
"sample_id": "data.sample_id"
|
|
42
|
+
2. Value from previous task output or script
|
|
43
|
+
If the value comes from another task’s output or from a script:
|
|
44
|
+
"sample_id": "!data.sample_id"
|
|
45
|
+
%%%fragments/data_references.txt
|
|
53
46
|
|
|
54
47
|
OUTPUT RULES
|
|
55
48
|
Include output only if required. Otherwise omit it.
|
|
@@ -67,16 +60,11 @@ Value sources
|
|
|
67
60
|
(b) Nested field access is used when the required value is located inside a specific key within result.
|
|
68
61
|
"data.ambient_light_lumens": "result['some_key']"
|
|
69
62
|
Required conversions
|
|
70
|
-
|
|
71
|
-
If the operation description specifies a numeric type or the semantic meaning implies a numeric type, a conversion MUST be applied.
|
|
72
|
-
Type rules:
|
|
73
|
-
- If the value is defined as or implied to be a float ALWAYS use .to_f
|
|
74
|
-
- If the value is defined as or implied to be an integer ALWAYS use .to_i
|
|
63
|
+
%%%fragments/numeric_conversion.txt
|
|
75
64
|
Examples:
|
|
76
65
|
"data.ambient_light_lux": "result.to_f"
|
|
77
66
|
"data.temperature": "result['value'].to_f"
|
|
78
67
|
"data.count": "result.to_i"
|
|
79
|
-
Do NOT omit a conversion!!!
|
|
80
68
|
|
|
81
69
|
Tasks that are not script or service tasks are ignored!!!
|
|
82
70
|
|
|
@@ -143,11 +131,11 @@ OUTPUT STRUCTURE EXAMPLE (SCHEMA ONLY)
|
|
|
143
131
|
"url": "...",
|
|
144
132
|
"input": {
|
|
145
133
|
"param1": "value",
|
|
146
|
-
"param2": "data.some_output"
|
|
134
|
+
"param2": "!data.some_output"
|
|
147
135
|
},
|
|
148
136
|
"output": {
|
|
149
|
-
"data.some_output": "result['
|
|
150
|
-
"data.
|
|
137
|
+
"data.some_output": "result['some_key']",
|
|
138
|
+
"data.other_output": "result.to_i"
|
|
151
139
|
}
|
|
152
140
|
},
|
|
153
141
|
"task_id": {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Service input parameters are stored inside arguments (which in turn are always stored inside parameters, see structure above). Each argument is represented by its own child element.
|
|
2
|
+
<parameters>
|
|
3
|
+
<arguments>
|
|
4
|
+
<min>1</min>
|
|
5
|
+
<max>100</max>
|
|
6
|
+
</arguments>
|
|
7
|
+
</parameters>
|
|
8
|
+
%%%fragments/data_references.txt
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Use only the following color palette:
|
|
2
|
+
* White — #ffffff
|
|
3
|
+
* Blue — #d4e1f1
|
|
4
|
+
* Green — #d8f0dd
|
|
5
|
+
* Yellow — #ffffcc
|
|
6
|
+
* Purple — #e4c3e4
|
|
7
|
+
* Pink — #f8a8c6
|
|
8
|
+
* Brown — #ded0c5
|
|
9
|
+
* Gray — #deddda
|
|
10
|
+
The same color palette also applies to the color attribute of <description> and to the color attribute of <manipulate>.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# CPEE XML Process Model Structure
|
|
2
|
+
The process model itself is contained entirely inside the <description color=""> element. Interpret the XML inside <description> using the following mapping.
|
|
3
|
+
The color attribute controls the color of the whole process model. Individual service task colors can be set (see below).
|
|
@@ -14,7 +14,7 @@ The documentation element may describe the service implementation as well as its
|
|
|
14
14
|
The <description> elements contain optional textual information about the task's behavior, including the process variables consumed (<in>), produced (<out>), or implementation-specific details (<implementation>).
|
|
15
15
|
Empty <description> elements indicate that no additional semantic information is provided.
|
|
16
16
|
|
|
17
|
-
If a `<documentation>` element does not exist for a Service Task, append an empty `<documentation>` element. Empty `<documentation>`
|
|
17
|
+
If a `<documentation>` element does not exist for a Service Task, append an empty `<documentation>` element. Empty `<documentation>` contains only <in> and <implementation>. Include <out> only in tasks, where output is defined.
|
|
18
18
|
|
|
19
19
|
#Outputs:
|
|
20
20
|
Every new output created by the Service Task must be added to the <out><description> element.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## Exclusive Gateway
|
|
2
|
+
An Exclusive Gateway is represented by <choose eid="..." mode="exclusive">
|
|
3
|
+
Each outgoing branch is represented by <alternative condition="..." eid="e.."> child.
|
|
4
|
+
The branch condition is stored in the **condition attribute**.
|
|
5
|
+
<alternative condition="data.temperature > 30" eid="e1">
|
|
6
|
+
Conditions must be valid Ruby expressions.
|
|
7
|
+
Default branch has no conditions. <otherwise eid="..."/>.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Returned service values are processed inside <finalize output="result">, where result is the variable containing the service response.
|
|
2
|
+
result can be a single value or an object. Inside <finalize>, assign result directly (<finalize output="result"> data.temperature = result</finalize>) or extract specific properties (<finalize output="result"> data.temperature = result["temperature"].to_f; data.type = result["celsius"];</finalize>) to store values for later use in the process.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## Loop
|
|
2
|
+
A BPMN loop is represented by <loop eid="e.." mode="..." condition="...">
|
|
3
|
+
The loop condition is stored in the **condition attribute**. The loop execution mode is stored in the **mode attribute**.
|
|
4
|
+
pre_test is used for head controlled loops.
|
|
5
|
+
post_test is used for tail controlled loops.
|
|
6
|
+
<loop eid="e1" mode="pre_test" condition="data.counter < 10">
|
|
7
|
+
Loop conditions must be valid Ruby expressions.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
The <method> field must strictly follow the Service Registry specification.
|
|
2
|
+
If the service specification defines a method, use exactly that value. The value must always be lowercase and enclosed in colons (example: <method>:get</method>).
|
|
3
|
+
Never invent, infer, or assume a method value that is not explicitly defined in the service specification:
|
|
4
|
+
<parameters>
|
|
5
|
+
<method/>
|
|
6
|
+
</parameters>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
## Parallel Gateway
|
|
2
|
+
Parallel execution is represented by <parallel eid="e.." wait="-1" cancel="last">
|
|
3
|
+
The attribute wait defines how many branches have to reach the cancel condition before other branches are considered invalid. A normal parallel has always wait="-1".
|
|
4
|
+
The attribute cancel defines the cancel condition, i.e., if the wait rules are evaluated after a branch fully finishes (attribute cancel has the value "last"), or if the wait rules are evaluated after the first task of a branch finishes ((attribute cancel has the value "first").
|
|
5
|
+
An event-based gateway (which is a special case of a parallel) has always wait="1" cancel="last".
|
|
6
|
+
Each concurrent branch is represented by <parallel_branch eid="e..">
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
When the user requests to pause, hold, or stop the process, insert a <stop> element.
|
|
2
|
+
The id attribute must be unique within the process model. The id must follow the same naming convention as the existing element IDs in the process model.
|
|
3
|
+
Insert the <stop> element at the location specified or implied by the user's request. Otherwise, insert the <stop> element as the last element of the process.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
## Script Task
|
|
2
|
+
A BPMN Script Task is represented by <manipulate id="..." label="..." color="...">. The executable Ruby code is stored inside the <code> child element:
|
|
3
|
+
<manipulate id="a1" label="Increase Counter"><code>data.counter += 1</code></manipulate>
|
|
4
|
+
The label of the BPMN Script Task is stored in an attribute label in the <manipulate>.
|
|
5
|
+
The color of the BPMN Script Task is stored in an attribute color in the <manipulate>.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Service Task
|
|
2
|
+
A BPMN Service Task is represented by a `<call id="..." endpoint="...">` element.
|
|
3
|
+
The endpoint of the service is stored in the **endpoint attribute**.
|
|
4
|
+
<call endpoint="measurelightingconditions">
|
|
5
|
+
The following child elements may appear inside `<call>`:
|
|
6
|
+
├── parameters
|
|
7
|
+
│ ├── label
|
|
8
|
+
│ ├── color
|
|
9
|
+
│ ├── method
|
|
10
|
+
│ └── arguments
|
|
11
|
+
├── code
|
|
12
|
+
│ ├── signal
|
|
13
|
+
│ ├── prepare
|
|
14
|
+
│ ├── finalize
|
|
15
|
+
│ ├── update
|
|
16
|
+
│ └── rescue
|
|
17
|
+
├── annotations
|
|
18
|
+
└── documentation
|
|
19
|
+
|
|
20
|
+
The parameters element stores task metadata, such as its label and display color. The <label> is the task name. The <color> element defines the display color of the task in hexadecimal RGB format.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
%%%fragments/cpee_xml/description.txt
|
|
2
|
+
%%%fragments/cpee_xml/sequence.txt
|
|
3
|
+
%%%fragments/cpee_xml/service_task.txt
|
|
4
|
+
%%%fragments/cpee_xml/color_palette.txt
|
|
5
|
+
%%%fragments/cpee_xml/method.txt
|
|
6
|
+
%%%fragments/cpee_xml/arguments.txt
|
|
7
|
+
%%%fragments/cpee_xml/finalize.txt
|
|
8
|
+
%%%fragments/cpee_xml/script_task.txt
|
|
9
|
+
%%%fragments/cpee_xml/exclusive_gateway.txt
|
|
10
|
+
%%%fragments/cpee_xml/inclusive_gateway.txt
|
|
11
|
+
%%%fragments/cpee_xml/loop.txt
|
|
12
|
+
%%%fragments/cpee_xml/parallel_gateway.txt
|
|
13
|
+
%%%fragments/cpee_xml/pause.txt
|
|
14
|
+
%%%fragments/cpee_xml/pause_insertion.txt
|
|
15
|
+
%%%fragments/cpee_xml/variables.txt
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
If a service argument (input parameter) depends on a previously computed or returned value, i.e. on process data, it must be provided using the !data.some_value syntax. A Ruby expression over process data is also allowed, e.g. !data.minutes * 60.
|
|
2
|
+
The leading ! marks the value as a Ruby expression that is evaluated against the process data at runtime. It is NOT a boolean negation and must never be removed.
|
|
3
|
+
Without the leading ! the value is passed as a literal string, i.e. data.timeout_duration would send the text "data.timeout_duration" instead of its value.
|
|
4
|
+
Use the leading ! ONLY when the value references process data (data.*). Constant values such as numbers or fixed text are written literally, without !, e.g. 300 and not !300.
|
|
5
|
+
Example (XML):
|
|
6
|
+
<parameters>
|
|
7
|
+
<arguments>
|
|
8
|
+
<timeout>!data.timeout_duration</timeout>
|
|
9
|
+
<unit>seconds</unit>
|
|
10
|
+
<retries>3</retries>
|
|
11
|
+
</arguments>
|
|
12
|
+
</parameters>
|
|
13
|
+
Example (JSON):
|
|
14
|
+
"timeout": "!data.timeout_duration", "unit": "seconds", "retries": 3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Endpoint names are derived from the task label: remove all characters except letters and digits, and convert the result to lowercase, e.g. the task label "Measure Lighting Conditions" results in the endpoint name measurelightingconditions.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Hard Structural Rules:
|
|
2
|
+
Tasks:
|
|
3
|
+
A Task represents a real business or system action that produces an external or domain-relevant effect.
|
|
4
|
+
Some process descriptions imply internal process-control logic that is not explicitly mentioned in the text (loop counters, variables initialization, math operations, etc.)
|
|
5
|
+
When necessary to create a complete and executable process model, additional tasks may be introduced to generate, initialize, update, or transform process data required by gateways, loops, routing decisions, or downstream activities. Such tasks must represent only internal workflow logic and must not model business actions or external effects.
|
|
6
|
+
No empty tasks are allowed: every task node must have a descriptive label.
|
|
7
|
+
“Default branches” between gateways are allowed — i.e., edges that go directly from one gateway to another without any task in between. These represent “nothing happens”.
|
|
8
|
+
|
|
9
|
+
Gateways:
|
|
10
|
+
Every split gateway must be matched with a corresponding merge gateway of the same type.
|
|
11
|
+
No implicit merges are allowed — merges must always be explicit.
|
|
12
|
+
No split gateway is permitted without a matching merge.
|
|
13
|
+
Any variable used in a loop condition MUST be derived from a task.
|
|
14
|
+
|
|
15
|
+
Loop Abstraction:
|
|
16
|
+
If a process contains repetitive behavior, it MUST NOT be unrolled into repeated tasks.
|
|
17
|
+
Instead, it MUST be modeled as a loop using an exclusive gateway for loop control.
|
|
18
|
+
The gateway branches either back to the loop body or to the exit path.
|
|
19
|
+
For time-based loops, timer or wait tasks may directly provide the loop termination condition. Explicit initialization and update tasks are required only when the process description implies them.
|
|
20
|
+
|
|
21
|
+
Parallel Logic:
|
|
22
|
+
Create a parallel gateway when two or more activities must occur concurrently or when one activity controls the duration of another. One branch may establish the termination condition while the other performs the repeated work. Merge parallel branches with a matching parallel gateway.
|
|
23
|
+
|
|
24
|
+
Flow correctness:
|
|
25
|
+
Each path/branch must start from the start event and lead to the end event.
|
|
26
|
+
Each incoming node must have its own separate edge to the target node.
|
|
27
|
+
|
|
28
|
+
Simplification Rule:
|
|
29
|
+
If you cannot generate a model that fully meets all requirements due to the complexity of the description, you must simplify the model until it fully satisfies every requirement.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Mermaid.js BPMN Syntax:
|
|
2
|
+
The graph must use the LR (Left to Right) direction.
|
|
3
|
+
Each Mermaid.js node must have the following structure:
|
|
4
|
+
id:type:shape and label
|
|
5
|
+
id: a unique identifier. New nodes use a unique integer from 0 to n.
|
|
6
|
+
type: BPMN element type → startevent, endevent, task, exclusivegateway, inclusivegateway, parallelgateway.
|
|
7
|
+
Shapes and labels:
|
|
8
|
+
Start event → id:startevent:((startevent))
|
|
9
|
+
End event → id:endevent:(((endevent)))
|
|
10
|
+
Task → id:task:(Task Label)
|
|
11
|
+
Exclusive gateway → id:exclusivegateway:{x}
|
|
12
|
+
Parallel gateway → id:parallelgateway:{AND}
|
|
13
|
+
Inclusive gateway → id:inclusivegateway:{O}
|
|
14
|
+
|
|
15
|
+
Reused nodes:
|
|
16
|
+
If a node occurs more than once, reference it by repeating the full node declaration like this - id:type:shape and label (e.g., 2:task:(do something)).
|
|
17
|
+
It is strictly prohibited to use only the ID (e.g., 2) without type and to use other short versions like id:type (e.g., 2:task or 2:task:).
|
|
18
|
+
|
|
19
|
+
Edges:
|
|
20
|
+
All nodes must be connected with -->.
|
|
21
|
+
Edge labels (for conditions/annotations) must be written as |text| between nodes.
|
|
22
|
+
Edge label is always located between 2 nodes: id:exclusivegateway:{x} --> |condition or annotation|id:task:(task label)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Service outputs are returned as strings unless otherwise specified.
|
|
2
|
+
If the service specification defines a numeric type, or the semantic meaning implies a numeric type, a conversion MUST be applied before the value is assigned to a workflow variable:
|
|
3
|
+
- If the value is defined as or implied to be a float ALWAYS use .to_f, e.g. data.temperature = result["temperature"].to_f
|
|
4
|
+
- If the value is defined as or implied to be an integer ALWAYS use .to_i, e.g. data.count = result.to_i
|
|
5
|
+
Do NOT omit a conversion!!!
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Each service in the service registry is described by:
|
|
2
|
+
- service url: the URL of the service
|
|
3
|
+
- description: one or more alternative task labels for the service, separated by ";"
|
|
4
|
+
- functionality: what the service does
|
|
5
|
+
- input: the input parameters of the service (RelaxNG schema)
|
|
6
|
+
- output: optional, the values the service returns
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
If no matching service exists for a task, but the step is purely data transformation or computation and no external system interaction is implied, implement it as a script task.
|
|
2
|
+
The script must be generated in simple Ruby. Example: assign from another variable: data.total = data.amount + data.tax
|
|
3
|
+
Script tasks participate in process data flow exactly like service tasks and may create or update data.* variables used by downstream tasks and gateways.
|
|
4
|
+
If no matching service exists and the step is not pure computation, the task stays an unconfigured service task: do not invent a service url, input parameters, output mappings, or implementation details.
|