cpee-llm 1.0.0
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 +7 -0
- data/AUTHORS +3 -0
- data/LICENSE +165 -0
- data/README.md +7 -0
- data/Rakefile +21 -0
- data/cpee-llm.gemspec +29 -0
- data/lib/cpee/llm/dataflow.rb +199 -0
- data/lib/cpee/llm/functions.rb +248 -0
- data/lib/cpee/llm/implementation.rb +237 -0
- data/lib/cpee/llm/implementation.xml +90 -0
- data/lib/cpee/llm/prompts/adapt_xml.txt +157 -0
- data/lib/cpee/llm/prompts/apply.txt +32 -0
- data/lib/cpee/llm/prompts/dataflow.txt +171 -0
- data/lib/cpee/llm/prompts/derive.txt +28 -0
- data/lib/cpee/llm/prompts/describe.txt +5 -0
- data/lib/cpee/llm/prompts/gemini-request.json +18 -0
- data/lib/cpee/llm/prompts/generate1.txt +90 -0
- data/lib/cpee/llm/prompts/generate_enpoints.txt +132 -0
- data/lib/cpee/llm/prompts/generate_enpoints1.txt +155 -0
- data/lib/cpee/llm/prompts/identify.txt +25 -0
- data/lib/cpee/llm/prompts/validate_mermaid.xml +74 -0
- data/lib/cpee/llm/prompts/validate_xml.txt +35 -0
- data/lib/cpee/llm/rubyllm_requests.rb +172 -0
- data/server/connect_gemini +3 -0
- data/server/connect_gpt +4 -0
- data/server/connect_morpheus +5 -0
- data/server/cpee-llm +43 -0
- data/server/cpee-llm.conf +11 -0
- data/tools/cpee-llm +74 -0
- data/tools/cpee-llm-tool +49 -0
- metadata +156 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# This file is part of CPEE-LLM.
|
|
2
|
+
#
|
|
3
|
+
# CPEE-LLM is free software: you can redistribute it and/or modify it under the
|
|
4
|
+
# terms of the GNU Lesser General Public License as published by the Free
|
|
5
|
+
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
6
|
+
# later version.
|
|
7
|
+
#
|
|
8
|
+
# CPEE-LLM is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
9
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
10
|
+
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
11
|
+
# details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
14
|
+
# along with CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
15
|
+
# <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
require 'riddl/server'
|
|
18
|
+
require 'riddl/client'
|
|
19
|
+
require 'xml/smart'
|
|
20
|
+
require 'json'
|
|
21
|
+
require_relative 'functions'
|
|
22
|
+
require_relative 'dataflow'
|
|
23
|
+
|
|
24
|
+
module CPEE
|
|
25
|
+
|
|
26
|
+
module LLM
|
|
27
|
+
|
|
28
|
+
SERVER = File.expand_path(File.join(__dir__,'implementation.xml'))
|
|
29
|
+
|
|
30
|
+
class CreateMermaid < Riddl::Implementation #{{{
|
|
31
|
+
include Functions
|
|
32
|
+
include DataFlow
|
|
33
|
+
|
|
34
|
+
def response
|
|
35
|
+
llms = @a[0]
|
|
36
|
+
input_cpee = @p.shift.value.read
|
|
37
|
+
user_input = @p.shift.value.read
|
|
38
|
+
myllm = @p.shift.value.read
|
|
39
|
+
prompt_type = @p.shift.value.read if @p[0]&.name == 'prompt_type'
|
|
40
|
+
endpoints = @p.shift.value.read if @p[0]&.name == 'endpoints'
|
|
41
|
+
temperature = @p.shift.value.read if @p[0]&.name == 'temperature'
|
|
42
|
+
|
|
43
|
+
doc = XML::Smart.string(input_cpee)
|
|
44
|
+
pp temperature
|
|
45
|
+
begin
|
|
46
|
+
output_cpee = if prompt_type == 'generate_noendpoints'
|
|
47
|
+
llm_response = generate_model(myllm,user_input,temperature,llms)
|
|
48
|
+
mermaid_to_cpee(llm_response)
|
|
49
|
+
elsif prompt_type == 'generate_endpoints'
|
|
50
|
+
# get endpoints (hardcoded for demo, in future separate step)
|
|
51
|
+
llm_response = generate_endpoint_model(myllm,user_input,get_demo_endpoints(),llms)
|
|
52
|
+
mermaid_to_cpee(llm_response)
|
|
53
|
+
elsif prompt_type == 'adapt_noendpoints'
|
|
54
|
+
llm_response = adapt_model(myllm,doc,user_input,llms)
|
|
55
|
+
mermaid_to_cpee(llm_response)
|
|
56
|
+
elsif prompt_type == 'adapt_endpoints'
|
|
57
|
+
xml_endpoints = XML::Smart.string(endpoints)
|
|
58
|
+
adapt_cpee_model(myllm,doc,user_input,xml_endpoints,get_demo_endpoints(),llms)
|
|
59
|
+
end
|
|
60
|
+
rescue Exception => e
|
|
61
|
+
@status = 500
|
|
62
|
+
return Riddl::Parameter::Complex.new('llm_out', 'application/json', { error: e }.to_json)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
return(Riddl::Parameter::Complex.new("llm_out","application/json",{:user_input => user_input, :used_llm => myllm, :input_cpee => input_cpee, :input_intermediate => doc.root().empty?() ? "" : cpee_to_mermaid(doc.to_s()), :output_intermediate => llm_response, :output_cpee => output_cpee, :status => "Success"}.to_json()))
|
|
66
|
+
rescue LLMError => e
|
|
67
|
+
pp 'here in error'
|
|
68
|
+
@status = e&.http_response || 400
|
|
69
|
+
return Riddl::Parameter::Complex.new("llm_out","application/json",{ :error => "#{prompt_type} #{e.message}"}.to_json())
|
|
70
|
+
end
|
|
71
|
+
end #}}}
|
|
72
|
+
|
|
73
|
+
class CreateText < Riddl::Implementation #{{{
|
|
74
|
+
include Functions
|
|
75
|
+
|
|
76
|
+
def response
|
|
77
|
+
llms = @a[0]
|
|
78
|
+
input_cpee = @p.shift.value.read
|
|
79
|
+
begin
|
|
80
|
+
input_cpee = @p[0].value.read
|
|
81
|
+
myllm = @p[1].value
|
|
82
|
+
doc = XML::Smart.string(input_cpee)
|
|
83
|
+
rescue Exception => e
|
|
84
|
+
@status = 400
|
|
85
|
+
return Riddl::Parameter::Complex.new('llm_out','application/json',{:error => e}.to_json())
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
if doc.root.empty?
|
|
89
|
+
@status = 400
|
|
90
|
+
return Riddl::Parameter::Complex.new('text_out','application/json',{:error => e}.to_json())
|
|
91
|
+
else
|
|
92
|
+
begin
|
|
93
|
+
llm_response = generate_text(myllm,doc,llms)
|
|
94
|
+
rescue LLMError => e
|
|
95
|
+
@status = e.http_response
|
|
96
|
+
return Riddl::Parameter::Complex.new('text_out','application/json',{:error => e.message}.to_json())
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
begin
|
|
100
|
+
output_cpee = mermaid_to_cpee(llm_response)
|
|
101
|
+
rescue Exception => e
|
|
102
|
+
@status = 500
|
|
103
|
+
return Riddl::Parameter::Complex.new('text_out','application/json',{:error => e}.to_json())
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
return(Riddl::Parameter::Complex.new("text_out","application/json",{:input_cpee => input_cpee, :input_intermediate => doc.root.empty? ? '' : cpee_to_mermaid(doc.to_s), :output_text => llm_response, :status => 'Success'}.to_json()))
|
|
107
|
+
end
|
|
108
|
+
end #}}}
|
|
109
|
+
|
|
110
|
+
class CreateGeneric < Riddl::Implementation #{{{
|
|
111
|
+
include Functions
|
|
112
|
+
|
|
113
|
+
def response
|
|
114
|
+
llms = @a[0]
|
|
115
|
+
#get parameters
|
|
116
|
+
begin
|
|
117
|
+
myllm = @p[0].value.read
|
|
118
|
+
user_input = @p[1].value.read
|
|
119
|
+
system_prompt = @p[2].value.read
|
|
120
|
+
format = @p[3].value.read
|
|
121
|
+
temperature = @p[4]&.value&.read
|
|
122
|
+
rescue Exception => e
|
|
123
|
+
@status = 400
|
|
124
|
+
return Riddl::Parameter::Complex.new("generic_out","application/json",{:error => e}.to_json())
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
begin
|
|
128
|
+
llm_response = generate_generic(myllm,user_input,system_prompt,format,temperature,llms)
|
|
129
|
+
rescue LLMError => e
|
|
130
|
+
@status = e.http_response
|
|
131
|
+
return Riddl::Parameter::Complex.new("generic_out","application/json",{:error => e.message}.to_json())
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
return(Riddl::Parameter::Complex.new("generic_out","application/json",{:user_input => user_input, :used_llm => myllm, :system_prompt => system_prompt, :llm_response => llm_response, :status => "Success"}.to_json()))
|
|
135
|
+
end
|
|
136
|
+
end #}}}
|
|
137
|
+
|
|
138
|
+
class CreateDataFlow < Riddl::Implementation #{{{
|
|
139
|
+
include Functions
|
|
140
|
+
include DataFlow
|
|
141
|
+
|
|
142
|
+
def response
|
|
143
|
+
llms = @a[0]
|
|
144
|
+
|
|
145
|
+
#get parameters
|
|
146
|
+
begin
|
|
147
|
+
input_cpee = @p[0].value().read()
|
|
148
|
+
myllm = @p[1].value().read()
|
|
149
|
+
doc = XML::Smart.string(input_cpee)
|
|
150
|
+
rescue Exception => e
|
|
151
|
+
@status = 400
|
|
152
|
+
return Riddl::Parameter::Complex.new("llm_out","application/json",{:error => e}.to_json())
|
|
153
|
+
end
|
|
154
|
+
begin
|
|
155
|
+
mermaid_model = cpee_to_mermaid(doc.to_s())
|
|
156
|
+
#get endpoints (hardcoded for demo, in future separate step)
|
|
157
|
+
endpoints_description = get_demo_endpoints()
|
|
158
|
+
#match tasks and endpoints
|
|
159
|
+
api_speck = get_matching_endpoints(doc,endpoints_description)
|
|
160
|
+
rescue Exception => e
|
|
161
|
+
@status = 500
|
|
162
|
+
return Riddl::Parameter::Complex.new('llm_out', 'application/json', { error: e }.to_json)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#generate data flow
|
|
166
|
+
begin
|
|
167
|
+
dataflow = generate_dataflow(myllm,mermaid_model,api_speck,llms)
|
|
168
|
+
rescue LLMError => e
|
|
169
|
+
pp e.http_response
|
|
170
|
+
@status = e.http_response || 400
|
|
171
|
+
return Riddl::Parameter::Complex.new("llm_out","application/json",{:error => e.message}.to_json())
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
#integrate dataflow in cpee_model
|
|
175
|
+
final_cpee, endpoints = integrate_dataflow(doc,dataflow)
|
|
176
|
+
|
|
177
|
+
return(Riddl::Parameter::Complex.new("llm_out","application/json",{:used_llm => myllm, :dataflow => dataflow, :output_cpee => final_cpee, :endpoints => endpoints, :status => "Success"}.to_json()))
|
|
178
|
+
end
|
|
179
|
+
end #}}}
|
|
180
|
+
|
|
181
|
+
class ValidateDataFlow < Riddl::Implementation #{{{
|
|
182
|
+
include Functions
|
|
183
|
+
|
|
184
|
+
def response
|
|
185
|
+
llms = @a[0]
|
|
186
|
+
|
|
187
|
+
#get parameters
|
|
188
|
+
begin
|
|
189
|
+
input_cpee = @p[0].value().read()
|
|
190
|
+
myllm = @p[1].value().read()
|
|
191
|
+
doc = XML::Smart.string(input_cpee)
|
|
192
|
+
rescue Exception => e
|
|
193
|
+
@status = 400
|
|
194
|
+
return Riddl::Parameter::Complex.new("llm_out","application/json",{:error => e}.to_json())
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
begin
|
|
198
|
+
llm_response = validate_cpee_model(myllm,input_cpee,llms)
|
|
199
|
+
rescue LLMError => e
|
|
200
|
+
@status = e.http_response
|
|
201
|
+
return Riddl::Parameter::Complex.new("generic_out","application/json",{:error => e.message}.to_json())
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
return(Riddl::Parameter::Complex.new("llm_out","application/json",{:used_llm => myllm, :output_cpee => llm_response, :status => "Success"}.to_json()))
|
|
205
|
+
end
|
|
206
|
+
end #}}}
|
|
207
|
+
|
|
208
|
+
def self::implementation(opts)
|
|
209
|
+
Proc.new do
|
|
210
|
+
on resource do
|
|
211
|
+
run(CreateMermaid, opts[:llms]) if post 'llm_in'
|
|
212
|
+
|
|
213
|
+
on resource 'dataflow' do
|
|
214
|
+
run(CreateDataFlow, opts[:llms]) if post 'dataflow_in'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
on resource 'validate' do
|
|
218
|
+
on resource 'xml' do
|
|
219
|
+
run(ValidateDataFlow, opts[:llms]) if post 'dataflow_in'
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
on resource 'text' do
|
|
224
|
+
on resource 'llm' do
|
|
225
|
+
run(CreateText, opts[:llms]) if post 'text_in'
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
on resource 'generic' do
|
|
230
|
+
run(CreateGeneric, opts[:llms]) if post 'generic_in'
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
end
|
|
237
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
This file is part of CPEE-LLM.
|
|
3
|
+
|
|
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 Software
|
|
6
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
|
7
|
+
version.
|
|
8
|
+
|
|
9
|
+
CPEE-LLM is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
11
|
+
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
12
|
+
|
|
13
|
+
You should have received a copy of the GNU General Public License along with
|
|
14
|
+
CPEE-LLM (file LICENSE in the main directory). If not, see
|
|
15
|
+
<http://www.gnu.org/licenses/>.
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
<description datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://riddl.org/ns/description/1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
19
|
+
|
|
20
|
+
<message name="llm_in">
|
|
21
|
+
<parameter name="rpst_xml" mimetype="text/xml"/>
|
|
22
|
+
<parameter name="user_input" mimetype="text/plain"/>
|
|
23
|
+
<parameter name="llm" mimetype="text/plain"/>
|
|
24
|
+
<optional>
|
|
25
|
+
<parameter name="prompt_type" mimetype="text/plain"/>
|
|
26
|
+
</optional>
|
|
27
|
+
<optional>
|
|
28
|
+
<parameter name="endpoints" mimetype="text/xml"/>
|
|
29
|
+
</optional>
|
|
30
|
+
<optional>
|
|
31
|
+
<parameter name="temperature" mimetype="text/plain"/>
|
|
32
|
+
</optional>
|
|
33
|
+
</message>
|
|
34
|
+
<message name="llm_out">
|
|
35
|
+
<parameter name="rpst_xml" mimetype="application/json"/>
|
|
36
|
+
</message>
|
|
37
|
+
|
|
38
|
+
<message name="text_in">
|
|
39
|
+
<parameter name="rpst_xml" mimetype="*/xml"/>
|
|
40
|
+
<parameter name="llm" type="string"/>
|
|
41
|
+
</message>
|
|
42
|
+
<message name="text_out">
|
|
43
|
+
<parameter name="output_text" mimetype="application/json"/>
|
|
44
|
+
</message>
|
|
45
|
+
|
|
46
|
+
<message name="generic_in">
|
|
47
|
+
<parameter name="llm" mimetype="text/plain"/>
|
|
48
|
+
<parameter name="user_input" mimetype="text/plain"/>
|
|
49
|
+
<parameter name="system_prompt" mimetype="text/plain"/>
|
|
50
|
+
<parameter name="format" mimetype="text/plain"/>
|
|
51
|
+
<optional>
|
|
52
|
+
<parameter name="temperature" mimetype="text/plain"/>
|
|
53
|
+
</optional>
|
|
54
|
+
</message>
|
|
55
|
+
<message name="generic_out">
|
|
56
|
+
<parameter name="output_text" mimetype="application/json"/>
|
|
57
|
+
</message>
|
|
58
|
+
|
|
59
|
+
<message name="dataflow_in">
|
|
60
|
+
<parameter name="rpst_xml" mimetype="text/xml"/>
|
|
61
|
+
<parameter name="llm" mimetype="text/plain"/>
|
|
62
|
+
</message>
|
|
63
|
+
|
|
64
|
+
<resource>
|
|
65
|
+
<post in="llm_in" out="llm_out"/>
|
|
66
|
+
|
|
67
|
+
<resource relative="dataflow">
|
|
68
|
+
<post in="dataflow_in" out="llm_out"/>
|
|
69
|
+
</resource>
|
|
70
|
+
|
|
71
|
+
<resource relative="text">
|
|
72
|
+
<resource relative="llm">
|
|
73
|
+
<post in="text_in" out="text_out"/>
|
|
74
|
+
</resource>
|
|
75
|
+
</resource>
|
|
76
|
+
|
|
77
|
+
<resource relative="generic">
|
|
78
|
+
<post in="generic_in" out="generic_out"/>
|
|
79
|
+
</resource>
|
|
80
|
+
|
|
81
|
+
<resource relative="validate">
|
|
82
|
+
<resource relative="xml">
|
|
83
|
+
<post in="dataflow_in" out="llm_out"/>
|
|
84
|
+
</resource>
|
|
85
|
+
</resource>
|
|
86
|
+
|
|
87
|
+
</resource>
|
|
88
|
+
|
|
89
|
+
</description>
|
|
90
|
+
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
You are an expert BPMN 2.0 process model editor for the CPEE XML process description language.
|
|
2
|
+
Your task is to modify an existing CPEE XML process model according to the user's natural-language modification request.
|
|
3
|
+
The user will always provide:
|
|
4
|
+
* an existing valid CPEE XML process model;
|
|
5
|
+
* one or more textual modification requests;
|
|
6
|
+
* a list of available API endpoints (service registry).
|
|
7
|
+
|
|
8
|
+
Service Registry maps each task label to one service specification. Each service specification includes:
|
|
9
|
+
- service url
|
|
10
|
+
- service description
|
|
11
|
+
- service functionality
|
|
12
|
+
- input (RelaxNG schema)
|
|
13
|
+
- optional output
|
|
14
|
+
|
|
15
|
+
Core Objective
|
|
16
|
+
Your task is to produce a modified CPEE XML process model that implements the requested changes.
|
|
17
|
+
Only modify the parts of the process that are explicitly or necessarily affected by the user's request.
|
|
18
|
+
Do not redesign, simplify, optimize, refactor, or rewrite unrelated parts of the model.
|
|
19
|
+
Never remove existing functionality unless explicitly requested.
|
|
20
|
+
Never introduce additional behavior that was not requested.
|
|
21
|
+
|
|
22
|
+
Editing Workflow
|
|
23
|
+
Internally perform the following steps:
|
|
24
|
+
1. Parse the existing CPEE XML testset.
|
|
25
|
+
2. Parse the endpoint definitions.
|
|
26
|
+
3. Parse the workflow contained in the description element.
|
|
27
|
+
4. Understand the user's requested modifications.
|
|
28
|
+
5. Determine which workflow elements and endpoint definitions are affected.
|
|
29
|
+
6. Apply only the requested changes.
|
|
30
|
+
7. Update data flow if necessary.
|
|
31
|
+
8. Generate the complete updated CPEE XML testset.
|
|
32
|
+
|
|
33
|
+
CPEE XML Testset Structure
|
|
34
|
+
The input CPEE XML document has the following structure:
|
|
35
|
+
- The root element is <testset>.
|
|
36
|
+
- <endpoints> contains the mapping from endpoint names to service URLs.
|
|
37
|
+
- <dslx> contains the workflow definition.
|
|
38
|
+
- The actual process model is the <description> element inside <dslx>.
|
|
39
|
+
|
|
40
|
+
#Endpoint Handling
|
|
41
|
+
The <endpoints> section defines all available service endpoints.
|
|
42
|
+
Each endpoint consists of the endpoint name (the XML element name), and the corresponding service URL (the element value).
|
|
43
|
+
Service tasks inside the workflow reference endpoints only by endpoint name, for example:
|
|
44
|
+
<call endpoint="measurewaterlevel">
|
|
45
|
+
Endpoint Rules:
|
|
46
|
+
- <call endpoint="..."> always references an endpoint name.
|
|
47
|
+
- URLs are stored only in <endpoints>.
|
|
48
|
+
- Update URLs in <endpoints>; update endpoint attributes only when the endpoint name changes.
|
|
49
|
+
- Do not modify unrelated endpoints.
|
|
50
|
+
|
|
51
|
+
# Service Registry Usage for Newly Added Tasks
|
|
52
|
+
When the user's modification request introduces one or more new tasks, first determine whether the task exists in the Service Registry.
|
|
53
|
+
If the task exists in the Service Registry:
|
|
54
|
+
- Create a <call> element using the corresponding service specification.
|
|
55
|
+
- Set the endpoint attribute to the endpoint defined for the service.
|
|
56
|
+
- If the endpoint is not already present in the <endpoints> section, add it using the URL from the Service Registry.
|
|
57
|
+
- Define the task according to the service specification.
|
|
58
|
+
- Define the <arguments> section with the required input parameters, assigning values from the existing process context whenever possible.
|
|
59
|
+
- If the service specification defines outputs, generate the appropriate <finalize> code to store the returned values in workflow variables (data.*) for later use.
|
|
60
|
+
- Integrate the task into the existing workflow without modifying unrelated behavior.
|
|
61
|
+
If the task does not exist in the Service Registry:
|
|
62
|
+
- Create an empty <call> element as a placeholder.
|
|
63
|
+
- Do not invent an endpoint, service URL, input parameters, output mappings, or implementation details.
|
|
64
|
+
- Leave the task unconfigured except for information explicitly requested by the user.
|
|
65
|
+
Always use the Service Registry whenever a matching service specification is available.
|
|
66
|
+
|
|
67
|
+
# CPEE XML Process Model Structure
|
|
68
|
+
The process model itself is contained entirely inside the <description> element. Interpret the XML inside <description> using the following mapping.
|
|
69
|
+
## Sequential Flow
|
|
70
|
+
Sequential execution is represented by sibling XML elements appearing in order inside the same parent element.
|
|
71
|
+
|
|
72
|
+
## Service Task
|
|
73
|
+
A BPMN Service Task is represented by a `<call>` element.
|
|
74
|
+
The endpoint of the service is stored in the **endpoint attribute**.
|
|
75
|
+
<call endpoint="measurelightingconditions">
|
|
76
|
+
The following child elements may appear inside `<call>`:
|
|
77
|
+
├── parameters
|
|
78
|
+
│ ├── label
|
|
79
|
+
│ ├── method
|
|
80
|
+
│ └── arguments
|
|
81
|
+
├── code
|
|
82
|
+
│ ├── signal
|
|
83
|
+
│ ├── prepare
|
|
84
|
+
│ ├── finalize
|
|
85
|
+
│ ├── update
|
|
86
|
+
│ └── rescue
|
|
87
|
+
├── annotations
|
|
88
|
+
└── documentation
|
|
89
|
+
|
|
90
|
+
The <method> field must strictly follow the Service Registry specification.
|
|
91
|
+
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>).
|
|
92
|
+
Never invent, infer, or assume a method value that is not explicitly defined in the service specification:
|
|
93
|
+
<method/>
|
|
94
|
+
|
|
95
|
+
Service input parameters are stored inside arguments. Each argument is represented by its own child element.
|
|
96
|
+
<arguments>
|
|
97
|
+
<min>1</min>
|
|
98
|
+
<max>100</max>
|
|
99
|
+
</arguments>
|
|
100
|
+
If an argument depends on a previously computed or returned value, it must be provided using the !data.some_value syntax.
|
|
101
|
+
<arguments>
|
|
102
|
+
<step>!data.current_step</step>
|
|
103
|
+
</arguments>
|
|
104
|
+
|
|
105
|
+
Returned service values are processed inside finalize: <finalize output="result">, where result is the variable containing the service response. Assign values from result (for example, result["start"] or result["end"]) to workflow variables (for example, data.start or data.end) to store them for later use in the process.
|
|
106
|
+
<finalize output="result"> data.temperature = result["temperature"].to_f; data.type = result["celsius"];</finalize>
|
|
107
|
+
|
|
108
|
+
## Script Task
|
|
109
|
+
A BPMN Script Task is represented by <manipulate>. The executable Ruby code is stored inside the <code> child element:
|
|
110
|
+
<manipulate><code>data.counter += 1</code></manipulate>
|
|
111
|
+
|
|
112
|
+
## Exclusive Gateway
|
|
113
|
+
An Exclusive Gateway is represented by <choose>
|
|
114
|
+
Each outgoing branch is represented by <alternative> child.
|
|
115
|
+
The branch condition is stored in the **condition attribute**.
|
|
116
|
+
<alternative condition="data.temperature > 30">
|
|
117
|
+
Conditions must be valid Ruby expressions.
|
|
118
|
+
|
|
119
|
+
## Loop
|
|
120
|
+
A BPMN loop is represented by <loop>
|
|
121
|
+
The loop condition is stored in the **condition attribute**. The loop execution mode is stored in the **mode attribute** (pre_test/post_test)
|
|
122
|
+
<loop mode="pre_test" condition="data.counter < 10">
|
|
123
|
+
Loop conditions must be valid Ruby expressions.
|
|
124
|
+
|
|
125
|
+
## Parallel Gateway
|
|
126
|
+
Parallel execution is represented by <parallel>
|
|
127
|
+
Each concurrent branch is represented by <parallel_branch>
|
|
128
|
+
|
|
129
|
+
##Pause Task
|
|
130
|
+
A pause is represented by a <stop> element.
|
|
131
|
+
A <stop> pauses the execution of the process (until it is manually resumed). It does not terminate the process.
|
|
132
|
+
<stop id="a5"/>
|
|
133
|
+
When the user requests to pause, hold, or stop the process, insert a <stop> element.
|
|
134
|
+
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.
|
|
135
|
+
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.
|
|
136
|
+
|
|
137
|
+
## Variables
|
|
138
|
+
Variables are referenced as: data.variable_name
|
|
139
|
+
Service outputs are returned as strings unless otherwise specified.
|
|
140
|
+
Whenever a value represents a numeric type (integer or floating-point), convert it to a numeric value before assigning it to a workflow variable by using Ruby's .to_f method:
|
|
141
|
+
data.temperature = result["temperature"].to_f
|
|
142
|
+
|
|
143
|
+
# Handling Ambiguity
|
|
144
|
+
If the user's request is sufficiently precise, perform the modification directly.
|
|
145
|
+
If multiple valid interpretations exist and the missing information affects the resulting workflow, select the best possible interpretation and perform changes.
|
|
146
|
+
|
|
147
|
+
# Output Requirements
|
|
148
|
+
Return the complete updated CPEE XML process model.
|
|
149
|
+
Preserve the overall document structure (testset, endpoints, dslx, and description).
|
|
150
|
+
Modify only the elements affected by the user's request.
|
|
151
|
+
Return the entire XML document, including unchanged sections.
|
|
152
|
+
Do not explain the modifications.
|
|
153
|
+
Do not summarize the changes.
|
|
154
|
+
Do not output Markdown.
|
|
155
|
+
Do not omit unchanged sections.
|
|
156
|
+
The returned XML must be immediately usable as a valid CPEE process model.
|
|
157
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
The Mermaid.js syntax for BPMN models is described as follows:
|
|
5
|
+
The graph must use the LR (Left to Right) direction.
|
|
6
|
+
Each mermaid js node must have the following structure:
|
|
7
|
+
id:type:shape and text
|
|
8
|
+
id - it is a unique identifier. Id can be only an integer from 0 to n. Each node has a unique identifier
|
|
9
|
+
type - defines the type of the element regarding to BPMN 2.0 notation.
|
|
10
|
+
possible types are: start event, end event, task, subprocess, exclusive, inclusive and parallel gateway.
|
|
11
|
+
Based on the type of the node following shapes and texts are to be used:
|
|
12
|
+
startevent: ((startevent)) i.e., id:startevent:((startevent))
|
|
13
|
+
endevent: (((endevent))) i.e., id:endevent:(((endevent)))
|
|
14
|
+
task: (task label) i.e., id:task:(task label)
|
|
15
|
+
subprocess: (subprocess label) i.e., id:subprocess:(subprocess label)
|
|
16
|
+
exclusivegateway: {x} i.e., id:exclusivegateway:{x}
|
|
17
|
+
parallelgateway: {AND} i.e., id:parallelgateway:{AND}
|
|
18
|
+
inclusivegateway: {O} i.e., id:inclusivegateway:{O}
|
|
19
|
+
|
|
20
|
+
All gateways must have both a split and a merge point.
|
|
21
|
+
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).
|
|
22
|
+
|
|
23
|
+
All nodes that have occurred more than once should have following structure: id:type: (i.e., 2:task: ) by futher occurrence.
|
|
24
|
+
It is strictly prohibited to use only id (i.e. 2) as a reference.
|
|
25
|
+
|
|
26
|
+
All elements are connected with each other with the help of the direction.
|
|
27
|
+
direction: -->
|
|
28
|
+
If there are some conditions or annotations it is necessary to use text on links (i.e., edge labels)
|
|
29
|
+
edge label: |condition or annotation|
|
|
30
|
+
Edge label is always located between 2 nodes: id:exclusivegateway:{x} --> |condition or annotation|id:task:(task label)
|
|
31
|
+
|
|
32
|
+
Return only mermaid.js as text without any additional information! Give me just the raw Mermaid.js code without markdown formatting.
|